diff --git a/src/lib/polymorphic-value.hpp b/src/lib/polymorphic-value.hpp index d6c3c713c..dd4254c40 100644 --- a/src/lib/polymorphic-value.hpp +++ b/src/lib/polymorphic-value.hpp @@ -389,36 +389,6 @@ namespace lib { } - template - PolymorphicValue (IMP*) - { - static_assert (siz >= sizeof(IMP), "insufficient inline buffer size"); - - new(&buf_) IMP(); - } - - template - PolymorphicValue (IMP*, A1 a1) - { - REQUIRE (siz >= sizeof(IMP)); - new(&buf_) IMP (a1); - } - - template - PolymorphicValue (IMP*, A1 a1, A2 a2) - { - REQUIRE (siz >= sizeof(IMP)); - new(&buf_) IMP (a1,a2); - } - - template - 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 - Adapter (A1 a1) : IMP(a1) { } - - template - Adapter (A1 a1, A2 a2) : IMP(a1,a2) { } - - template - Adapter (A1 a1, A2 a2, A3 a3) : IMP(a1,a2,a3) { } + template + Adapter (ARGS&&... args) + : IMP(std::forward(args)...) + { } /* using default copy and assignment */ }; + template + using TypeSelector = Adapter*; + _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 + PolymorphicValue (TypeSelector, ARGS&&... args) + { + static_assert (siz >= sizeof(Adapter), "insufficient inline buffer size"); + new(&buf_) Adapter (std::forward(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 + PolymorphicValue (IMP*, ARGS&&... args) + : PolymorphicValue (TypeSelector(), std::forward(args)...) + { } + public: /* === PolymorphicValue public API === */ @@ -510,36 +502,12 @@ namespace lib { /* === static factory functions === */ - template + template static PolymorphicValue - build () + build (ARGS&&... args) { Adapter* type_to_build_in_buffer(0); - return PolymorphicValue (type_to_build_in_buffer); - } - - template - static PolymorphicValue - build (A1 a1) - { - Adapter* type_to_build_in_buffer(0); - return PolymorphicValue (type_to_build_in_buffer, a1); - } - - template - static PolymorphicValue - build (A1 a1, A2 a2) - { - Adapter* type_to_build_in_buffer(0); - return PolymorphicValue (type_to_build_in_buffer, a1,a2); - } - - template - static PolymorphicValue - build (A1 a1, A2 a2, A3 a3) - { - Adapter* 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)...); }