Library: allow for subclassing PolymorphicValue
Up to now, PolymorphicValue was always used as-is, packaged into a typedef. Now we consider using it as building block within an adapter for visitor-like tokens. Which requires to pass-down the ctor call directly from the subclass, at least if we want to emplace the resulting entity directly into a stdlib container. As an asside, PolymorphicValue also used explicit specialisations for N-arguments, which meanwhile can be replaced by variadic templates
This commit is contained in:
parent
ec9b2388da
commit
500af8aa34
1 changed files with 35 additions and 67 deletions
|
|
@ -389,36 +389,6 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
template<class IMP>
|
||||
PolymorphicValue (IMP*)
|
||||
{
|
||||
static_assert (siz >= sizeof(IMP), "insufficient inline buffer size");
|
||||
|
||||
new(&buf_) IMP();
|
||||
}
|
||||
|
||||
template<class IMP, typename A1>
|
||||
PolymorphicValue (IMP*, A1 a1)
|
||||
{
|
||||
REQUIRE (siz >= sizeof(IMP));
|
||||
new(&buf_) IMP (a1);
|
||||
}
|
||||
|
||||
template<class IMP, typename A1, typename A2>
|
||||
PolymorphicValue (IMP*, A1 a1, A2 a2)
|
||||
{
|
||||
REQUIRE (siz >= sizeof(IMP));
|
||||
new(&buf_) IMP (a1,a2);
|
||||
}
|
||||
|
||||
template<class IMP, typename A1, typename A2, typename A3>
|
||||
PolymorphicValue (IMP*, A1 a1, A2 a2, A3 a3)
|
||||
{
|
||||
REQUIRE (siz >= sizeof(IMP));
|
||||
new(&buf_) IMP (a1,a2,a3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation Helper: add support for copy operations.
|
||||
* Actually instances of this Adapter template are placed
|
||||
|
|
@ -450,20 +420,17 @@ namespace lib {
|
|||
|
||||
public: /* == forwarding ctor to implementation type == */
|
||||
|
||||
Adapter() : IMP() { }
|
||||
|
||||
template<typename A1>
|
||||
Adapter (A1 a1) : IMP(a1) { }
|
||||
|
||||
template<typename A1, typename A2>
|
||||
Adapter (A1 a1, A2 a2) : IMP(a1,a2) { }
|
||||
|
||||
template<typename A1, typename A2, typename A3>
|
||||
Adapter (A1 a1, A2 a2, A3 a3) : IMP(a1,a2,a3) { }
|
||||
template<typename...ARGS>
|
||||
Adapter (ARGS&&... args)
|
||||
: IMP(std::forward<ARGS>(args)...)
|
||||
{ }
|
||||
|
||||
/* using default copy and assignment */
|
||||
};
|
||||
|
||||
template<typename IMP>
|
||||
using TypeSelector = Adapter<IMP>*;
|
||||
|
||||
|
||||
_CopyHandlingAdapter&
|
||||
accessHandlingInterface () const
|
||||
|
|
@ -472,6 +439,31 @@ namespace lib {
|
|||
return _Traits::accessCopyHandlingInterface (bufferContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal this is the actual working ctor, which must care to decorate
|
||||
* the desired impl type with an additional adapter to support copy operations.
|
||||
*/
|
||||
template<class IMP, typename...ARGS>
|
||||
PolymorphicValue (TypeSelector<IMP>, ARGS&&... args)
|
||||
{
|
||||
static_assert (siz >= sizeof(Adapter<IMP>), "insufficient inline buffer size");
|
||||
new(&buf_) Adapter<IMP> (std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @internal ctor for subclasses and builder functions.
|
||||
* The constructor requires an additional type-selector argument.
|
||||
* On invocation, the desired subclass/implementation object is immediately
|
||||
* planted into the embedded buffer, passing through the given ctor arguments.
|
||||
* @see [factory functions for public use](\ref PolymorphicValue::build)
|
||||
*/
|
||||
template<class IMP, typename...ARGS>
|
||||
PolymorphicValue (IMP*, ARGS&&... args)
|
||||
: PolymorphicValue (TypeSelector<IMP>(), std::forward<ARGS>(args)...)
|
||||
{ }
|
||||
|
||||
|
||||
public: /* === PolymorphicValue public API === */
|
||||
|
||||
|
|
@ -510,36 +502,12 @@ namespace lib {
|
|||
|
||||
/* === static factory functions === */
|
||||
|
||||
template<class IMP>
|
||||
template<class IMP, typename...ARGS>
|
||||
static PolymorphicValue
|
||||
build ()
|
||||
build (ARGS&&... args)
|
||||
{
|
||||
Adapter<IMP>* type_to_build_in_buffer(0);
|
||||
return PolymorphicValue (type_to_build_in_buffer);
|
||||
}
|
||||
|
||||
template<class IMP, typename A1>
|
||||
static PolymorphicValue
|
||||
build (A1 a1)
|
||||
{
|
||||
Adapter<IMP>* type_to_build_in_buffer(0);
|
||||
return PolymorphicValue (type_to_build_in_buffer, a1);
|
||||
}
|
||||
|
||||
template<class IMP, typename A1, typename A2>
|
||||
static PolymorphicValue
|
||||
build (A1 a1, A2 a2)
|
||||
{
|
||||
Adapter<IMP>* type_to_build_in_buffer(0);
|
||||
return PolymorphicValue (type_to_build_in_buffer, a1,a2);
|
||||
}
|
||||
|
||||
template<class IMP, typename A1, typename A2, typename A3>
|
||||
static PolymorphicValue
|
||||
build (A1 a1, A2 a2, A3 a3)
|
||||
{
|
||||
Adapter<IMP>* type_to_build_in_buffer(0);
|
||||
return PolymorphicValue (type_to_build_in_buffer, a1,a2,a3);
|
||||
return PolymorphicValue (type_to_build_in_buffer, std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue