Lumiera  0.pre.03
»edit your freedom«
tuple-helper.hpp
Go to the documentation of this file.
1 /*
2  TUPLE-HELPER.hpp - metaprogramming utilities for type and data tuples
3 
4  Copyright (C) Lumiera.org
5  2016, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
50 #ifndef LIB_META_TUPLE_HELPER_H
51 #define LIB_META_TUPLE_HELPER_H
52 
53 #include "lib/meta/typelist.hpp"
57 #include "lib/meta/util.hpp"
58 
59 #include <tuple>
60 
61 
62 namespace util { // forward declaration
63 
64  template<typename TY>
65  std::string
66  toString (TY const& val) noexcept;
67 }
68 
69 
70 namespace lib {
71 namespace meta {
72 
81  template<class FUN, typename...ELMS>
82  void forEach (std::tuple<ELMS...>&& tuple, FUN fun)
83  {
84  std::apply ([&fun](auto&... elms)
85  {
86  (fun(elms), ...);
87  }
88  ,tuple);
89  }
90 
91 
92 
93  namespace { // rebinding helper to create std::tuple from a type sequence
94 
95  template<typename SEQ>
97  : std::false_type
98  { };
99 
100  template<typename...TYPES>
101  struct BuildTupleType<TySeq<TYPES...>>
102  {
103  using Type = std::tuple<TYPES...>;
104  };
105 
110  template<typename...TYPES>
111  struct BuildTupleType<Types<TYPES...>>
112  {
113  using VariadicSeq = typename StripNullType<Types<TYPES...>>::Seq;
114 
115  using Type = typename BuildTupleType<VariadicSeq>::Type;
116  };
117 
118  template<class H, typename TAIL>
119  struct BuildTupleType<Node<H, TAIL>>
120  {
121  using Seq = typename Types< Node<H,TAIL>>::Seq;
122  using Type = typename BuildTupleType<Seq>::Type;
123  };
124 
125  template<>
127  {
128  using Type = typename BuildTupleType<Types<>>::Type;
129  };
130  }
131 
132 
141  template<typename TYPES>
142  using Tuple = typename BuildTupleType<TYPES>::Type;
143 
144 
145  using std::tuple_size;
146  using std::tuple_element;
147 
148 
149 
151  template<typename...TYPES>
153  {
154  using Seq = typename Types<TYPES...>::Seq;
155  using List = typename Seq::List;
156  };
157  template<typename...TYPES>
158  struct RebindTupleTypes<std::tuple<TYPES...>>
159  {
160  using Seq = typename Types<TYPES...>::Seq;
161  using List = typename Seq::List;
162  };
163 
164 
166  template<typename T>
167  struct is_Tuple
168  : std::false_type
169  { };
170 
171  template<typename...TYPES>
172  struct is_Tuple<std::tuple<TYPES...>>
173  : std::true_type
174  { };
175 
176 
177 
178 
179 
180 
202  template< typename TYPES
203  , template<class,class, size_t> class _ElmMapper_
204  >
206  : Tuple<TYPES>
207  {
209  using SequenceIterator = typename BuildIdxIter<TYPES>::Ascending;
210 
211  protected:
212  template<class SRC, size_t...idx>
213  TupleConstructor (SRC values, IndexSeq<idx...>)
214  : Tuple<TYPES> (_ElmMapper_<SRC, Tuple<TYPES>, idx>{values}...)
215  { }
216 
217 
218  public:
219  template<class SRC>
220  TupleConstructor (SRC values)
221  : TupleConstructor (values, SequenceIterator())
222  { }
223  };
224 
225 
234  template<class SRC, class TAR>
236 
237 
238  template<class SRC, class TAR, size_t i>
239  using ExtractArg = typename ElementExtractor<SRC, TAR>::template Access<i>;
240 
241 
251  template<typename TYPES, class SRC>
253  buildTuple (SRC values)
254  {
255  return TupleConstructor<TYPES, ExtractArg> (values);
256  }
257 
258 
259 
260 
261 
262 
263 
264 
283  template
284  < template<class,class,class, uint> class _X_
285  , typename TYPES
286  , class TUP =Tuple<TYPES>
287  , uint i = 0
288  >
290  {
291  // prepare recursion...
292  using Head = typename Split<TYPES>::Head;
293  using Tail = typename Split<TYPES>::Tail;
295  using NextAccessor = typename NextBuilder::Product;
296  public:
297 
300  using Product = _X_< Head // the type to use for this accessor
301  , NextAccessor // the base type to inherit from
302  , TUP // the tuple type we build upon
303  , i // current element index
304  >;
305  };
306 
307 
308  template
309  < template<class,class,class, uint> class _X_
310  , class TUP
311  , uint i
312  >
313  class BuildTupleAccessor< _X_, Types<>, TUP, i>
314  {
315  public:
316  using Product = _X_<NullType, TUP, TUP, i>; // Note: i == tuple size
317 
318  };
319 
320 
321 
328  template
329  < typename TY
330  , class BASE
331  , class TUP
332  , uint idx
333  >
335  : BASE
336  {
337  using BASE::BASE;
338 
339  std::string
340  dump (std::string const& prefix ="(") const
341  {
342  return BASE::dump (prefix + util::toString(std::get<idx>(*this))+",");
343  }
344  };
345 
346  template<class TUP, uint n>
347  struct TupleElementDisplayer<NullType, TUP, TUP, n>
348  : TUP
349  {
350  TupleElementDisplayer (TUP const& tup)
351  : TUP(tup)
352  { }
353 
354  std::string
355  dump (std::string const& prefix ="(") const
356  {
357  if (1 < prefix.length())
358  // remove the trailing comma
359  return prefix.substr (0, prefix.length()-1) +")";
360  else
361  return prefix+")";
362  }
363  };
364 
365 
374  template<typename...TYPES>
375  inline std::string
376  dump (std::tuple<TYPES...> const& tuple)
377  {
378  using BuildAccessor = BuildTupleAccessor<TupleElementDisplayer, Types<TYPES...>>;
379  using Displayer = typename BuildAccessor::Product ;
380 
381  return static_cast<Displayer const&> (tuple)
382  .dump();
383  }
384 
385 
386 
387 }} // namespace lib::meta
388 
389 
390 // add a specialisation to enable tuple string conversion
391 namespace util {
392 
393  template<typename...TYPES>
394  struct StringConv<std::tuple<TYPES...>>
395  {
396  static std::string
397  invoke (std::tuple<TYPES...> const& tuple) noexcept
398  try {
399  return "«"+typeStr(tuple)
400  + "»──" + lib::meta::dump (tuple);
401  }
402  catch(...) { return FAILURE_INDICATOR; }
403  };
404 
405 
406 } // namespace util
407 #endif /*LIB_META_TUPLE_HELPER_H*/
Hold a sequence of index numbers as template parameters.
A template metaprogramming technique for manipulating collections of types.
trait to detect tuple types
typename BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
Simple and lightweight helpers for metaprogramming and type detection.
Extensible Adapter to construct a distinct tuple from some arbitrary source type. ...
STL namespace.
temporary workaround: alternative definition of "type sequence", already using variadic template para...
Metaprogramming: simple helpers for working with lists-of-types.
Some basic facilities for manipulating type sequences.
Generic converter to somehow extract values from the "source" type to fill and initialise a tuple of ...
_X_< Head, NextAccessor, TUP, i > Product
type of the product created by this template.
Tuple< TYPES > buildTuple(SRC values)
convenience shortcut to build a tuple from some suitable source data.
Implementation namespace for support and library code.
temporary workaround: strip trailing NullType entries from a type sequence, to make it compatible wit...
void forEach(std::tuple< ELMS... > &&tuple, FUN fun)
Helper: perform some arbitrary operation on each element of a tuple.
Helper: separate parts of a type sequence.
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Definition: format-obj.hpp:200
temporary workaround: match and rebind the type sequence from a tuple
Decorating a tuple type with auxiliary data access operations.
typename BuildIdxIter< TYPES >::Ascending SequenceIterator
meta-sequence to drive instantiation of the ElmMapper
failsafe invocation of custom string conversion.
Definition: meta/util.hpp:399
Metaprogramming with type sequences based on variadic template parameters.
Helper to dump tuple contents.
std::string dump(std::tuple< TYPES... > const &tuple)
convenience function to dump a given tuple&#39;s contents.