From efd6e99c990047f16cf169556c729681c3c9dd3f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 4 Aug 2009 01:30:50 +0200 Subject: [PATCH] first shot at solving the problem how to bind later on --- src/proc/control/argument-tuple-accept.hpp | 78 ++++++++++++++++++++-- 1 file changed, 71 insertions(+), 7 deletions(-) diff --git a/src/proc/control/argument-tuple-accept.hpp b/src/proc/control/argument-tuple-accept.hpp index 4018da73a..80cc94f9b 100644 --- a/src/proc/control/argument-tuple-accept.hpp +++ b/src/proc/control/argument-tuple-accept.hpp @@ -430,16 +430,40 @@ namespace control { typedef typename FunctionSignature< function >::Args Args; typedef typename FunctionSignature< function >::Ret Ret; typedef Tuple ArgTuple; + typedef SIG Sig; + }; + + template + struct _Type > + { + typedef TYPES Args; + typedef void Ret; + typedef Tuple ArgTuple; + typedef typename FunctionTypedef::Sig Sig; }; struct Dummy {}; - } // (END) impl details + } // (END) impl details (bind_arg) + /** Helper Template for building a Functor or function-like class: + * Mix in a function call operator, which mimics the specified signature SIG . + * This template is to be used as a base class to inherit the target type TAR from; + * this target type is assumed to provide a function \bindArg(Tuple) -- + * where \c TYPES... is the sequence of types found in the provided Signature SIG. + */ + template + class AcceptArgumentTuple + : public bind_arg::AcceptArgs::Ret + , typename bind_arg::_Type::Args> + { + }; + + /** Helper Template for Proc-Layer control::Command : mix in a \c bind(...) function * @param SIG function signature to mimic (regarding the arguments and return type) * @param TAR the target class providing a function \c bindArg(Tuple >) @@ -464,17 +488,57 @@ namespace control { }; - /** This variation of AcceptArgumentBindingRet mixes in a function call operator - * according to the specified signature SIG + + /** + * Adapter interface for invoking an argument binding (e.g. as defined through + * AcceptArgumentBinding) \em without the need to disclose the concrete type + * actually accepting the bind call. This is an application of the "type erasure" + * pattern; in order to use it + * - the concrete type accepting the \bind(..) call need to have a vtable, + * so it can be re-discovered by dynamic_cast + * - moreover, the concrete type must inherit from + * - at the call site, only a reference to the adapter interface is exposed. */ - template - class AcceptArgumentTuple - : public bind_arg::AcceptArgs::Ret - , typename bind_arg::_Type::Args> + class ArgumentReceiver; + + template + class TypedArgumentReceiver; + + + class ArgumentReceiver { + public: + virtual ~ArgumentReceiver() {} + + template + void + bindArg (TUP const& args) + { + typedef typename bind_arg::_Type::Sig Sig; + typedef TypedArgumentReceiver Receiver; + + Receiver* dest = dynamic_cast (this); + if (!dest) + throw lumiera::error::Invalid("Wrong type or number of arguments"); + + dest->bindArg(args); + } }; + template + class TypedArgumentReceiver + : public ArgumentReceiver + { + typedef typename bind_arg::_Type::Args ArgTypes; + + virtual void bindArg (lumiera::typelist::Tuple const&) =0; + }; + + + + + } // namespace control #endif