Lumiera  0.pre.03
»edit your freedom«
tuple-record-init.hpp
Go to the documentation of this file.
1 /*
2  TUPLE-RECORD-INIT.hpp - adapter to construct tuple components from GenNode entries
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 
49 #ifndef LIB_META_TUPLE_RECORD_INIT_H
50 #define LIB_META_TUPLE_RECORD_INIT_H
51 
55 #include "lib/meta/generator.hpp"
56 #include "lib/diff/gen-node.hpp"
57 #include "lib/meta/trait.hpp"
58 
59 
60 
61 namespace lib {
62 namespace meta {
63  namespace error = lumiera::error;
64 
65  namespace { // implementation details...
66 
67  using lib::Variant;
68  using lib::diff::Rec;
69  using lib::diff::GenNode;
71 
72 
75 
76 
90  template<typename TAR>
93  {
94 
95  template<typename TY>
97  : __and_<is_constructible<TAR, TY const&>
98  ,__not_<is_narrowingInit<typename Strip<TY>::TypePlain
99  ,typename Strip<TAR>::TypePlain>>
100  >
101  { };
102 
103  using SupportedSourceTypes = typename Filter<DataValues::List, allow_Conversion>::List;
104 
105 
106 
109  {
110  char buffer[sizeof(TAR)];
111  };
112 
113  template<typename TY, class BA>
114  class Converter
115  : public BA
116  {
117  virtual bool
118  handle(TY const& srcElm)
119  {
120  new(&(BA::buffer)) TAR{srcElm};
121  return true;
122  };
123  };
124 
125 
126  using ConversionBuffer = InstantiateChained< SupportedSourceTypes // for each of those types...
127  , Converter // instantiate the Converter template
128  , ConverterBase // and use this as common base class.
129  >; // RESULT: for each type we get a handle(TY)
130 
131  ConversionBuffer converter_;
132 
133  TAR&
134  accessTargetElement()
135  {
136  return *reinterpret_cast<TAR*> (&converter_.buffer);
137  }
138 
139 
140  public:
141  GenNodeAccessor (GenNode const& node)
142  : converter_()
143  {
144  if (not node.data.accept (converter_))
145  throw error::Invalid ("Unable to build «" + util::typeStr<TAR>()
146  +"» element from " + string(node)
147  ,error::LUMIERA_ERROR_WRONG_TYPE);
148  }
149 
152  {
153  accessTargetElement().~TAR();
154  }
155 
156 
157  operator TAR ()
158  {
159  return accessTargetElement();
160  }
161  };
162 
163  }//(End)implementation details
164 
165 
166 
167 
185  template<typename...TYPES>
186  struct ElementExtractor<lib::diff::Rec, std::tuple<TYPES...>>
187  {
188  template<size_t i>
189  using TargetType = typename Pick<Types<TYPES...>, i>::Type;
190 
191 
192  template<size_t i>
193  struct Access
194  {
195  Rec const& values;
196 
197  operator TargetType<i> ()
198  {
199  using util::toString;
200 
201  if (values.childSize() <= i)
202  throw error::Logic ("Attempt to init the " + toString(sizeof...(TYPES))
203  +" element " + util::typeStr<std::tuple<TYPES...>>()
204  +" from an Rec<GenNode> with only " + toString(values.childSize())
205  +" child elements: " + toString(values)
206  ,error::LUMIERA_ERROR_WRONG_TYPE);
207 
208  return GenNodeAccessor<TargetType<i>> (values.child(i));
209  }
210  };
211  };
212 
213 
214 
215 }} // namespace lib::meta
216 #endif /*LIB_META_TUPLE_RECORD_INIT_H*/
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
Typesafe union record.
Definition: variant.hpp:215
Helpers for working with lib::meta::Types (i.e.
Some basic facilities for manipulating type sequences.
Generic converter to somehow extract values from the "source" type to fill and initialise a tuple of ...
Implementation namespace for support and library code.
Metaprogramming with tuples-of-types and the std::tuple record.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Generic building block for tree shaped (meta)data structures.
pick the n-th element from a typelist
Helpers for type detection, type rewriting and metaprogramming.
filter away those types which don&#39;t fulfil a predicate metafunction
object-like record of data.
Definition: record.hpp:141
Metaprogramming: Helpers for manipulating lists-of-types.
generic data element node within a tree
Definition: gen-node.hpp:222