• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_JOIN
25 #define ARM_COMPUTE_TEST_DATASET_JOIN
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 the concatenation of the input datasets.
42  *
43  * For example, for the inputs {1, 2} and {3, 4} this dataset virtually
44  * represents the values {1, 2, 3, 4}.
45  */
46 template <typename T, typename U>
47 class JoinDataset : public Dataset
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      */
JoinDataset(T && dataset1,U && dataset2)61     JoinDataset(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 */
68     JoinDataset(JoinDataset &&) = default;
69 
70     /** Type of the dataset. */
71     using type = typename T_noref::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          */
iteratoriterator81         iterator(const T_noref *dataset1, const U_noref *dataset2)
82             : _iter1{ dataset1->begin() }, _iter2{ dataset2->begin() }, _first_size{ dataset1->size() }
83         {
84         }
85 
86         /** Get the description of the current value.
87          *
88          * @return description of the current value.
89          */
descriptioniterator90         std::string description() const
91         {
92             return _first_size > 0 ? _iter1.description() : _iter2.description();
93         }
94 
95         /** Get the value of the iterator.
96          *
97          * @return the value of the iterator.
98          */
99         JoinDataset::type operator*() const
100         {
101             return _first_size > 0 ? *_iter1 : *_iter2;
102         }
103 
104         /** Inrement the iterator.
105          *
106          * @return *this;
107          */
108         iterator &operator++()
109         {
110             if(_first_size > 0)
111             {
112                 --_first_size;
113                 ++_iter1;
114             }
115             else
116             {
117                 ++_iter2;
118             }
119 
120             return *this;
121         }
122 
123     private:
124         iter1_type _iter1;
125         iter2_type _iter2;
126         int        _first_size;
127     };
128 
129     /** Iterator pointing at the begin of the dataset.
130      *
131      * @return Iterator for the dataset.
132      */
begin()133     iterator begin() const
134     {
135         return iterator(&_dataset1, &_dataset2);
136     }
137 
138     /** Size of the dataset.
139      *
140      * @return Number of values in the dataset.
141      */
size()142     int size() const
143     {
144         return _dataset1.size() + _dataset2.size();
145     }
146 
147 private:
148     T _dataset1;
149     U _dataset2;
150 };
151 
152 /** Helper function to create a @ref JoinDataset.
153  *
154  * @param[in] dataset1 First dataset.
155  * @param[in] dataset2 Second dataset.
156  *
157  * @return A join dataset.
158  */
159 template <typename T, typename U>
concat(T && dataset1,U && dataset2)160 JoinDataset<T, U> concat(T &&dataset1, U &&dataset2)
161 {
162     return JoinDataset<T, U>(std::forward<T>(dataset1), std::forward<U>(dataset2));
163 }
164 } // namespace dataset
165 } // namespace framework
166 } // namespace test
167 } // namespace arm_compute
168 #endif /* ARM_COMPUTE_TEST_DATASET_JOIN */
169