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) 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 
58 #ifndef LIB_META_TUPLE_RECORD_INIT_H
59 #define LIB_META_TUPLE_RECORD_INIT_H
60 
64 #include "lib/meta/generator.hpp"
65 #include "lib/diff/gen-node.hpp"
66 #include "lib/meta/trait.hpp"
67 
68 
69 
70 namespace lib {
71 namespace meta {
72  namespace error = lumiera::error;
73 
74  namespace { // implementation details...
75 
76  using lib::Variant;
77  using lib::diff::Rec;
78  using lib::diff::GenNode;
80 
81 
84 
85 
99  template<typename TAR>
102  {
103 
104  template<typename TY>
106  : __and_<is_constructible<TAR, TY const&>
107  ,__not_<is_narrowingInit<typename Strip<TY>::TypePlain
108  ,typename Strip<TAR>::TypePlain>>
109  >
110  { };
111 
112  using SupportedSourceTypes = typename Filter<DataValues::List, allow_Conversion>::List;
113 
114 
115 
118  {
119  char buffer[sizeof(TAR)];
120  };
121 
122  template<typename TY, class BA>
123  class Converter
124  : public BA
125  {
126  virtual bool
127  handle(TY const& srcElm)
128  {
129  new(&(BA::buffer)) TAR{srcElm};
130  return true;
131  };
132  };
133 
134 
135  using ConversionBuffer = InstantiateChained< SupportedSourceTypes // for each of those types...
136  , Converter // instantiate the Converter template
137  , ConverterBase // and use this as common base class.
138  >; // RESULT: for each type we get a handle(TY)
139 
140  ConversionBuffer converter_;
141 
142  TAR&
143  accessTargetElement()
144  {
145  return *reinterpret_cast<TAR*> (&converter_.buffer);
146  }
147 
148 
149  public:
150  GenNodeAccessor (GenNode const& node)
151  : converter_()
152  {
153  if (not node.data.accept (converter_))
154  throw error::Invalid ("Unable to build «" + util::typeStr<TAR>()
155  +"» element from " + string(node)
156  ,error::LUMIERA_ERROR_WRONG_TYPE);
157  }
158 
161  {
162  accessTargetElement().~TAR();
163  }
164 
165 
166  operator TAR ()
167  {
168  return accessTargetElement();
169  }
170  };
171 
172  }//(End)implementation details
173 
174 
175 
176 
194  template<typename...TYPES>
195  struct ElementExtractor<lib::diff::Rec, std::tuple<TYPES...>>
196  {
197  template<size_t i>
198  using TargetType = typename Pick<Types<TYPES...>, i>::Type;
199 
200 
201  template<size_t i>
202  struct Access
203  {
204  Rec const& values;
205 
206  operator TargetType<i> ()
207  {
208  using util::toString;
209 
210  if (values.childSize() <= i)
211  throw error::Logic ("Attempt to init the " + toString(sizeof...(TYPES))
212  +" element " + util::typeStr<std::tuple<TYPES...>>()
213  +" from an Rec<GenNode> with only " + toString(values.childSize())
214  +" child elements: " + toString(values)
215  ,error::LUMIERA_ERROR_WRONG_TYPE);
216 
217  return GenNodeAccessor<TargetType<i>> (values.child(i));
218  }
219  };
220  };
221 
222 
223 
224 }} // namespace lib::meta
225 #endif /*LIB_META_TUPLE_RECORD_INIT_H*/
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
Typesafe union record.
Definition: variant.hpp:224
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:199
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:150
Metaprogramming: Helpers for manipulating lists-of-types.
generic data element node within a tree
Definition: gen-node.hpp:231