SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
TupleTraits.h
Go to the documentation of this file.
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 
11 #ifndef smtk_TupleTraits_h
12 #define smtk_TupleTraits_h
13 
14 #include <cstddef>
15 #include <tuple>
16 
18 namespace smtk
19 {
20 
21 namespace detail
22 {
30 template<typename T, typename Tuple>
32 
34 template<typename T>
35 struct tuple_if_unique<T, std::tuple<>>
36 {
37  using type = std::tuple<T>;
38 };
39 
41 template<typename T, typename U, typename... Ts>
42 struct tuple_if_unique<T, std::tuple<U, Ts...>>
43 {
44  using type = typename tuple_if_unique<T, std::tuple<Ts...>>::type;
45 };
46 
48 template<typename T, typename... Ts>
49 struct tuple_if_unique<T, std::tuple<T, Ts...>>
50 {
51  using type = std::tuple<>;
52 };
53 
56 template<typename T, typename Tuple>
58 
60 template<typename T>
61 struct tuple_if_not_base<T, std::tuple<>>
62 {
63  using type = std::tuple<T>;
64 };
65 
67 template<typename T, typename U, typename... Ts>
68 struct tuple_if_not_base<T, std::tuple<U, Ts...>>
69 {
70  using type = typename std::conditional<
71  std::is_base_of<T, U>::value,
72  std::tuple<>,
73  typename tuple_if_not_base<T, std::tuple<Ts...>>::type>::type;
74 };
75 
79 template<typename T, typename... Args>
81 
82 template<>
83 struct remove_bases_from_tuple_lr<std::tuple<>>
84 {
85  using type = std::tuple<>;
86 };
87 
88 template<typename T>
89 struct remove_bases_from_tuple_lr<std::tuple<T>>
90 {
91  using type = std::tuple<T>;
92 };
93 
94 template<typename T, typename... Args>
95 struct remove_bases_from_tuple_lr<std::tuple<T, Args...>>
96 {
97  using type = decltype(std::tuple_cat(
98  std::declval<typename detail::tuple_if_not_base<T, std::tuple<Args...>>::type>(),
99  std::declval<typename remove_bases_from_tuple_lr<std::tuple<Args...>>::type>()));
100 };
101 
110 template<typename T>
111 struct untuple
112 {
113  using type = T;
114 };
115 
117 template<typename T>
118 struct untuple<std::tuple<T>>
119 {
120  using type = typename untuple<T>::type;
121 };
122 } // namespace detail
123 
133 template<typename T>
135 
137 template<>
138 struct flatten_tuple<std::tuple<>>
139 {
140  using type = std::tuple<>;
141 };
142 
144 template<typename T, typename... Args>
145 struct flatten_tuple<std::tuple<T, Args...>>
146 {
147  using type = decltype(std::tuple_cat(
148  std::declval<std::tuple<typename detail::untuple<T>::type>>(),
149  std::declval<typename flatten_tuple<std::tuple<Args...>>::type>()));
150 };
151 
153 template<typename... TupleArgs, typename... Args>
154 struct flatten_tuple<std::tuple<std::tuple<TupleArgs...>, Args...>>
155 {
156  using type = decltype(std::tuple_cat(
157  std::declval<std::tuple<TupleArgs...>>(),
158  std::declval<typename flatten_tuple<std::tuple<Args...>>::type>()));
159 };
160 
169 template<typename T, typename... Args>
171 
173 template<>
174 struct unique_tuple<std::tuple<>>
175 {
176  using type = std::tuple<>;
177 };
178 
180 template<typename T>
181 struct unique_tuple<std::tuple<T>>
182 {
183  using type = std::tuple<T>;
184 };
185 
187 template<typename T, typename... Args>
188 struct unique_tuple<std::tuple<T, Args...>>
189 {
190  using type = decltype(std::tuple_cat(
191  std::declval<typename detail::tuple_if_unique<T, std::tuple<Args...>>::type>(),
192  std::declval<typename unique_tuple<std::tuple<Args...>>::type>()));
193 };
194 
201 template<typename T>
203 
204 template<typename T>
205 struct reverse_tuple<std::tuple<T>>
206 {
207  using type = std::tuple<T>;
208 };
209 
210 template<typename T, typename... Args>
211 struct reverse_tuple<std::tuple<T, Args...>>
212 {
213  using type = decltype(std::tuple_cat(
214  std::declval<typename reverse_tuple<std::tuple<Args...>>::type>(),
215  std::declval<std::tuple<T>>()));
216 };
217 
227 template<template<typename> class X, typename T>
228 struct recursive
229 {
230  using type = typename X<T>::type;
231 };
232 
233 template<template<typename> class X, typename... Args>
234 struct recursive<X, std::tuple<Args...>>
235 {
236  using type = typename X<std::tuple<typename recursive<X, Args>::type...>>::type;
237 };
238 
241 template<typename T>
243 {
244  using type = typename detail::remove_bases_from_tuple_lr<typename reverse_tuple<
246  type;
247 };
248 
258 template<typename T, typename Tuple>
260 
262 template<typename T, typename... Args>
263 struct remove_from_tuple<T, std::tuple<T, Args...>>
264 {
265  using type = decltype(std::declval<typename remove_from_tuple<T, std::tuple<Args...>>::type>());
266 };
267 
269 template<typename T, typename X, typename... Args>
270 struct remove_from_tuple<T, std::tuple<X, Args...>>
271 {
272  using type = decltype(std::tuple_cat(
273  std::declval<std::tuple<X>>(),
274  std::declval<typename remove_from_tuple<T, std::tuple<Args...>>::type>()));
275 };
276 
278 template<typename T>
279 struct remove_from_tuple<T, std::tuple<>>
280 {
281  using type = std::tuple<>;
282 };
283 
291 template<class T, class Tuple>
292 struct tuple_index;
293 
295 template<class T, class... Types>
296 struct tuple_index<T, std::tuple<T, Types...>>
297 {
298  constexpr static const std::size_t value = 0;
299 };
300 
302 template<class T, class U, class... Types>
303 struct tuple_index<T, std::tuple<U, Types...>>
304 {
305  constexpr static const std::size_t value = 1 + tuple_index<T, std::tuple<Types...>>::value;
306 };
307 
316 template<typename T, typename Tuple>
318 
320 template<typename T>
321 struct tuple_contains<T, std::tuple<>> : std::false_type
322 {
323 };
324 
326 template<typename T, typename U, typename... Ts>
327 struct tuple_contains<T, std::tuple<U, Ts...>> : tuple_contains<T, std::tuple<Ts...>>
328 {
329 };
330 
332 template<typename T, typename... Ts>
333 struct tuple_contains<T, std::tuple<T, Ts...>> : std::true_type
334 {
335 };
336 
339 template<typename T>
340 struct identity
341 {
342  typedef T type;
343 };
344 
345 template<std::size_t...>
346 struct sequence
347 {
348 };
349 
350 template<std::size_t N, std::size_t... S>
351 struct index_sequence : index_sequence<N - 1, N - 1, S...>
352 {
353 };
354 
355 template<std::size_t... S>
356 struct index_sequence<0, S...>
357 {
358  typedef sequence<S...> type;
359 };
360 
361 namespace detail
362 {
363 
364 template<std::size_t I, typename RI, template<typename T, typename R> class Reducer, typename Tuple>
366 
367 template<typename RI, template<typename T, typename R> class Reducer, typename Tuple>
368 struct tuple_reduce_ii<0, RI, Reducer, Tuple>
369 {
370  using type = RI;
371 };
372 
373 template<std::size_t I, typename RI, template<typename T, typename R> class Reducer, typename Tuple>
374 struct tuple_reduce_ii
375 {
376  static_assert(I > 0, "This template can never terminate the sequence.");
377  using type = typename tuple_reduce_ii<
378  I - 1,
379  typename Reducer<
380  typename std::tuple_element<std::tuple_size<Tuple>::value - 1, Tuple>::type,
381  RI>::type,
382  Reducer,
383  Tuple>::type;
384 };
385 } // namespace detail
386 
412 template<template<typename T, typename RI> class Reducer, typename Tuple, typename Start>
414 {
415  using type = typename std::conditional<
416  std::tuple_size<Tuple>::value == 0,
417  Start,
418  typename detail::tuple_reduce_ii<std::tuple_size<Tuple>::value, Start, Reducer, Tuple>::type>::
419  type;
420 };
421 
454 template<typename Functor, size_t I = 0, typename... Ts>
455 typename std::enable_if<I == sizeof...(Ts), void>::type apply(Functor& f, std::tuple<Ts...> tup)
456 {
457 }
458 
459 template<typename Functor, size_t I = 0, typename... Ts>
460 typename std::enable_if<(I < sizeof...(Ts)), void>::type apply(Functor& f, std::tuple<Ts...> tup)
461 {
462  f(I, std::get<I>(tup));
463 
464  // Go to next element
465  apply<Functor, I + 1>(f, tup);
466 }
468 
495 template<typename Tuple, std::size_t I = 0, typename Functor>
496 typename std::enable_if<I == std::tuple_size<Tuple>::value, void>::type tuple_evaluate(Functor& f)
497 {
498  // Do nothing; no more tuple elements left.
499  (void)f;
500 }
501 
502 template<typename Tuple, std::size_t I = 0, typename Functor>
503 typename std::enable_if<(I < std::tuple_size<Tuple>::value), void>::type tuple_evaluate(Functor& f)
504 {
505  // Process the I-th tuple element...
506  f.template evaluate<typename std::tuple_element<I, Tuple>::type>(I);
507 
508  // ... and then go to next element
509  smtk::tuple_evaluate<Tuple, I + 1>(f);
510 }
511 
512 } // namespace smtk
513 
514 #endif
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::apply
std::enable_if< I==sizeof...(Ts), void >::type apply(Functor &f, std::tuple< Ts... > tup)
Apply a functor to each element of a tuple.
Definition: TupleTraits.h:455
smtk::tuple_reduce
A reduce operation for tuples of typenames.
Definition: TupleTraits.h:413
smtk::tuple_evaluate
std::enable_if< I==std::tuple_size< Tuple >::value, void >::type tuple_evaluate(Functor &f)
Invoke a Functor's evaluate() method on each type specified in a tuple.
Definition: TupleTraits.h:496
smtk::index_sequence
Definition: TupleTraits.h:351
smtk::remove_from_tuple
Takes a type and a tuple of types and returns a tuple with all of the original types sans the input t...
Definition: TupleTraits.h:259
smtk::tuple_index
Takes a type and a tuple of types and returns the index of the first instance of that type in the tup...
Definition: TupleTraits.h:292
smtk::sequence
Definition: TupleTraits.h:346
smtk::recursive
Takes a template class and a tuple and returns a tuple of elements transformed by the template class,...
Definition: TupleTraits.h:228
smtk::detail::tuple_if_not_base
If T is not a base of any types in Tuple, return std::tuple<T>.
Definition: TupleTraits.h:57
smtk::unique_tuple
Takes a tuple of potentially duplicate types and returns a tuple with the duplicate types removed.
Definition: TupleTraits.h:170
smtk::flatten_tuple
Takes a tuple of tuples and types and returns a tuple of the tuple contents and the plain types.
Definition: TupleTraits.h:134
smtk::detail::remove_bases_from_tuple_lr
Given a tuple, starting with the first parameter and moving to the last, remove the parameter from th...
Definition: TupleTraits.h:80
smtk::detail::tuple_reduce_ii
Definition: TupleTraits.h:365
smtk::reverse_tuple
Takes a tuple and reverses its arguments.
Definition: TupleTraits.h:202
smtk::detail::untuple
If T is a tuple containing a single type, return the type it contians.
Definition: TupleTraits.h:111
smtk::detail::tuple_if_unique
If T is not in Tuple, return std::tuple<T>.
Definition: TupleTraits.h:31
smtk::remove_bases_from_tuple
Takes a tuple and removes any types that are bases of any other types in the tuple.
Definition: TupleTraits.h:242
smtk::identity
Embeds a type in another class so its type information can be passed as a parameter.
Definition: TupleTraits.h:340
smtk::tuple_contains
Takes a type and a tuple of types and returns a bool indicating whether or not the type is in the tup...
Definition: TupleTraits.h:317