90 #include <type_traits> 109 using std::remove_reference;
110 using meta::NullType;
115 template<
typename X,
typename TYPES>
118 ,typename TYPES::List
122 template<
typename X,
typename TYPES>
129 template<
typename X,
typename TYPES>
136 template<
typename TYPES,
size_t len>
143 template<
typename X,
typename T,
typename TYPES>
164 template<
class TYPES,
template<
class>
class _P_>
167 static_assert(not
sizeof(TYPES),
"None of the possible Types fulfils the condition");
170 template<
class...TYPES,
template<
class>
class _P_>
175 template<
class T,
class TYPES,
template<
class>
class _P_>
177 : std::conditional_t<_P_<T>::value, Identity<T>, FirstMatchingType<TYPES, _P_>>
182 template<
typename RET>
189 virtual RET handle(VAL&) {
return RET(); };
194 template<
typename TYPES>
223 template<
typename TYPES>
232 template<
typename RET>
234 template<
typename RET>
242 :
public VisitorFunc<void>
249 :
public VisitorConstFunc<bool>
256 :
public VisitorConstFunc<string>
267 template<
template<
class>
class _P_>
277 std::byte content_[SIZ];
279 void* ptr() {
return &content_; }
284 virtual void dispatch (
Visitor&) =0;
285 virtual bool dispatch (
Predicate&)
const =0;
286 virtual string dispatch (
Renderer&)
const =0;
287 virtual operator string()
const =0;
292 template<
typename TY>
296 static_assert (SIZ >=
sizeof(TY),
"Variant record: insufficient embedded Buffer size");
301 return * std::launder (reinterpret_cast<TY*> (unConst(
this)->ptr()));
311 new(Buffer::ptr()) TY(obj);
316 new(Buffer::ptr()) TY(move(robj));
321 new(Buffer::ptr()) TY(oBuff.
access());
326 new(Buffer::ptr()) TY(move (rBuff.access()));
330 operator= (
Buff const& buff)
336 operator= (
Buff&& rref)
338 *
this = move (rref.access());
342 operator= (TY
const& ob)
344 if (&ob != Buffer::ptr())
349 operator= (TY && rob)
351 if (&rob != Buffer::ptr())
352 this->access() = move(rob);
357 static string indicateTypeMismatch (
Buffer&);
363 Buff* buff =
dynamic_cast<Buff*
> (&b);
377 Dispatcher& typeDispatcher = visitor;
378 typeDispatcher.handle (this->access());
386 Dispatcher& typeDispatcher = visitor;
387 return typeDispatcher.handle (this->access());
395 Dispatcher& typeDispatcher = visitor;
396 return typeDispatcher.handle (this->access());
400 operator string()
const;
403 enum{ BUFFSIZE =
sizeof(
Buffer) };
408 char storage_[BUFFSIZE];
419 return * std::launder (reinterpret_cast<Buffer*> (&storage_));
424 return * std::launder (reinterpret_cast<const Buffer*> (&storage_));
431 return Buff<X>::downcast(this->buffer());
439 Buff<X>* buff =
dynamic_cast<Buff<X>*
> (& this->buffer());
441 return & buff->access();
455 using DefaultType =
typename TYPES::List::Head;
457 new(storage_) Buff<DefaultType> (DefaultType());
467 new(storage_) Buff<StorageType> (forward<X>(x));
472 ref.buffer().copyInto (&storage_);
477 ref.buffer().copyInto (&storage_);
482 rref.buffer().moveInto (&storage_);
489 using RawType =
typename std::remove_reference<X>::type;
490 static_assert (meta::isInList<RawType, typename TYPES::List>(),
491 "Type error: the given variant could never hold the required type");
492 static_assert (std::is_copy_assignable<RawType>::value,
"target type does not support assignment");
494 buff<RawType>() = forward<X>(x);
501 ovar.buffer().copyInto (this->buffer());
506 operator= (
Variant const& ovar)
508 ovar.buffer().copyInto (this->buffer());
515 rvar.buffer().moveInto (this->buffer());
523 operator string()
const;
532 static_assert (meta::isInList<X, typename TYPES::List>(),
533 "Type error: the given variant could never hold the required type");
535 return buff<X>().access();
542 return unConst(
this)->template get<X>();
546 accept (Visitor& visitor)
548 buffer().dispatch (visitor);
552 accept (Predicate& visitor)
const 554 return buffer().dispatch (visitor);
558 accept (Renderer& visitor)
const 560 return buffer().dispatch (visitor);
569 template<
typename TYPES>
572 return "Variant|" + string(buffer());
575 template<
typename TYPES>
576 template<
typename TY>
579 return util::typedString (this->access());
590 template<
typename TYPES>
591 template<
typename TY>
596 return "Variant type mismatch: expected value of type «" 597 + lib::meta::typeStr<TY>()+
"», " 598 +
"however the given variant record is " 601 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.