81 #include <type_traits> 100 using std::remove_reference;
101 using meta::NullType;
106 template<
typename X,
typename TYPES>
109 ,typename TYPES::List
113 template<
typename X,
typename TYPES>
120 template<
typename X,
typename TYPES>
127 template<
typename TYPES,
size_t len>
134 template<
typename X,
typename T,
typename TYPES>
155 template<
class TYPES,
template<
class>
class _P_>
158 static_assert(not
sizeof(TYPES),
"None of the possible Types fulfils the condition");
161 template<
class...TYPES,
template<
class>
class _P_>
166 template<
class T,
class TYPES,
template<
class>
class _P_>
168 : std::conditional_t<_P_<T>::value, Identity<T>, FirstMatchingType<TYPES, _P_>>
173 template<
typename RET>
180 virtual RET handle(VAL&) {
return RET(); };
185 template<
typename TYPES>
214 template<
typename TYPES>
223 template<
typename RET>
225 template<
typename RET>
233 :
public VisitorFunc<void>
240 :
public VisitorConstFunc<bool>
247 :
public VisitorConstFunc<string>
258 template<
template<
class>
class _P_>
268 std::byte content_[SIZ];
270 void* ptr() {
return &content_; }
275 virtual void dispatch (
Visitor&) =0;
276 virtual bool dispatch (
Predicate&)
const =0;
277 virtual string dispatch (
Renderer&)
const =0;
278 virtual operator string()
const =0;
283 template<
typename TY>
287 static_assert (SIZ >=
sizeof(TY),
"Variant record: insufficient embedded Buffer size");
292 return * std::launder (reinterpret_cast<TY*> (unConst(
this)->ptr()));
302 new(Buffer::ptr()) TY(obj);
307 new(Buffer::ptr()) TY(move(robj));
312 new(Buffer::ptr()) TY(oBuff.
access());
317 new(Buffer::ptr()) TY(move (rBuff.access()));
321 operator= (
Buff const& buff)
327 operator= (
Buff&& rref)
329 *
this = move (rref.access());
333 operator= (TY
const& ob)
335 if (&ob != Buffer::ptr())
340 operator= (TY && rob)
342 if (&rob != Buffer::ptr())
343 this->access() = move(rob);
348 static string indicateTypeMismatch (
Buffer&);
354 Buff* buff =
dynamic_cast<Buff*
> (&b);
368 Dispatcher& typeDispatcher = visitor;
369 typeDispatcher.handle (this->access());
377 Dispatcher& typeDispatcher = visitor;
378 return typeDispatcher.handle (this->access());
386 Dispatcher& typeDispatcher = visitor;
387 return typeDispatcher.handle (this->access());
391 operator string()
const;
394 enum{ BUFFSIZE =
sizeof(
Buffer) };
399 char storage_[BUFFSIZE];
410 return * std::launder (reinterpret_cast<Buffer*> (&storage_));
415 return * std::launder (reinterpret_cast<const Buffer*> (&storage_));
422 return Buff<X>::downcast(this->buffer());
430 Buff<X>* buff =
dynamic_cast<Buff<X>*
> (& this->buffer());
432 return & buff->access();
446 using DefaultType =
typename TYPES::List::Head;
448 new(storage_) Buff<DefaultType> (DefaultType());
458 new(storage_) Buff<StorageType> (forward<X>(x));
463 ref.buffer().copyInto (&storage_);
468 ref.buffer().copyInto (&storage_);
473 rref.buffer().moveInto (&storage_);
480 using RawType =
typename std::remove_reference<X>::type;
481 static_assert (meta::isInList<RawType, typename TYPES::List>(),
482 "Type error: the given variant could never hold the required type");
483 static_assert (std::is_copy_assignable<RawType>::value,
"target type does not support assignment");
485 buff<RawType>() = forward<X>(x);
492 ovar.buffer().copyInto (this->buffer());
497 operator= (
Variant const& ovar)
499 ovar.buffer().copyInto (this->buffer());
506 rvar.buffer().moveInto (this->buffer());
514 operator string()
const;
523 static_assert (meta::isInList<X, typename TYPES::List>(),
524 "Type error: the given variant could never hold the required type");
526 return buff<X>().access();
533 return unConst(
this)->template get<X>();
537 accept (Visitor& visitor)
539 buffer().dispatch (visitor);
543 accept (Predicate& visitor)
const 545 return buffer().dispatch (visitor);
549 accept (Renderer& visitor)
const 551 return buffer().dispatch (visitor);
560 template<
typename TYPES>
563 return "Variant|" + string(buffer());
566 template<
typename TYPES>
567 template<
typename TY>
570 return util::typedString (this->access());
581 template<
typename TYPES>
582 template<
typename TY>
587 return "Variant type mismatch: expected value of type «" 588 + lib::meta::typeStr<TY>()+
"», " 589 +
"however the given variant record is " 592 catch(...) {
return lib::meta::FAILURE_INDICATOR; }
virtual ~Renderer()
this is an interface
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.