Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
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
56#include "lib/diff/gen-node.hpp"
57#include "lib/meta/trait.hpp"
58
59
60// GCC > 13 warns at class definition when a new overload shadows an inherited virtual function.
61// While theoretically correct, in practice any call will be dispatched through the base interface,
62// which in turn is also generated by metaprogramming from a type list.
63// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
64_Pragma("GCC diagnostic push") \
65_Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"")
66
67
68namespace lib {
69namespace meta {
70 namespace error = lumiera::error;
71
72 namespace { // implementation details...
73
74 using lib::Variant;
75 using lib::diff::Rec;
78
79
81 using DataCapPredicate = Variant<DataValues>::Predicate;
82
83
97 template<typename TAR>
98 struct GenNodeAccessor
100 {
101
102 template<typename TY>
103 struct allow_Conversion
104 : __and_<is_constructible<TAR, TY const&>
105 ,__not_<is_narrowingInit<typename Strip<TY>::TypePlain
106 ,typename Strip<TAR>::TypePlain>>
107 >
108 { };
109
110 using SupportedSourceTypes = Filter<DataValues::List, allow_Conversion>::List;
111
112
113
114 struct ConverterBase
115 : DataCapPredicate
116 {
117 char buffer[sizeof(TAR)];
118 };
119
120 template<typename TY, class BA>
121 class Converter
122 : public BA
123 {
124 virtual bool
125 handle(TY const& srcElm)
126 {
127 new(&(BA::buffer)) TAR{srcElm};
128 return true;
129 };
130 };
131
132
133 using ConversionBuffer = InstantiateChained< SupportedSourceTypes // for each of those types...
134 , Converter // instantiate the Converter template
135 , ConverterBase // and use this as common base class.
136 >; // RESULT: for each type we get a handle(TY)
137
138 ConversionBuffer converter_;
139
140 TAR&
141 accessTargetElement()
142 {
143 return *reinterpret_cast<TAR*> (&converter_.buffer);
144 }
145
146
147 public:
148 GenNodeAccessor (GenNode const& node)
149 : converter_()
150 {
151 if (not node.data.accept (converter_))
152 throw error::Invalid ("Unable to build «" + util::typeStr<TAR>()
153 +"» element from " + string(node)
154 ,error::LUMIERA_ERROR_WRONG_TYPE);
155 }
156
158 ~GenNodeAccessor()
159 {
160 accessTargetElement().~TAR();
161 }
162
163
164 operator TAR ()
165 {
166 return accessTargetElement();
167 }
168 };
169
170 }//(End)implementation details
171
172
173
174
192 template<typename...TYPES>
193 struct ElementExtractor<lib::diff::Rec, std::tuple<TYPES...>>
194 {
195 template<size_t i>
196 using TargetType = Pick<Types<TYPES...>, i>::Type;
197
198
199 template<size_t i>
200 struct Access
201 {
202 Rec const& values;
203
204 operator TargetType<i> ()
205 {
206 using util::toString;
207
208 if (values.childSize() <= i)
209 throw error::Logic ("Attempt to init the " + toString(sizeof...(TYPES))
210 +" element " + util::typeStr<std::tuple<TYPES...>>()
211 +" from an Rec<GenNode> with only " + toString(values.childSize())
212 +" child elements: " + toString(values)
213 ,error::LUMIERA_ERROR_WRONG_TYPE);
214
215 return GenNodeAccessor<TargetType<i>> (values.child(i));
216 }
217 };
218 };
219
220
221
222}} // namespace lib::meta
223#endif /*LIB_META_TUPLE_RECORD_INIT_H*/
Typesafe union record.
Definition variant.hpp:216
object-like record of data.
Definition record.hpp:142
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
Generic building block for tree shaped (meta)data structures.
Helpers for working with lib::meta::Types (i.e.
meta::Types< int,int64_t,short,char,bool,double,string,time::Time,time::Offset,time::Duration,time::TimeSpan,hash::LuidH,RecRef,Rec > DataValues
Definition gen-node.hpp:150
Implementation namespace for support and library code.
LumieraError< LERR_(LOGIC)> Logic
Definition error.hpp:207
LumieraError< LERR_(INVALID)> Invalid
Definition error.hpp:211
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
#define Type(_EXPR_)
generic data element node within a tree
Definition gen-node.hpp:224
Helpers for type detection, type rewriting and metaprogramming.
Metaprogramming with tuples-of-types and the std::tuple record.
_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"") namespace lib
Metaprogramming: Helpers for manipulating lists-of-types.
Some basic facilities for manipulating type sequences.