161 #ifndef LIB_POLYMORPHIC_VALUE_H 162 #define LIB_POLYMORPHIC_VALUE_H 175 namespace polyvalue {
207 virtual void cloneInto (
void* targetBuffer)
const =0;
208 virtual void copyInto (IFA& targetBase)
const =0;
223 virtual void cloneInto (
void* targetBuffer)
const =0;
239 enum{ value = HasFunName_cloneInto<T>::value
254 && ! HasMember_copyInto<T>::value
263 template<
class API,
class YES =
void>
268 assignEmbedded(IMP& dest,IMP
const& src)
286 assignEmbedded(IMP&,IMP
const&)
288 throw error::Logic(
"attempt to overwrite unmodifiable value");
302 template <
class TY,
class YES =
void>
308 enum{ ADMIN_OVERHEAD = 2 *
sizeof(
void*) };
311 accessCopyHandlingInterface (TY& bufferContents)
314 return dynamic_cast<CopyAPI&
> (bufferContents);
331 using AdapterAttachment =
struct{ };
332 enum{ ADMIN_OVERHEAD = 1 *
sizeof(
void*) };
336 accessCopyHandlingInterface (IFA& bufferContents)
338 REQUIRE (
INSTANCEOF (CopyAPI, &bufferContents));
339 return static_cast<CopyAPI&
> (bufferContents);
381 siz = storage + _Traits::ADMIN_OVERHEAD
393 accessEmbedded()
const 395 return * std::launder (reinterpret_cast<IFA*> (&buf_));
401 accessEmbedded().~IFA();
421 cloneInto (
void* targetBuffer)
const 423 new(targetBuffer)
Adapter(*
this);
427 copyInto (IFA& targetBase)
const 431 _AssignmentPolicy::assignEmbedded(target,*
this);
436 template<
typename...ARGS>
438 : IMP(std::forward<ARGS>(args)...)
444 template<
typename IMP>
448 _CopyHandlingAdapter&
449 accessHandlingInterface ()
const 451 IFA& bufferContents = accessEmbedded();
452 return _Traits::accessCopyHandlingInterface (bufferContents);
459 template<
class IMP,
typename...ARGS>
462 static_assert (siz >=
sizeof(Adapter<IMP>),
"insufficient inline buffer size");
463 new(&buf_) Adapter<IMP> (std::forward<ARGS>(args)...);
475 template<
class IMP,
typename...ARGS>
488 return accessEmbedded();
491 operator Interface& ()
493 return accessEmbedded();
495 operator Interface
const& ()
const 497 return accessEmbedded();
502 return &( accessEmbedded() );
512 o.accessHandlingInterface().cloneInto (&buf_);
518 o.accessHandlingInterface().copyInto (this->accessEmbedded());
524 template<
class IMP,
typename...ARGS>
526 build (ARGS&&... args)
528 Adapter<IMP>* type_to_build_in_buffer(0);
529 return PolymorphicValue (type_to_build_in_buffer, std::forward<ARGS>(args)...);
538 return v1.accessEmbedded() == v2.accessEmbedded();
543 return not (v1 == v2);
Building block: the Interface to cause the invocation.
#define META_DETECT_MEMBER(_NAME_)
Detector for a nested member (field or function).
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
A variation for limited copy support.
helper to detect presence of a function to support clone operations
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
trait template to deal with different ways to support copy operations.
Implementation namespace for support and library code.
Derived specific exceptions within Lumiera's exception hierarchy.
Implementation Helper: add support for copy operations.
PolymorphicValue(IMP *, ARGS &&... args)
Template to build polymorphic value objects.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
helper to detect if the API supports only copy construction, but no assignment
Interface for active support of copy operations by the embedded client objects.
Lumiera error handling (C++ interface).
#define META_DETECT_FUNCTION_NAME(_FUN_NAME_)
Detector for a member function with the given name.
PolymorphicValue(TypeSelector< IMP >, ARGS &&... args)
Policy class for invoking the assignment operator.
Metaprogramming helpers to check for specific properties of a type in question.