meta.hpp
Go to the documentation of this file.
1 
14 #ifndef CORE_META_HPP
15 #define CORE_META_HPP
16 
17 #include <type_traits>
18 #include <limits>
19 #include <tuple>
20 
21 #include <cstdint>
22 #include <cstddef>
23 
24 namespace core {
25 inline namespace v2 {
26 namespace meta {
27 namespace impl {
28 
29 using false_t = ::std::false_type;
30 using true_t = ::std::true_type;
31 
32 template <class T, T V> using integral = ::std::integral_constant<T, V>;
33 template <bool B> using boolean = integral<bool, B>;
34 
35 template <class T> struct identity { using type = T; };
36 
37 template <class...> struct deducer : identity<void> { };
38 template <class... Ts> using deduce = typename deducer<Ts...>::type;
39 
40 template <class T, class V, template <class...> class Detector, class... Args>
41 struct detect : identity<T> { using value = false_t; };
42 
43 template <class T, template <class...> class Detector, class... Args>
44 struct detect<T, deduce<Detector<Args...>>, Detector, Args...> :
45  identity<Detector<Args...>>
46 { using value = true_t; };
47 
48 template <class... Ts>
49 struct list {
50  static constexpr ::std::size_t size () noexcept { return sizeof...(Ts); }
51  static constexpr bool empty () noexcept { return size() == 0u; }
52 };
53 
54 template <class, template <class...> class> struct convert;
55 template <class, class> struct rebind;
56 template <class> struct into;
57 
58 template <class, template <class...> class, class...> struct filter;
59 template <class, template <class...> class, class...> struct map;
60 template <class...> struct join;
61 
62 template <template <class...> class, class...> struct apply;
63 
64 template <class, ::std::size_t> struct get;
65 template <class, class> struct index_of;
66 template <class> struct head;
67 template <class> struct tail;
68 
69 template <class, template <class...> class, class...> struct count_if;
70 template <class, template <class...> class, class...> struct find_if;
71 template <class, class> struct count;
72 template <class, class> struct find;
73 
74 template <class, ::std::size_t> struct rotate;
75 template <class> struct reverse;
76 
77 template <class, class> struct equal;
78 
79 template <class, template <class...> class, class...> struct none_of;
80 template <class, template <class...> class, class...> struct all_of;
81 template <class, template <class...> class, class...> struct any_of;
82 
83 template <bool...> struct none;
84 template <bool...> struct all;
85 template <bool...> struct any;
86 
87 template <class... Ts, template <class...> class To>
88 struct convert<list<Ts...>, To> : identity<To<Ts...>> { };
89 
90 template <template <class...> class To, class... Ts, class... Us>
91 struct rebind<list<Ts...>, To<Us...>> : identity<To<Ts...>> { };
92 
93 template <template <class...> class T, class... Ts>
94 struct into<T<Ts...>> : identity<list<Ts...>> { };
95 
96 template <template <class...> class F, class... Ts, class... Args>
97 struct filter<list<Ts...>, F, Args...> :
98  join<
99  typename ::std::conditional<
100  F<Ts, Args...>::value,
101  list<Ts>,
102  list<>
103  >::type...
104  >
105 { };
106 
107 template <template <class...> class F, class... Ts, class... Args>
108 struct map<list<Ts...>, F, Args...> : identity<list<F<Ts, Args...>...>> { };
109 
110 template <class... Ts> struct join<list<Ts...>> : identity<list<Ts...>> { };
111 template <class... Ts, class... Us, class... Vs>
112 struct join<list<Ts...>, list<Us...>, Vs...> :
113  join<list<Ts..., Us...>, Vs...>
114 { };
115 
116 template <class T, class... Ts>
117 struct index_of<list<Ts...>, T> : integral<
118  ::std::size_t,
119  list<Ts...>::size() - find<list<Ts...>, T>::type::size()
120 > { };
121 
122 template <class T, class... Ts>
123 struct get<list<T, Ts...>, 0> : identity<T> { };
124 template <class T, class... Ts, size_t N>
125 struct get<list<T, Ts...>, N> :
126  get<list<Ts...>, N - 1>
127 { static_assert(N < (sizeof...(Ts) + 1),""); };
128 
129 
130 template <class T, class... Ts>
131 struct head<list<T, Ts...>> : identity<T> { };
132 template <class T, class... Ts>
133 struct tail<list<T, Ts...>> : identity<list<Ts...>> { };
134 
135 template <class... Ts, template <class...> class F, class... Args>
136 struct count_if<list<Ts...>, F, Args...> : integral<
137  ::std::size_t,
138  filter<list<Ts...>, F, Args...>::type::size()
139 > { };
140 
141 template <template <class...> class F, class... Args>
142 struct find_if<list<>, F, Args...> : identity<list<>> { };
143 
144 template <template <class...> class F, class T, class... Ts, class... Args>
145 struct find_if<list<T, Ts...>, F, Args...> : ::std::conditional<
146  F<Args..., T>::value,
147  list<T, Ts...>,
148  typename find_if<list<Ts...>, F, Args...>::type
149 > { };
150 
151 template <class T, class U> struct count : count_if<T, ::std::is_same, U> { };
152 template <class T, class U> struct find : find_if<T, ::std::is_same, U> { };
153 
154 template <template <class...> class F, class... Ts, class... Args>
155 struct none_of<list<Ts...>, F, Args...> : none<F<Ts, Args...>::value...> { };
156 
157 template <template <class...> class F, class... Ts, class... Args>
158 struct all_of<list<Ts...>, F, Args...> : all<F<Ts, Args...>::value...> { };
159 
160 template <template <class...> class F, class... Ts, class... Args>
161 struct any_of<list<Ts...>, F, Args...> : any<F<Ts, Args...>::value...> { };
162 
163 template <bool B, bool... Bs> struct none<B, Bs...> :
164  boolean<not B and none<Bs...>::value>
165 { };
166 template <> struct none<> : true_t { };
167 
168 template <bool B, bool... Bs> struct all<B, Bs...> :
169  boolean<B and all<Bs...>::value>
170 { };
171 template <> struct all<> : true_t { };
172 
173 template <bool B, bool... Bs> struct any<B, Bs...> :
174  boolean<B or any<Bs...>::value>
175 { };
176 template <> struct any<> : false_t { };
177 
178 template <class T, template <class...> class U>
180 template <template <class...> class T, class... Ts>
181 struct is_specialization_of<T<Ts...>, T> : true_t { };
182 
183 }}}} /* namespace core::v2::meta::impl */
184 
185 namespace core {
186 inline namespace v2 {
187 namespace meta {
188 
189 template <bool B, class T = void>
190 using unless = typename ::std::enable_if<not B, T>::type;
191 
192 template <bool B, class T = void>
193 using when = typename ::std::enable_if<B, T>::type;
194 
195 template <bool B> using inhibit = unless<B, ::std::size_t>;
196 template <bool B> using require = when<B, ::std::size_t>;
197 
198 template <bool B, class T, class F>
199 using either = typename ::std::conditional<B, T, F>::type;
200 
201 using impl::integral;
202 using impl::boolean;
203 
204 using impl::false_t;
205 using impl::true_t;
206 
207 using impl::identity;
208 using impl::list;
209 
211 
212 template <class... Ts> using deduce = typename impl::deduce<Ts...>;
213 
214 template <class T, template <class...> class U>
216 
217 template <class T, class U> using rebind = typename impl::rebind<T, U>::type;
218 template <class T> using into = typename impl::into<T>::type;
219 
220 template <class... Ts> using join = typename impl::join<Ts...>::type;
221 
222 template <class T, size_t N> using get = typename impl::get<T, N>::type;
223 template <class T> using head = typename impl::head<T>::type;
224 template <class T> using tail = typename impl::tail<T>::type;
225 
226 template <class T, class U>
228 
229 template <class T, template <class...> class F, class... Args>
230 using count_if_t = impl::count_if<T, F, Args...>;
231 
232 template <class T, template <class...> class F, class... Args>
234 
235 template <class T, class U> using count_t = impl::count<T, U>;
236 
237 template <class T, class U>
238 using find = typename impl::find<T, U>::type;
239 
240 template <class T, template <class...> class F, class... Args>
241 using none_of_t = impl::none_of<T, F, Args...>;
242 
243 template <class T, template <class...> class F, class... Args>
244 using all_of_t = impl::all_of<T, F, Args...>;
245 
246 template <class T, template <class...> class F, class... Args>
247 using any_of_t = impl::any_of<T, F, Args...>;
248 
249 template <bool... Bs> using none_t = impl::none<Bs...>;
250 template <bool... Bs> using all_t = impl::all<Bs...>;
251 template <bool... Bs> using any_t = impl::any<Bs...>;
252 
253 template <class T, class U>
254 constexpr ::std::size_t index_of () noexcept {
256 }
257 
258 template <class T, template <class...> class F, class... Args>
259 constexpr ::std::size_t count_if () noexcept {
260  return count_if_t<T, F, Args...>::value;
261 }
262 
263 template <class T, class U>
264 constexpr ::std::size_t count () noexcept { return count_t<T, U>::value; }
265 
266 template <class T, template <class...> class F, class... Args>
267 constexpr bool none_of () noexcept { return none_of_t<T, F, Args...>::value; }
268 
269 template <class T, template <class...> class F, class... Args>
270 constexpr bool all_of () noexcept { return all_of_t<T, F, Args...>::value; }
271 
272 template <class T, template <class...> class F, class... Args>
273 constexpr bool any_of () noexcept { return any_of_t<T, F, Args...>::value; }
274 
275 template <bool... Bs>
276 constexpr bool none () noexcept { return none_t<Bs...>::value; }
277 
278 template <bool... Bs>
279 constexpr bool all () noexcept { return all_t<Bs...>::value; }
280 
281 template <bool... Bs>
282 constexpr bool any () noexcept { return any_t<Bs...>::value; }
283 
284 }}} /* namespace core::v2::meta */
285 
286 namespace core {
287 inline namespace v2 {
288 namespace meta {
289 
290 template <class T, T... I> struct integer_sequence : identity<T> {
291  static_assert(
292  ::std::is_integral<T>::value,
293  "integer_sequence must use an integral type"
294  );
295 
296  template <T N> using append = integer_sequence<T, I..., N>;
297  static constexpr ::std::size_t size() noexcept { return sizeof...(I); }
298  using next = append<sizeof...(I)>;
299 };
300 
301 template <class T, T Index, ::std::size_t N>
302 struct iota : identity<
303  typename iota<T, Index - 1, N - 1u>::type::next
304 > { static_assert(Index >= 0, "Index cannot be negative"); };
305 
306 template <class T, T Index>
307 struct iota<T, Index, 0u> : identity<integer_sequence<T>> { };
308 
309 template <::std::size_t... I>
310 using index_sequence = integer_sequence<::std::size_t, I...>;
311 
312 template <class T, T N>
314 
315 template <::std::size_t N>
317 
318 template <class... Ts>
320 
321 template <class> struct index_sequence_from;
322 
323 }}} /* namespace core::meta::v2 */
324 
325 #endif /* CORE_META_HPP */
auto rotate(Range &&rng, ForwardIt &&it) -> enable_if_t< is_range< Range >::value >
Definition: algorithm.hpp:1134
constexpr bool any() noexcept
Definition: meta.hpp:282
typename impl::find_if< T, F >::type find_if
Definition: meta.hpp:233
::std::false_type false_t
Definition: meta.hpp:29
::std::integral_constant< T, V > integral
Definition: meta.hpp:32
constexpr auto size(Container const &container) noexcept -> decltype(container.size())
Definition: iterator.hpp:29
auto apply(F &&f, T &&t, index_sequence< I... >) -> decltype(invoke(core::forward< F >(f), ::std::get< I >(core::forward< T >(t))...))
Definition: functional.hpp:92
meta::identity< T > identity
Definition: type_traits.hpp:30
constexpr bool none() noexcept
Definition: meta.hpp:276
Copyright © 2013 - 2015 MNMLSTC.
Definition: algorithm.hpp:23
constexpr bool all_of() noexcept
Definition: meta.hpp:270
typename impl::find< T, U >::type find
Definition: meta.hpp:238
typename impl::convert< T, U >::type convert
Definition: meta.hpp:215
constexpr bool all() noexcept
Definition: meta.hpp:279
typename impl::into< T >::type into
Definition: meta.hpp:218
typename impl::rebind< T, U >::type rebind
Definition: meta.hpp:217
constexpr bool any_of() noexcept
Definition: meta.hpp:273
auto reverse(Range &&rng) -> enable_if_t< is_range< Range >::value >
Definition: algorithm.hpp:1111
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: meta.hpp:319
static constexpr ::std::size_t size() noexcept
Definition: meta.hpp:297
typename ::std::enable_if< not B, T >::type unless
Definition: meta.hpp:190
static constexpr bool empty() noexcept
Definition: meta.hpp:51
static constexpr ::std::size_t size() noexcept
Definition: meta.hpp:50
constexpr ::std::size_t index_of() noexcept
Definition: meta.hpp:254
typename iota< T, N, N >::type make_integer_sequence
Definition: meta.hpp:313
typename ::std::enable_if< B, T >::type when
Definition: meta.hpp:193
unless< B, ::std::size_t > inhibit
Definition: meta.hpp:195
integral< bool, B > boolean
Definition: meta.hpp:33
when< B, ::std::size_t > require
Definition: meta.hpp:196
typename impl::tail< T >::type tail
Definition: meta.hpp:224
list(APPEND ${name}_METHOD_MAIN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${name}_${method}_main.cpp) list(APPEND $
Definition: CMakeLists.txt:30
typename impl::join< Ts... >::type join
Definition: meta.hpp:220
constexpr ::std::size_t count() noexcept
Definition: meta.hpp:264
typename deducer< Ts... >::type deduce
Definition: meta.hpp:38
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate bp)
Definition: algorithm.hpp:355
typename impl::deduce< Ts... > deduce
Definition: meta.hpp:212
typename impl::head< T >::type head
Definition: meta.hpp:223
constexpr bool none_of() noexcept
Definition: meta.hpp:267
typename ::std::conditional< B, T, F >::type either
Definition: meta.hpp:199
constexpr ::std::size_t count_if() noexcept
Definition: meta.hpp:259
::std::true_type true_t
Definition: meta.hpp:30
make_integer_sequence<::std::size_t, N > make_index_sequence
Definition: meta.hpp:316