90 #include <type_traits> 108 using std::remove_reference;
109 using meta::NullType;
114 template<
typename X,
typename TYPES>
117 ,typename TYPES::List
121 template<
typename X,
typename TYPES>
128 template<
typename X,
typename TYPES>
135 template<
typename TYPES,
size_t len>
142 template<
typename X,
typename T,
typename TYPES>
163 template<
class TYPES,
template<
class>
class _P_>
166 static_assert(not
sizeof(TYPES),
"None of the possible Types fulfils the condition");
169 template<
class...TYPES,
template<
class>
class _P_>
174 template<
class T,
class TYPES,
template<
class>
class _P_>
176 : std::conditional_t<_P_<T>::value, Identity<T>, FirstMatchingType<TYPES, _P_>>
181 template<
typename RET>
188 virtual RET handle(VAL&) {
return RET(); };
193 template<
typename TYPES>
222 template<
typename TYPES>
230 template<
typename RET>
232 template<
typename RET>
240 :
public VisitorFunc<void>
247 :
public VisitorConstFunc<bool>
258 template<
template<
class>
class _P_>
269 void* ptr() {
return &content_; }
274 virtual void dispatch (
Visitor&) =0;
275 virtual bool dispatch (
Predicate&)
const =0;
276 virtual operator string()
const =0;
281 template<
typename TY>
285 static_assert (SIZ >=
sizeof(TY),
"Variant record: insufficient embedded Buffer size");
290 return *
reinterpret_cast<TY*
> (unConst(
this)->ptr());
300 new(Buffer::ptr()) TY(obj);
305 new(Buffer::ptr()) TY(move(robj));
310 new(Buffer::ptr()) TY(oBuff.
access());
315 new(Buffer::ptr()) TY(move (rBuff.access()));
319 operator= (
Buff const& buff)
325 operator= (
Buff&& rref)
327 *
this = move (rref.access());
331 operator= (TY
const& ob)
333 if (&ob != Buffer::ptr())
338 operator= (TY && rob)
340 if (&rob != Buffer::ptr())
341 this->access() = move(rob);
346 static string indicateTypeMismatch (
Buffer&);
352 Buff* buff =
dynamic_cast<Buff*
> (&b);
356 ,error::LERR_(WRONG_TYPE));
366 Dispatcher& typeDispatcher = visitor;
367 typeDispatcher.handle (this->access());
375 Dispatcher& typeDispatcher = visitor;
376 return typeDispatcher.handle (this->access());
380 operator string()
const;
383 enum{ BUFFSIZE =
sizeof(
Buffer) };
388 char storage_[BUFFSIZE];
399 return *
reinterpret_cast<Buffer*
> (&storage_);
404 return *
reinterpret_cast<const Buffer*
> (&storage_);
411 return Buff<X>::downcast(this->buffer());
419 Buff<X>* buff =
dynamic_cast<Buff<X>*
> (& this->buffer());
421 return & buff->access();
435 using DefaultType =
typename TYPES::List::Head;
437 new(storage_) Buff<DefaultType> (DefaultType());
447 new(storage_) Buff<StorageType> (forward<X>(x));
452 ref.buffer().copyInto (&storage_);
457 ref.buffer().copyInto (&storage_);
462 rref.buffer().moveInto (&storage_);
469 using RawType =
typename std::remove_reference<X>::type;
470 static_assert (meta::isInList<RawType, typename TYPES::List>(),
471 "Type error: the given variant could never hold the required type");
472 static_assert (std::is_copy_assignable<RawType>::value,
"target type does not support assignment");
474 buff<RawType>() = forward<X>(x);
481 ovar.buffer().copyInto (this->buffer());
486 operator= (
Variant const& ovar)
488 ovar.buffer().copyInto (this->buffer());
495 rvar.buffer().moveInto (this->buffer());
503 operator string()
const;
512 static_assert (meta::isInList<X, typename TYPES::List>(),
513 "Type error: the given variant could never hold the required type");
515 return buff<X>().access();
522 return unConst(
this)->template get<X>();
526 accept (Visitor& visitor)
528 buffer().dispatch (visitor);
532 accept (Predicate& visitor)
const 534 return buffer().dispatch (visitor);
543 template<
typename TYPES>
546 return "Variant|" + string(buffer());
549 template<
typename TYPES>
550 template<
typename TY>
553 return util::typedString (this->access());
564 template<
typename TYPES>
565 template<
typename TY>
570 return "Variant type mismatch: expected value of type «" 571 + lib::meta::typeStr<TY>()+
"», " 572 +
"however the given variant record is " 575 catch(...) {
return lib::meta::FAILURE_INDICATOR; }
A template metaprogramming technique for manipulating collections of types.
Helpers for working with lib::meta::Types (i.e.
Metaprogramming: simple helpers for working with lists-of-types.
Helper to pick the first type from a type sequence, which fulfils the predicate (meta function) given...
virtual ~Buffer()
this is an ABC with VTable
Implementation namespace for support and library code.
TY & access() const
< core operation: target is contained within the inline buffer
Derived specific exceptions within Lumiera's exception hierarchy.
virtual ~Predicate()
this is an interface
virtual ~Visitor()
this is an interface
concrete inner capsule specialised for a given type
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
how to treat one single type in visitation
Lumiera error handling (C++ interface).
to be implemented by the client for visitation
Inner capsule managing the contained object (interface)
Helper for building "virtual copy" operations.