152 #ifndef LIB_POLYMORPHIC_VALUE_H 153 #define LIB_POLYMORPHIC_VALUE_H 166 namespace polyvalue {
198 virtual void cloneInto (
void* targetBuffer)
const =0;
199 virtual void copyInto (IFA& targetBase)
const =0;
214 virtual void cloneInto (
void* targetBuffer)
const =0;
230 enum{ value = HasFunName_cloneInto<T>::value
245 && ! HasMember_copyInto<T>::value
254 template<
class API,
class YES =
void>
259 assignEmbedded(IMP& dest,IMP
const& src)
277 assignEmbedded(IMP&,IMP
const&)
279 throw error::Logic(
"attempt to overwrite unmodifiable value");
293 template <
class TY,
class YES =
void>
299 enum{ ADMIN_OVERHEAD = 2 *
sizeof(
void*) };
302 accessCopyHandlingInterface (TY& bufferContents)
305 return dynamic_cast<CopyAPI&
> (bufferContents);
322 using AdapterAttachment =
struct{ };
323 enum{ ADMIN_OVERHEAD = 1 *
sizeof(
void*) };
327 accessCopyHandlingInterface (IFA& bufferContents)
329 REQUIRE (
INSTANCEOF (CopyAPI, &bufferContents));
330 return static_cast<CopyAPI&
> (bufferContents);
372 siz = storage + _Traits::ADMIN_OVERHEAD
384 accessEmbedded()
const 386 return * std::launder (reinterpret_cast<IFA*> (&buf_));
392 accessEmbedded().~IFA();
412 cloneInto (
void* targetBuffer)
const 414 new(targetBuffer)
Adapter(*
this);
418 copyInto (IFA& targetBase)
const 422 _AssignmentPolicy::assignEmbedded(target,*
this);
427 template<
typename...ARGS>
429 : IMP(std::forward<ARGS>(args)...)
435 template<
typename IMP>
439 _CopyHandlingAdapter&
440 accessHandlingInterface ()
const 442 IFA& bufferContents = accessEmbedded();
443 return _Traits::accessCopyHandlingInterface (bufferContents);
450 template<
class IMP,
typename...ARGS>
453 static_assert (siz >=
sizeof(Adapter<IMP>),
"insufficient inline buffer size");
454 new(&buf_) Adapter<IMP> (std::forward<ARGS>(args)...);
466 template<
class IMP,
typename...ARGS>
479 return accessEmbedded();
482 operator Interface& ()
484 return accessEmbedded();
486 operator Interface
const& ()
const 488 return accessEmbedded();
493 return &( accessEmbedded() );
503 o.accessHandlingInterface().cloneInto (&buf_);
509 o.accessHandlingInterface().copyInto (this->accessEmbedded());
515 template<
class IMP,
typename...ARGS>
517 build (ARGS&&... args)
519 Adapter<IMP>* type_to_build_in_buffer(0);
520 return PolymorphicValue (type_to_build_in_buffer, std::forward<ARGS>(args)...);
529 return v1.accessEmbedded() == v2.accessEmbedded();
534 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.