From 327cbc822a977ae42f93c45315b4fee86c431757 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 2 Aug 2009 20:55:43 +0200 Subject: [PATCH] WIP extended binding and invocation to support the convenience shortcuts --- src/proc/control/argument-tuple-accept.hpp | 230 ++++++++++++++++-- src/proc/control/command-argument-holder.hpp | 8 +- src/proc/control/command-binding.hpp | 42 ++-- src/proc/control/command-def.hpp | 6 +- src/proc/control/command-invocation.hpp | 162 ++++++++++++ src/proc/control/command.hpp | 16 +- .../control/argument-tuple-accept-test.cpp | 12 +- 7 files changed, 418 insertions(+), 58 deletions(-) create mode 100644 src/proc/control/command-invocation.hpp diff --git a/src/proc/control/argument-tuple-accept.hpp b/src/proc/control/argument-tuple-accept.hpp index b7a309525..4018da73a 100644 --- a/src/proc/control/argument-tuple-accept.hpp +++ b/src/proc/control/argument-tuple-accept.hpp @@ -22,7 +22,7 @@ /** @file argument-tuple-accept.hpp - ** The AcceptArgumentTuple template allows to mix in a \c bind(...) function. + ** The AcceptArgumentBinding template allows to mix in a \c bind(...) function. ** Thereby, the correct number and types of arguments is derived according to ** the function signature given as template parameter. This helper template is ** used for the ArgumentHolder and generally for binding the arguments when @@ -53,8 +53,7 @@ namespace control { using namespace lumiera::typelist; - /** @internal mix in a \c bind() function - */ + /** @internal mix in a function operator */ template< class TAR, class BA, class RET , typename TYPES > @@ -69,7 +68,7 @@ namespace control { : BA { RET - bind () + operator() () { return static_cast (this) -> bindArg (tuple::makeNullTuple() ); } @@ -80,6 +79,192 @@ namespace control { , typename T1 > //_______________________________ struct AcceptArgs > ///< Accept binding for 1 Argument + : BA + { + RET + operator() (T1 a1) + { + return static_cast (this) -> bindArg (tuple::make (a1)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 2 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 3 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + , typename T4 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 4 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3, T4 a4) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + , typename T4 + , typename T5 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 5 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + , typename T4 + , typename T5 + , typename T6 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 6 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + , typename T4 + , typename T5 + , typename T6 + , typename T7 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 7 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + , typename T4 + , typename T5 + , typename T6 + , typename T7 + , typename T8 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 8 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8)); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + , typename T2 + , typename T3 + , typename T4 + , typename T5 + , typename T6 + , typename T7 + , typename T8 + , typename T9 + > //________________________________ + struct AcceptArgs > ///< Accept binding for 9 Arguments + : BA + { + RET + operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9) + { + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8,a9)); + } + }; + + + + /** @internal mix in a \c bind() function + */ + template< class TAR, class BA, class RET + , typename TYPES + > + struct AcceptBind ; + + + /* specialisations for 0...9 Arguments.... */ + + template< class TAR, class BA, class RET + > //____________________________________ + struct AcceptBind > ///< Accept dummy binding (0 Arguments) + : BA + { + RET + bind () + { + return static_cast (this) -> bindArg (tuple::makeNullTuple() ); + } + }; + + + template< class TAR, class BA, class RET + , typename T1 + > //_______________________________ + struct AcceptBind > ///< Accept binding for 1 Argument : BA { RET @@ -94,7 +279,7 @@ namespace control { , typename T1 , typename T2 > //________________________________ - struct AcceptArgs > ///< Accept binding for 2 Arguments + struct AcceptBind > ///< Accept binding for 2 Arguments : BA { RET @@ -110,7 +295,7 @@ namespace control { , typename T2 , typename T3 > //________________________________ - struct AcceptArgs > ///< Accept binding for 3 Arguments + struct AcceptBind > ///< Accept binding for 3 Arguments : BA { RET @@ -127,7 +312,7 @@ namespace control { , typename T3 , typename T4 > //________________________________ - struct AcceptArgs > ///< Accept binding for 4 Arguments + struct AcceptBind > ///< Accept binding for 4 Arguments : BA { RET @@ -145,7 +330,7 @@ namespace control { , typename T4 , typename T5 > //________________________________ - struct AcceptArgs > ///< Accept binding for 5 Arguments + struct AcceptBind > ///< Accept binding for 5 Arguments : BA { RET @@ -164,7 +349,7 @@ namespace control { , typename T5 , typename T6 > //________________________________ - struct AcceptArgs > ///< Accept binding for 6 Arguments + struct AcceptBind > ///< Accept binding for 6 Arguments : BA { RET @@ -184,7 +369,7 @@ namespace control { , typename T6 , typename T7 > //________________________________ - struct AcceptArgs > ///< Accept binding for 7 Arguments + struct AcceptBind > ///< Accept binding for 7 Arguments : BA { RET @@ -205,7 +390,7 @@ namespace control { , typename T7 , typename T8 > //________________________________ - struct AcceptArgs > ///< Accept binding for 8 Arguments + struct AcceptBind > ///< Accept binding for 8 Arguments : BA { RET @@ -227,7 +412,7 @@ namespace control { , typename T8 , typename T9 > //________________________________ - struct AcceptArgs > ///< Accept binding for 9 Arguments + struct AcceptBind > ///< Accept binding for 9 Arguments : BA { RET @@ -261,19 +446,30 @@ namespace control { * @param BASE the base class for inheritance chaining */ template - class AcceptArgumentTuple - : public bind_arg::AcceptArgs::Ret + class AcceptArgumentBinding + : public bind_arg::AcceptBind::Ret , typename bind_arg::_Type::Args> { }; - /** Variation of AcceptArgumentTuple, allowing to control the return type + /** Variation of AcceptArgumentBinding, allowing to control the return type * of the generated \c bind(...) functions independently from SIG */ template - class AcceptArgumentTupleRet - : public bind_arg::AcceptArgs::Args> + { + }; + + + /** This variation of AcceptArgumentBindingRet mixes in a function call operator + * according to the specified signature SIG + */ + template + class AcceptArgumentTuple + : public bind_arg::AcceptArgs::Ret , typename bind_arg::_Type::Args> { }; diff --git a/src/proc/control/command-argument-holder.hpp b/src/proc/control/command-argument-holder.hpp index 50c784782..1e627c9ca 100644 --- a/src/proc/control/command-argument-holder.hpp +++ b/src/proc/control/command-argument-holder.hpp @@ -103,10 +103,10 @@ namespace control { */ template class ArgumentHolder - : public AcceptArgumentTuple< SIG // to derive the desired bind(..) signature - , ArgumentHolder // target class providing the implementation - , CmdClosure // base class to inherit from - > + : public AcceptArgumentBinding< SIG // to derive the desired bind(..) signature + , ArgumentHolder // target class providing the implementation + , CmdClosure // base class to inherit from + > { /** copy construction allowed(but no assignment)*/ ArgumentHolder& operator= (ArgumentHolder const&); diff --git a/src/proc/control/command-binding.hpp b/src/proc/control/command-binding.hpp index 79ae2f0c8..35b81b575 100644 --- a/src/proc/control/command-binding.hpp +++ b/src/proc/control/command-binding.hpp @@ -80,28 +80,28 @@ namespace com { ///< Proc-Layer command implementation details * if the number and type of arguments of the stored operation function * within the command matches the given argument pattern */ - void + TAR& bind () { - static_cast (this) -> bindArg (tuple::makeNullTuple()); + return static_cast (this) -> bindArg (tuple::makeNullTuple()); } template - void //________________________________ + TAR& //________________________________ bind (T1 a1) ///< Accept binding with 1 Argument { - static_cast (this) -> bindArg (tuple::make (a1)); + return static_cast (this) -> bindArg (tuple::make (a1)); } template< typename T1 , typename T2 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2) ///< Accept binding for 2 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2)); + return static_cast (this) -> bindArg (tuple::make (a1,a2)); } @@ -109,10 +109,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T2 , typename T3 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3) ///< Accept binding for 3 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3)); } @@ -121,10 +121,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T3 , typename T4 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3, T4 a4) ///< Accept binding for 4 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4)); } @@ -134,10 +134,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T4 , typename T5 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) ///< Accept binding for 5 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5)); } @@ -148,10 +148,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T5 , typename T6 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) ///< Accept binding for 6 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6)); } @@ -163,10 +163,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T6 , typename T7 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) ///< Accept binding for 7 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7)); } @@ -179,10 +179,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T7 , typename T8 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8) ///< Accept binding for 8 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8)); } @@ -196,10 +196,10 @@ namespace com { ///< Proc-Layer command implementation details , typename T8 , typename T9 > - void //________________________________ + TAR& //________________________________ bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9) ///< Accept binding for 9 Arguments { - static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8,a9)); + return static_cast (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8,a9)); } }; @@ -209,5 +209,5 @@ namespace com { ///< Proc-Layer command implementation details -}} // namespace control +}} // namespace control::com #endif diff --git a/src/proc/control/command-def.hpp b/src/proc/control/command-def.hpp index 15f7ae7ed..ad8a17152 100644 --- a/src/proc/control/command-def.hpp +++ b/src/proc/control/command-def.hpp @@ -87,9 +87,9 @@ namespace control { template struct UndoDefinition - : AcceptArgumentTupleRet< Command&, SIG // Return type and Argument Signature of the \c bind(..) function - , UndoDefinition // target type (this class) providing the implementation \c bindArg(Tuple<..>) - > + : AcceptArgumentBindingRet< Command&, SIG // Return type and Argument Signature of the \c bind(..) function + , UndoDefinition // target type (this class) providing the implementation \c bindArg(Tuple<..>) + > { typedef CommandSignature CmdType; typedef typename CmdType::OperateSig CommandOperationSig; diff --git a/src/proc/control/command-invocation.hpp b/src/proc/control/command-invocation.hpp new file mode 100644 index 000000000..f8ab945cb --- /dev/null +++ b/src/proc/control/command-invocation.hpp @@ -0,0 +1,162 @@ +/* + COMMAND-INVOCATION.hpp - shortcuts and helpers for calling Proc-Layer commands + + Copyright (C) Lumiera.org + 2009, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file command-invocation.hpp + ** Some additional helpers and convenience shortcuts to ease command invocation. + ** Especially, this header defines a set of free \c invoke(...) functions, + ** allowing to bind to specific arguments and then invoke through the default + ** HandlingPatern in a single call. + ** + ** @see Command + ** @see CommandDef + ** @see command-binding.hpp + ** @see command-use1-test.cpp + ** + */ + + + +#ifndef CONTROL_COMMAND_INVOCACTION_H +#define CONTROL_COMMAND_INVOCACTION_H + +//#include "pre.hpp" +//#include "include/symbol.hpp" +//#include "lib/meta/typelist.hpp" +//#include "lib/meta/tuple.hpp" +#include "proc/control/command.hpp" +#include "proc/control/handling-pattern.hpp" +#include "proc/control/argument-tuple-accept.hpp" + +//#include +#include + + + + +namespace control { + +// using lumiera::Symbol; +// using std::tr1::shared_ptr; + using namespace lumiera::typelist; + + + namespace com { // define transient invoker objects, to allow for arbitrary bindings + + template + struct _DefineBindFunc + { + typedef ExecResult SIG_Bind(int); + }; + + + /** @internal transient invoker object for invoking the command based + * on a function provided at compile time. Because of the + * known signature, we're able to expose a precisely typed + * function invocation operator. + */ + template + struct CommandInvoker + : AcceptArgumentTuple< typename _DefineBindFunc::SIG_Bind + , CommandInvoker + > + { + Command com_; + + CommandInvoker (Command c) + : com_(c) + { } + + + template + ExecResult + bindArg (Tuple const& args) + { + com_.bindArg(args); + ASSERT (com_.canExec()); + return com_(); + } + }; + + + + /** @internal transient invoker object, usable when the exact signature + * of the command's operation isn't known at compile time. + * In this case, we allow any invocation call to compile, + * but the command will reject unsuitable signatures + * at runtime, when fetching the operation functor. + */ + struct RuntimeCheckedCommandInvoker + { + Command com_; + + RuntimeCheckedCommandInvoker (Command c) + : com_(c) + { } + + + template< typename T1> + ExecResult //_________________________________ + operator() (T1 a1) ///< Invoke command with 1 Argument. + { + com_.bind(a1); + return com_(); + } + + + template< typename T1 + , typename T2 + , typename T3 + > + ExecResult //_________________________________ + operator() (T1 a1, T2 a2, T3 a3) ///< Invoke command with 3 Arguments + { + com_.bind(a1,a2,a3); + return com_(); + } + }; + } + + + + template + inline + com::CommandInvoker + invoke (SIG& operation_func) + { + Command command = Command::get ((FuncPtr)&operation_func); + ASSERT (command); + return com::CommandInvoker (command); + } + + + inline + com::RuntimeCheckedCommandInvoker + invoke (Symbol cmdID) + { + Command command = Command::get (cmdID); + ASSERT (command); + return com::RuntimeCheckedCommandInvoker (command); + } + +} // namespace control +#endif diff --git a/src/proc/control/command.hpp b/src/proc/control/command.hpp index bf12734e2..a4674279f 100644 --- a/src/proc/control/command.hpp +++ b/src/proc/control/command.hpp @@ -88,18 +88,18 @@ namespace control { Command() { } ///< undefined command ~Command(); - void operator() () ; - void undo () ; + ExecResult operator() () ; + ExecResult undo () ; /** core operation: invoke the command * @param execPattern describes the individual steps * necessary to get this command invoked properly */ - void exec (HandlingPattern const& execPattern); - void exec (HandlingPattern::ID); + ExecResult exec (HandlingPattern const& execPattern); + ExecResult exec (HandlingPattern::ID); - void execSync (); + ExecResult execSync (); /** @return ID of the execution pattern used by operator() */ HandlingPattern::ID getDefaultHandlingPattern() const; @@ -115,7 +115,7 @@ namespace control { Command& activate (CommandImpl&); template - void bindArg (Tuple const&); + Command& bindArg (Tuple const&); /* === diagnostics === */ @@ -142,10 +142,10 @@ namespace control { ////////////////TODO currently just fleshing out the API.... - inline void + inline ExecResult Command::operator() () { - exec (getDefaultHandlingPattern()); + return exec (getDefaultHandlingPattern()); } diff --git a/tests/components/proc/control/argument-tuple-accept-test.cpp b/tests/components/proc/control/argument-tuple-accept-test.cpp index a1a939fee..e6ebb7bd3 100644 --- a/tests/components/proc/control/argument-tuple-accept-test.cpp +++ b/tests/components/proc/control/argument-tuple-accept-test.cpp @@ -57,22 +57,24 @@ namespace test { struct Tup { typedef typename FunctionSignature< function >::Args Args; + typedef typename FunctionSignature< function >::Ret Ret; typedef Tuple Ty; }; template class TestClass - : public AcceptArgumentTuple< SIG // to derive the desired signature - , TestClass // the target class providing the implementation - , typename Tup::Ty // base class to inherit from - > + : public AcceptArgumentBinding< SIG // to derive the desired signature + , TestClass // the target class providing the implementation + , typename Tup::Ty // base class to inherit from + > { typedef typename Tup::Ty ATuple; + typedef typename Tup::Ret RetType; public: - void + RetType bindArg (ATuple const& tuple) { static_cast (*this) = tuple;