From f0de986399552f70302d4dab88941684ca082ae4 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 2 Oct 2016 22:15:55 +0200 Subject: [PATCH] Library: allow to immediately emplace a subclass type into InPlaceBuffer Up to now, InPlaceBuffer used to default construct an instance of the Interface class, and then you'd need to invoke the `create()` function to actually create the desired subclass. This is not only inefficient, but rules out the use of abstract interfaces / base classes. Unfortunately, there is no way in C++ to specify an explicit template argument list on ctor calls, so we resort to the trick of passing an additional dummy marker argument --- src/lib/opaque-holder.hpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lib/opaque-holder.hpp b/src/lib/opaque-holder.hpp index 799703ce7..41ebe662d 100644 --- a/src/lib/opaque-holder.hpp +++ b/src/lib/opaque-holder.hpp @@ -616,16 +616,30 @@ namespace lib { public: - InPlaceBuffer () - { - placeDefault(); - } - ~InPlaceBuffer () { destroy(); } + InPlaceBuffer () + { + placeDefault(); + } + + /** immediately emplace an embedded subclass type */ + template + InPlaceBuffer (TY*, ARGS&& ...args) + { + new(&buf_) TY (std::forward (args)...); + } + + /** helper to mark the subclass type to create. + * @remarks we can not specify explicit template arguments on ctor calls, + * so the only way is to use a dummy marker argument to pass the type. + * Use as `InPlaceBuffer(embedType, arg1, arg2, arg3)` */ + template + static auto embedType() { return (SUB*) nullptr; } + /** Abbreviation for placement new */ template