Compute Library
 22.02
CartesianProductDataset.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2018 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef ARM_COMPUTE_TEST_DATASET_CARTESIAN_PRODUCT
25 #define ARM_COMPUTE_TEST_DATASET_CARTESIAN_PRODUCT
26 
27 #include "Dataset.h"
28 
29 #include <string>
30 #include <tuple>
31 #include <utility>
32 
33 namespace arm_compute
34 {
35 namespace test
36 {
37 namespace framework
38 {
39 namespace dataset
40 {
41 /** Implementation of a dataset representing all combinations of values of the input datasets.
42  *
43  * For example, for the inputs {1, 2} and {3, 4} this dataset virtually
44  * represents the values {(1, 3), (1, 4), (2, 3), (2, 4)}.
45  */
46 template <typename T, typename U>
48 {
49 private:
50  using T_noref = typename std::remove_reference<T>::type;
51  using U_noref = typename std::remove_reference<U>::type;
52  using iter1_type = typename T_noref::iterator;
53  using iter2_type = typename U_noref::iterator;
54 
55 public:
56  /** Construct dataset from the given datasets.
57  *
58  * @param[in] dataset1 First dataset.
59  * @param[in] dataset2 Second dataset.
60  */
61  CartesianProductDataset(T &&dataset1, U &&dataset2)
62  : _dataset1{ std::forward<T>(dataset1) },
63  _dataset2{ std::forward<U>(dataset2) }
64  {
65  }
66 
67  /** Allow instances of this class to be move constructed */
69 
70  /** Type of the dataset. */
71  using type = decltype(std::tuple_cat(*std::declval<iter1_type>(), *std::declval<iter2_type>()));
72 
73  /** Iterator for the dataset. */
74  struct iterator
75  {
76  /** Construct an iterator.
77  *
78  * @param[in] dataset1 Dataset 1.
79  * @param[in] dataset2 Dataset 2.
80  */
81  iterator(const T_noref *dataset1, const U_noref *dataset2)
82  : _iter1{ dataset1->begin() },
83  _dataset2{ dataset2 },
84  _iter2{ dataset2->begin() }
85  {
86  }
87 
88  /** Allow instances of this class to be copy constructed */
89  iterator(const iterator &) = default;
90  /** Allow instances of this class to be copied */
91  iterator &operator=(const iterator &) = default;
92  /** Allow instances of this class to be move constructed */
93  iterator(iterator &&) = default;
94  /** Allow instances of this class to be moved */
95  iterator &operator=(iterator &&) = default;
96 
97  /** Default destructor */
98  ~iterator() = default;
99 
100  /** Get the description of the current value.
101  *
102  * @return description of the current value.
103  */
104  std::string description() const
105  {
106  return _iter1.description() + ":" + _iter2.description();
107  }
108 
109  /** Get the value of the iterator.
110  *
111  * @return the value of the iterator.
112  */
114  {
115  return std::tuple_cat(*_iter1, *_iter2);
116  }
117 
118  /** Inrement the iterator.
119  *
120  * @return *this;
121  */
123  {
124  ++_second_pos;
125 
126  if(_second_pos < _dataset2->size())
127  {
128  ++_iter2;
129  }
130  else
131  {
132  _second_pos = 0;
133  _iter2 = _dataset2->begin();
134 
135  ++_iter1;
136  }
137 
138  return *this;
139  }
140 
141  private:
142  iter1_type _iter1;
143  const U_noref *_dataset2;
144  iter2_type _iter2;
145  int _first_pos{ 0 };
146  int _second_pos{ 0 };
147  };
148 
149  /** Iterator pointing at the begin of the dataset.
150  *
151  * @return Iterator for the dataset.
152  */
153  iterator begin() const
154  {
155  return iterator(&_dataset1, &_dataset2);
156  }
157 
158  /** Size of the dataset.
159  *
160  * @return Number of values in the dataset.
161  */
162  int size() const
163  {
164  return _dataset1.size() * _dataset2.size();
165  }
166 
167 private:
168  T _dataset1;
169  U _dataset2;
170 };
171 
172 /** Helper function to create a @ref CartesianProductDataset.
173  *
174  * @param[in] dataset1 First dataset.
175  * @param[in] dataset2 Second dataset.
176  *
177  * @return A grid dataset.
178  */
179 template <typename T, typename U>
180 CartesianProductDataset<T, U> combine(T &&dataset1, U &&dataset2)
181 {
182  return CartesianProductDataset<T, U>(std::forward<T>(dataset1), std::forward<U>(dataset2));
183 }
184 
185 /** Helper function to create a @ref CartesianProductDataset.
186  *
187  * @param[in] dataset1 First dataset.
188  * @param[in] dataset2 Second dataset.
189  *
190  * @return A grid dataset.
191  */
192 template <typename T, typename U>
194 operator*(T &&dataset1, U &&dataset2)
195 {
196  return CartesianProductDataset<T, U>(std::forward<T>(dataset1), std::forward<U>(dataset2));
197 }
198 
199 } // namespace dataset
200 } // namespace framework
201 } // namespace test
202 } // namespace arm_compute
203 #endif /* ARM_COMPUTE_TEST_DATASET_CARTESIAN_PRODUCT */
std::string description() const
Get the description of the current value.
Implementation of a dataset representing all combinations of values of the input datasets.
CartesianProductDataset::type operator*() const
Get the value of the iterator.
iterator begin() const
Iterator pointing at the begin of the dataset.
CartesianProductDataset(T &&dataset1, U &&dataset2)
Construct dataset from the given datasets.
decltype(strategy::transforms) typedef type
Copyright (c) 2017-2021 Arm Limited.
decltype(std::tuple_cat(*std::declval< iter1_type >(), *std::declval< iter2_type >())) type
Type of the dataset.
Abstract dataset base class.
Definition: Dataset.h:39
iterator(const T_noref *dataset1, const U_noref *dataset2)
Construct an iterator.
CartesianProductDataset< T, U > combine(T &&dataset1, U &&dataset2)
Helper function to create a CartesianProductDataset.
iterator & operator=(const iterator &)=default
Allow instances of this class to be copied.