Variadic.hpp
Go to the documentation of this file.
1 //
3 // Aurora C++ Library
4 // Copyright (c) 2012-2016 Jan Haller
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not be
20 // misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source distribution.
23 //
25 
28 
29 #ifndef AURORA_VARIADIC_HPP
30 #define AURORA_VARIADIC_HPP
31 
32 #include <Aurora/Config.hpp>
33 
34 #include <utility> // std::forward()
35 
36 #ifdef AURORA_HAS_VARIADIC_TEMPLATES
37 
38 namespace aurora
39 {
40 
41 template <typename... Ts>
42 struct Typelist;
43 
44 namespace detail
45 {
46 
47  // Reverse of NthType: get index of type T in typelist Types
48  template <typename T, typename... Types>
49  struct IndexOfType;
50 
51  template <typename T, typename Head, typename... Tail>
52  struct IndexOfType<T, Head, Tail...>
53  {
54  static const std::size_t value = 1 + IndexOfType<T, Tail...>::value;
55  };
56 
57  template <typename T, typename... Tail>
58  struct IndexOfType<T, T, Tail...>
59  {
60  static const std::size_t value = 0;
61  };
62 
63 
64  // Metafunction to apply a class template 'Function' to each type of variadic pack typelist
65  template <typename Function, typename... Ts>
66  struct ForEachType;
67 
68  template <typename Function, typename T, typename... Ts>
69  struct ForEachType<Function, T, Ts...>
70  {
71  static void apply(Function&& fn)
72  {
73  // Note: Calling member operator template with explicit template argument is not too elegant
74  // Possible alternative is aurora::Type<T> argument.
75 #ifdef _MSC_VER
76  fn.operator()<T>();
77 #else
78  fn.template operator()<T>();
79 #endif
80  ForEachType<Function, Ts...>::apply(std::forward<Function>(fn));
81  }
82  };
83 
84  template <typename Function>
85  struct ForEachType<Function>
86  {
87  static void apply(Function&& /*fn*/)
88  {
89  }
90  };
91 
92  // Specialization for typelists: Unpack arguments and use ForEachType as usual
93  template <typename Function, typename... Ts>
94  struct ForEachType<Function, Typelist<Ts...>> : ForEachType<Function, Ts...>
95  {
96  };
97 
98 
99  // Metafunction to apply a class template 'Function' to each value of variadic pack
100  template <typename Function, typename... Ts>
101  struct ForEachValue;
102 
103  template <typename Function, typename T, typename... Ts>
104  struct ForEachValue<Function, T, Ts...>
105  {
106  static void apply(Function&& fn, T&& t, Ts&&... ts)
107  {
108  fn(std::forward<T>(t));
109  ForEachValue<Function, Ts...>::apply(std::forward<Function>(fn), std::forward<Ts>(ts)...);
110  }
111  };
112 
113  template <typename Function>
114  struct ForEachValue<Function>
115  {
116  static void apply(Function&& /*fn*/)
117  {
118  }
119  };
120 
121 } // namespace detail
122 
123 
126 
133 template <typename... Ts>
134 struct Typelist
135 {
136 };
137 
138 
141 template <typename Types, std::size_t Index>
142 struct TypelistAt;
143 
144 template <typename Head, typename... Tail, std::size_t Index>
145 struct TypelistAt<Typelist<Head, Tail...>, Index>
146 {
147  typedef typename TypelistAt<Typelist<Tail...>, Index - 1u>::Type Type;
148 };
149 
150 template <typename Head, typename... Tail>
151 struct TypelistAt<Typelist<Head, Tail...>, 0u>
152 {
153  typedef Head Type;
154 };
155 
156 
159 template <typename Types, typename Searched>
161 
162 template <typename Head, typename... Tail, typename Searched>
163 struct TypelistFind<Typelist<Head, Tail...>, Searched>
164 {
165  static const std::size_t value = TypelistFind<Typelist<Tail...>, Searched>::value + 1u;
166 };
167 
168 template <typename Head, typename... Tail>
169 struct TypelistFind<Typelist<Head, Tail...>, Head>
170 {
171  static const std::size_t value = 0u;
172 };
173 
174 
177 template <typename LhsTypelist, typename RhsTypelist>
178 struct TypelistCat;
179 
180 template <typename... Ts, typename... Us>
181 struct TypelistCat<Typelist<Ts...>, Typelist<Us...>>
182 {
183  typedef Typelist<Ts..., Us...> Type;
184 };
185 
186 
189 template <typename Typelist1, typename T>
191 
192 template <typename U, typename... Us, typename T>
193 struct TypelistContains<Typelist<U, Us...>, T>
194 {
195  static const bool value =
196  std::is_same<U, T>::value || TypelistContains<Typelist<Us...>, T>::value;
197 };
198 
199 template <typename T>
200 struct TypelistContains<Typelist<>, T>
201 {
202  static const bool value = false;
203 };
204 
205 
222 template <typename... Ts, typename Function>
223 void foreach(Function&& fn)
224 {
225  detail::ForEachType<Function, Ts...>::apply(std::forward<Function>(fn));
226 }
227 
245 template <typename... Ts, typename Function>
246 void foreach(Function&& fn, Ts&&... args)
247 {
248  detail::ForEachValue<Function, Ts...>::apply(std::forward<Function>(fn), std::forward<Ts>(args)...);
249 }
250 
252 
253 } // namespace aurora
254 
255 #endif // AURORA_HAS_VARIADIC_TEMPLATES
256 #endif // AURORA_VARIADIC_HPP
Concatenate two typelists.
Definition: Variadic.hpp:178
Check if type is part of typelist.
Definition: Variadic.hpp:190
Simple type wrapper, can be used for overload resolution.
Definition: Templates.hpp:120
Configuration header of the library.
Random access to type.
Definition: Variadic.hpp:142
Find position of type in typelist.
Definition: Variadic.hpp:160
Class template to store a list of types.
Definition: Variadic.hpp:42
Definition: DispatchTraits.hpp:39