VisionCpp  0.0.1
tuple.hpp
Go to the documentation of this file.
1 // This file is part of VisionCpp, a lightweight C++ template library
2 // for computer vision and image processing.
3 //
4 // Copyright (C) 2016 Codeplay Software Limited. All Rights Reserved.
5 //
6 // Contact: visioncpp@codeplay.com
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
19 
20 /// \file tuple.hpp
21 /// \brief Tuples standard layout implementation.
22 /// http://en.cppreference.com/w/cpp/utility/tuple
23 
24 #ifndef VISIONCPP_INCLUDE_FRAMEWORK_TOOLS_TUPLE_HPP_
25 #define VISIONCPP_INCLUDE_FRAMEWORK_TOOLS_TUPLE_HPP_
26 
27 namespace visioncpp {
28 namespace internal {
29 namespace tools {
30 /// \brief Contains standard layout tuple implementation.
31 namespace tuple {
32 /// \struct EnableIf
33 /// \brief The EnableIf struct is used to statically define type based on the
34 /// condition.
35 template <bool, typename T = void>
36 struct EnableIf {};
37 /// \brief Specialisation of the \ref EnableIf when the condition is matched.
38 template <typename T>
39 struct EnableIf<true, T> {
40  typedef T type;
41 };
42 
43 /// \struct Tuple
44 /// \brief The tuple is a fixed-size collection of heterogeneous values.
45 /// \tparam Ts... - the types of the elements that the tuple stores.
46 /// Empty list is supported.
47 template <class... Ts>
48 struct Tuple {};
49 
50 /// \brief Specialisation of the \ref Tuple class when it has at least one
51 /// element.
52 /// \tparam t : the type of the first element in the tuple.
53 /// \tparam ts... the rest of the elements in the tuple. Ts... can be empty.
54 template <class T, class... Ts>
55 struct Tuple<T, Ts...> {
56  Tuple(T t, Ts... ts) : head(t), tail(ts...) {}
57 
58  T head;
59  Tuple<Ts...> tail;
60 };
61 
62 /// \struct ElemTypeHolder
63 /// \brief ElemTypeHolder class is used to specify the types of the
64 /// elements inside the tuple.
65 /// \tparam size_t The number of elements inside the tuple.
66 /// \tparam class The tuple class.
67 template <size_t, class>
69 
70 /// \brief Specialisation of the \ref ElemTypeHolder class when the number of
71 /// the
72 /// elements inside the tuple is 1.
73 template <class T, class... Ts>
74 struct ElemTypeHolder<0, Tuple<T, Ts...>> {
75  typedef T type;
76 };
77 
78 /// \brief Specialisation of the \ref ElemTypeHolder class when the number of
79 /// the
80 /// elements inside the tuple is bigger than 1. It recursively calls itself to
81 /// detect the type of each element in the tuple.
82 /// \tparam T : the type of the first element in the tuple.
83 /// \tparam Ts... the rest of the elements in the tuple. Ts... can be empty.
84 /// \tparam K is the Kth element in the tuple.
85 template <size_t k, class T, class... Ts>
86 struct ElemTypeHolder<k, Tuple<T, Ts...>> {
87  typedef typename ElemTypeHolder<k - 1, Tuple<Ts...>>::type type;
88 };
89 
90 /// get
91 /// \brief Extracts the first element from the tuple.
92 /// K=0 represents the first element of the tuple. The tuple cannot be empty.
93 /// \tparam Ts... are the elements type in the tuple.
94 /// \param t is the tuple whose contents to extract.
95 /// \return typename ElemTypeHolder<0, Tuple<Ts...>>\::type &>\::type
96 template <size_t k, class... Ts>
97 typename EnableIf<k == 0,
98  typename ElemTypeHolder<0, Tuple<Ts...>>::type &>::type
100  return t.head;
101 }
102 
103 /// get
104 /// \brief Extracts the Kth element from the tuple.
105 /// \tparam K is an integer value in [0,sizeof...(Types)) range.
106 /// \tparam T is the (sizeof...(Types) -(K+1)) element in the tuple.
107 /// \tparam Ts... are the elements type in the tuple.
108 /// \param t is the tuple whose contents to extract.
109 /// \return typename ElemTypeHolder<K, Tuple<Ts...>>\::type &>\::type
110 template <size_t k, class T, class... Ts>
111 typename EnableIf<k != 0,
112  typename ElemTypeHolder<k, Tuple<T, Ts...>>::type &>::type
114  return get<k - 1>(t.tail);
115 }
116 
117 /// get
118 /// \brief Extracts the first element from the tuple when the tuple and all the
119 /// elements inside it are const.
120 /// K=0 represents the first element of the tuple. The tuple cannot be empty.
121 /// \tparam Ts... are the elements type in the tuple.
122 /// \param t is the const tuple whose contents to extract.
123 /// \return const typename ElemTypeHolder<0, Tuple<Ts...>>\::type &>\::type
124 template <size_t k, class... Ts>
125 typename EnableIf<k == 0,
126  const typename ElemTypeHolder<0, Tuple<Ts...>>::type &>::type
127 get(const Tuple<Ts...> &t) {
128  return t.head;
129 }
130 
131 /// get
132 /// \brief Extracts the Kth element from the tuple when the tuple and all the
133 /// elements inside are const.
134 /// \tparam K is an integer value in [0,sizeof...(Types)) range.
135 /// \tparam T is the (sizeof...(Types) -(K+1)) element in the tuple.
136 /// \tparam Ts... are the elements type in the tuple.
137 /// \param t is the const tuple whose contents to extract.
138 /// \return const typename ElemTypeHolder<K, Tuple<Ts...>>\::type &>\::type
139 template <size_t k, class T, class... Ts>
140 typename EnableIf<
141  k != 0, const typename ElemTypeHolder<k, Tuple<T, Ts...>>::type &>::type
142 get(const Tuple<T, Ts...> &t) {
143  return get<k - 1>(t.tail);
144 }
145 
146 /// make_tuple
147 /// \brief Creates a tuple object, deducing the target type from the types of
148 /// the arguments.
149 /// \tparam Args the type of the arguments to construct the tuple from.
150 /// \param args zero or more arguments to construct the tuple from.
151 /// \return Tuple<Args...>
152 template <typename... Args>
153 Tuple<Args...> make_tuple(Args... args) {
154  return Tuple<Args...>(args...);
155 }
156 
157 /// size
158 /// \brief Returns the number of the elements in the tuple as a
159 /// compile-time expression.
160 /// \tparam Args the type of the arguments to construct the tuple from.
161 /// \return size_t
162 template <typename... Args>
163 static constexpr size_t size(Tuple<Args...> &) {
164  return sizeof...(Args);
165 }
166 
167 /// \struct Index_list
168 /// \brief Creates a list of indices created for the elements in the tuple.
169 /// \tparam Is... a list of indices from range of [0 to sizeof...(tuple
170 /// elements)).
171 template <size_t... Is>
172 struct Index_list {};
173 
174 /// \struct RangeBuilder
175 /// \brief Collects internal details for index ranges generation [MIN, MAX).
176 /// Declares primary template for the RangeBuilder.
177 /// \tparam MIN is the starting index in the tuple.
178 /// \tparam N represents sizeof..(elemens)- sizeof...(Is)
179 /// \tparam Is... Collection of so far generated indices.
180 template <size_t MIN, size_t N, size_t... Is>
181 struct RangeBuilder;
182 
183 /// \brief Specialisation of the \ref RangeBuilder when the
184 /// MIN==MAX. In this case the Is... contains [0 to sizeof...(tuple elements))
185 /// indices.
186 /// \tparam MIN is the starting index of the tuple.
187 /// \tparam Is is collection of [0 to sizeof...(tuple elements)) indices.
188 template <size_t MIN, size_t... Is>
189 struct RangeBuilder<MIN, MIN, Is...> {
190  typedef Index_list<Is...> type;
191 };
192 
193 /// \brief Specialisation of the RangeBuilder class when N!=MIN.
194 /// In this case we are recursively subtracting the N by one and adding one
195 /// index to the Is... list until MIN==N.
196 /// \tparam MIN is the starting index in the tuple.
197 /// \tparam N represents reduction value from MAX which is equal to
198 /// sizeof..(elemens)- sizeof...(Is).
199 /// \tparam Is... Collection of so far generated indices.
200 template <size_t MIN, size_t N, size_t... Is>
201 struct RangeBuilder : public RangeBuilder<MIN, N - 1, N - 1, Is...> {};
202 
203 /// \brief IndexRange that returns a index from range of [MIN, MAX).
204 /// \tparam MIN is the starting index in the tuple.
205 /// \tparam MAX is the size of the tuple.
206 template <size_t MIN, size_t MAX>
208 
209 /// append_impl
210 /// \brief Unpacks the elements of the input tuple t and creates a new tuple
211 /// by adding the element a at the end of it.
212 /// \tparam Args... the type of the elements inside the tuple t.
213 /// \tparam T the type of the new element that is going to be added at the end
214 /// of the returned tuple.
215 /// \tparam I... is the list of indices from [0 to sizeof...(t)) range.
216 /// \param t the tuple on which we want to append a.
217 /// \param a the new elements that are going to be added to the returned tuple.
218 /// \return Tuple<Args..., T>
219 template <typename... Args, typename T, size_t... I>
222  return internal::tools::tuple::make_tuple(get<I>(t)..., a);
223 }
224 
225 /// append
226 /// \brief the deduction function for \ref append_impl that automatically
227 /// generates the \ref Index_range.
228 /// \tparam Args... the type of the elements inside the tuple t.
229 /// \tparam T the type of the new element that is going to be added at the end
230 /// of the returned tuple.
231 /// \param t the tuple on which we want to append a.
232 /// \param a the new elements that are going to be added to the returned tuple.
233 /// \return Tuple<Args..., T>
234 template <typename... Args, typename T>
235 Tuple<Args..., T> append(Tuple<Args...> t, T a) {
237  t, a, internal::tools::tuple::Index_range<0, sizeof...(Args)>());
238 }
239 
240 /// append_impl
241 /// \brief This is a specialisation of the \ref append_impl for the
242 /// concatenation
243 /// of the t2 tupe at the end of the t1 tuple. Both tuples are unpacked.
244 /// Index_range is generated for each of them and output tuple T is created.
245 /// The return tuple contains both elements of t1 and t2 tuples.
246 /// \tparam Args1... The type of the t1 tuple.
247 /// \tparam Args2... The type of the t2 tuple.
248 /// \tparam I1... The list of the indices from [0 to sizeof...(t1)) range.
249 /// \tparam I2... The list of the indices from [0 to sizeof...(t2)) range.
250 /// \param t1 Is the tuple on which we want to append the t2 tuple.
251 /// \param t2 Is the tuple to be appended.
252 /// \return Tuple<Args1..., Args2...>
253 template <typename... Args1, typename... Args2, size_t... I1, size_t... I2>
254 Tuple<Args1..., Args2...> append_impl(
260  internal::tools::tuple::get<I1>(t1)...,
261  internal::tools::tuple::get<I2>(t2)...);
262 }
263 
264 /// append
265 /// \brief Deduction function of the \ref append_impl for the append of the
266 /// tuple
267 /// t2 to the t1 tuple. The \ref Index_range for both tuple is automatically
268 /// generated.
269 /// \tparam Args1... The type of the t1 tuple.
270 /// \tparam Args2... The type of the t2 tuple.
271 /// \param t1 Is the tuple on which we want to append the t2 tuple.
272 /// \param t2 Is the tuple to be appended.
273 /// \return Tuple<Args1..., Args2...>
274 template <typename... Args1, typename... Args2>
278  t1, t2, internal::tools::tuple::Index_range<0, sizeof...(Args1)>(),
279  internal::tools::tuple::Index_range<0, sizeof...(Args2)>());
280 }
281 } // tuple
282 } // tools
283 } // internal
284 } // visioncpp
285 #endif // VISIONCPP_INCLUDE_FRAMEWORK_TOOLS_TUPLE_HPP_
Tuple< Args..., T > append_impl(internal::tools::tuple::Tuple< Args... > t, T a, internal::tools::tuple::Index_list< I... >)
append_impl
Definition: tuple.hpp:220
EnableIf< k==0, typename ElemTypeHolder< 0, Tuple< Ts... > >::type & >::type get(Tuple< Ts... > &t)
get
Definition: tuple.hpp:99
static constexpr size_t size(Tuple< Args... > &)
size
Definition: tuple.hpp:163
Tuple< Args..., T > append(Tuple< Args... > t, T a)
append
Definition: tuple.hpp:235
Tuple< Args... > make_tuple(Args... args)
make_tuple
Definition: tuple.hpp:153
typename RangeBuilder< MIN, MAX >::type Index_range
IndexRange that returns a index from range of [MIN, MAX).
Definition: tuple.hpp:207
VisionCpp namespace.
Definition: sycl/device.hpp:24
ElemTypeHolder< k - 1, Tuple< Ts... > >::type type
Definition: tuple.hpp:87
ElemTypeHolder class is used to specify the types of the elements inside the tuple.
Definition: tuple.hpp:68
The EnableIf struct is used to statically define type based on the condition.
Definition: tuple.hpp:36
Creates a list of indices created for the elements in the tuple.
Definition: tuple.hpp:172
Specialisation of the RangeBuilder class when N!=MIN.
Definition: tuple.hpp:201
Specialisation of the Tuple class when it has at least one element.
Definition: tuple.hpp:55
The tuple is a fixed-size collection of heterogeneous values.
Definition: tuple.hpp:48