Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
variadic-helper.hpp
Go to the documentation of this file.
1/*
2 VARIADIC-HELPER.hpp - metaprogramming utilities for parameter- and type sequences
3
4 Copyright (C)
5 2016, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
38#ifndef LIB_META_VARIADIC_HELPER_H
39#define LIB_META_VARIADIC_HELPER_H
40
41#include "lib/meta/typelist.hpp"
45#include "lib/meta/util.hpp"
46
47namespace lib {
48namespace meta {
49
50
51
52 /* ==== Build Variadic Sequences ==== **/
53
54
56 template<size_t...idx>
57 struct IndexSeq
58 {
59 template<size_t i>
60 using AppendElm = IndexSeq<idx..., i>;
61
62 template<size_t i>
63 using PrependElm = IndexSeq<i, idx...>;
64 };
65
70 template<size_t n>
72 {
73 using Ascending = BuildIndexSeq<n-1>::Ascending::template AppendElm<n-1>;
74 using Descending = BuildIndexSeq<n-1>::Descending::template PrependElm<n-1>;
75
76 template<size_t d>
78
79 template<size_t x>
81
82 template<size_t c>
83 using First = BuildIndexSeq<std::min(c,n)>::Ascending;
84
85 template<size_t c>
86 using After = BuildIndexSeq< (n>c)? n-c : 0>::template OffsetBy<c>;
87 };
88
89 template<>
90 struct BuildIndexSeq<0>
91 {
93
96
97 template<size_t>
99
100 template<size_t>
102
103 template<size_t>
105
106 template<size_t>
108 };
109
110
111
115 template<typename...TYPES>
117 {
118 enum {SIZ = sizeof...(TYPES) };
120
121 using Ascending = Builder::Ascending;
122 using Descending = Builder::Descending;
123
124 template<size_t d>
125 using OffsetBy = Builder::template OffsetBy<d>;
126
127 template<size_t x>
128 using FilledWith = Builder::template FilledWith<x>;
129
130 template<size_t c>
131 using First = Builder::template First<c>;
132
133 template<size_t c>
134 using After = Builder::template After<c>;
135 };
136
138 template<typename...TYPES>
140 : BuildIdxIter<TYPES...>
141 { };
142
143
144
145
146
147
148
149
150 /* ==== Build and Rebuild variadic type sequences ==== **/
151
165 template<class X, typename =void>
166 struct ElmTypes
167 {
168 static constexpr size_t SIZ = 1;
169 using Idx = std::index_sequence<SIZ>;
170 using Seq = Types<X>;
171 using Tup = std::tuple<X>;
172
173 template<template<class> class META>
175 template<template<typename...> class O>
176 using Rebind = O<X>;
177 template<template<class> class PRED>
178 using AndAll = std::__and_<PRED<X>>;
179 template<template<class> class PRED>
180 using OrAll = std::__or_<PRED<X>>;
181 };
182
184 template<typename...TYPES>
185 struct ElmTypes<Types<TYPES...>>
186 {
187 static constexpr size_t SIZ = sizeof...(TYPES);
188 using Idx = std::make_index_sequence<SIZ>;
189 using Seq = Types<TYPES...>;
190 using Tup = std::tuple<TYPES...>;
191
192 template<template<class> class META>
194
195 template<template<typename...> class O>
197
198 template<template<class> class PRED>
200
201 template<template<class> class PRED>
203 };
204
205 // Note: a further specialisation for any »tuple-like« is defined in tuple-helper.hpp
206
207
208
209
210
211
212 /* ==== Invoke with index from variadic ==== **/
213
220 template<size_t N>
222 {
223 template<class FUN, size_t...idx>
224 static constexpr void
225 invoke_forEach (FUN&& fun, std::index_sequence<idx...>)
226 {
227 (fun (std::integral_constant<size_t,idx>{}), ...);
228 }
229
230 template<class FUN, size_t...idx>
231 static constexpr bool
232 and_forEach (FUN&& fun, std::index_sequence<idx...>)
233 {
234 return (fun (std::integral_constant<size_t,idx>{}) and ...);
235 }
236
237 template<class FUN, size_t...idx>
238 static constexpr bool
239 or_forEach (FUN&& fun, std::index_sequence<idx...>)
240 {
241 return (fun (std::integral_constant<size_t,idx>{}) or ...);
242 }
243
244 using IdxSeq = std::make_index_sequence<N>;
245
246 public:
247 template<class FUN>
248 static constexpr void
249 invoke (FUN&& fun)
250 {
251 invoke_forEach (std::forward<FUN>(fun), IdxSeq{});
252 }
253
254 template<class FUN>
255 static constexpr bool
256 andAll (FUN&& fun)
257 {
258 return and_forEach (std::forward<FUN>(fun), IdxSeq{});
259 }
260
261 template<class FUN>
262 static constexpr bool
263 orAny (FUN&& fun)
264 {
265 return or_forEach (std::forward<FUN>(fun), IdxSeq{});
266 }
267 };
268
279 template<class TTX, class FUN>
280 inline void
282 {
283 WithIdxSeq<ElmTypes<TTX>::SIZ>::invoke (std::forward<FUN> (fun));
284 }
285
286 template<class TTX, class FUN>
287 inline bool
289 {
290 return WithIdxSeq<ElmTypes<TTX>::SIZ>::andAll (std::forward<FUN> (fun));
291 }
292
293 template<class TTX, class FUN>
294 inline bool
295 orAnyIDX (FUN&& fun)
296 {
297 return WithIdxSeq<ElmTypes<TTX>::SIZ>::orAny (std::forward<FUN> (fun));
298 }
299
300
301
302
303
304
305
306
307 /* ==== Manipulation of variadic arguments ==== **/
308
309 namespace { // Implementation delegate template...
315 template<size_t i>
317 {
318 template<typename ARG, typename...ARGS>
319 static auto
320 get (ARG, ARGS&& ...args)
321 {
322 return SelectVararg<i-1>::get (std::forward<ARGS> (args)...);
323 }
324 };
325
326 template<>
327 struct SelectVararg<0>
328 {
329 template<typename ARG, typename...ARGS>
330 static auto
331 get (ARG&& a, ARGS...)
332 {
333 return std::forward<ARG>(a);
334 }
335 };
336
342 template<bool, typename, size_t idx>
344 : SelectVararg<idx>
345 { };
346
347 template<typename DEFAULT, size_t idx>
349 {
350 template<typename...ARGS>
351 static DEFAULT
352 get (ARGS&&...)
353 {
354 return DEFAULT{};
355 }
356 };
357 }//(End)Implementation
358
359
368 template<size_t idx, typename...ARGS>
369 constexpr inline auto
370 pickArg (ARGS&&... args)
371 {
372 static_assert (idx < sizeof...(args), "insufficient number of arguments");
373
374 return SelectVararg<idx>::get (std::forward<ARGS> (args)...);
375 }
376
384 template<size_t idx, typename DEFAULT, typename...ARGS>
385 constexpr inline auto
386 pickInit (ARGS&&... args)
387 {
388 return SelectOrInit<(idx < sizeof...(args)), DEFAULT, idx>::get (std::forward<ARGS> (args)...);
389 }
390
391
392
393}} // namespace lib::meta
394#endif /*LIB_META_VARIADIC_HELPER_H*/
helper to invoke a functor, passing instances of std::integral_constant
static constexpr void invoke(FUN &&fun)
static constexpr bool and_forEach(FUN &&fun, std::index_sequence< idx... >)
static constexpr bool andAll(FUN &&fun)
std::make_index_sequence< N > IdxSeq
static constexpr void invoke_forEach(FUN &&fun, std::index_sequence< idx... >)
static constexpr bool or_forEach(FUN &&fun, std::index_sequence< idx... >)
static constexpr bool orAny(FUN &&fun)
Simple and lightweight helpers for metaprogramming and type detection.
bool orAnyIDX(FUN &&fun)
IndexSeq< idx..., i > AppendElm
IndexSeq< i, idx... > PrependElm
constexpr auto pickArg(ARGS &&... args)
Helper to single out one argument from a variadic argument pack.
BuildIndexSeq< n-1 >::template OffsetBy< d >::template AppendElm< n-1+d > OffsetBy
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
constexpr auto pickInit(ARGS &&... args)
Helper to pick one initialisation argument from a variadic argument pack, falling back to a default c...
BuildIndexSeq< n-1 >::Ascending::template AppendElm< n-1 > Ascending
void forEachIDX(FUN &&fun)
Invoke a function (or λ) with index numbers derived from some variadic count.
BuildIndexSeq< n-1 >::template FilledWith< x >::template AppendElm< x > FilledWith
BuildIndexSeq< std::min(c, n)>::Ascending First
BuildIndexSeq< n-1 >::Descending::template PrependElm< n-1 > Descending
BuildIndexSeq<(n >c)? n-c :0 >::template OffsetBy< c > After
bool andAllIDX(FUN &&fun)
build regular sequences of index number e.g.
Hold a sequence of index numbers as template parameters.
variadic sequence of types
Definition typelist.hpp:102
Implementation namespace for support and library code.
build a sequence of index numbers based on a type sequence
Builder::template FilledWith< x > FilledWith
Builder::template First< c > First
Builder::template OffsetBy< d > OffsetBy
Builder::template After< c > After
Builder::Descending Descending
Builder::Ascending Ascending
BuildIndexSeq< SIZ > Builder
std::make_index_sequence< SIZ > Idx
ElmTypes< Apply< PRED > >::template Rebind< std::__or_ > OrAll
lib::meta::RebindVariadic< O, Seq >::Type Rebind
ElmTypes< Apply< PRED > >::template Rebind< std::__and_ > AndAll
Variadic type sequence builder.
std::__or_< PRED< X > > OrAll
std::index_sequence< SIZ > Idx
static constexpr size_t SIZ
std::__and_< PRED< X > > AndAll
Types< META< X > > Apply
Metaprogramming: simple helpers for working with lists-of-types.
A template metaprogramming technique for manipulating collections of types.
Some basic facilities for manipulating type sequences.
Metaprogramming support to rebuild and rebind variadic templates.