WIP extended binding and invocation to support the convenience shortcuts

This commit is contained in:
Fischlurch 2009-08-02 20:55:43 +02:00
parent 4236d0649a
commit 327cbc822a
7 changed files with 418 additions and 58 deletions

View file

@ -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<TAR*> (this) -> bindArg (tuple::makeNullTuple() );
}
@ -80,6 +79,192 @@ namespace control {
, typename T1
> //_______________________________
struct AcceptArgs<TAR,BA,RET, Types<T1> > ///< Accept binding for 1 Argument
: BA
{
RET
operator() (T1 a1)
{
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
}
};
template< class TAR, class BA, class RET
, typename T1
, typename T2
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2> > ///< Accept binding for 2 Arguments
: BA
{
RET
operator() (T1 a1, T2 a2)
{
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2));
}
};
template< class TAR, class BA, class RET
, typename T1
, typename T2
, typename T3
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3> > ///< Accept binding for 3 Arguments
: BA
{
RET
operator() (T1 a1, T2 a2, T3 a3)
{
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3));
}
};
template< class TAR, class BA, class RET
, typename T1
, typename T2
, typename T3
, typename T4
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4> > ///< Accept binding for 4 Arguments
: BA
{
RET
operator() (T1 a1, T2 a2, T3 a3, T4 a4)
{
return static_cast<TAR*> (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<TAR,BA,RET, Types<T1,T2,T3,T4,T5> > ///< Accept binding for 5 Arguments
: BA
{
RET
operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
return static_cast<TAR*> (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<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6> > ///< Accept binding for 6 Arguments
: BA
{
RET
operator() (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
{
return static_cast<TAR*> (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<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7> > ///< 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<TAR*> (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<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7,T8> > ///< 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<TAR*> (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<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > ///< 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<TAR*> (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<TAR,BA,RET, Types<> > ///< Accept dummy binding (0 Arguments)
: BA
{
RET
bind ()
{
return static_cast<TAR*> (this) -> bindArg (tuple::makeNullTuple() );
}
};
template< class TAR, class BA, class RET
, typename T1
> //_______________________________
struct AcceptBind<TAR,BA,RET, Types<T1> > ///< Accept binding for 1 Argument
: BA
{
RET
@ -94,7 +279,7 @@ namespace control {
, typename T1
, typename T2
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2> > ///< Accept binding for 2 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2> > ///< Accept binding for 2 Arguments
: BA
{
RET
@ -110,7 +295,7 @@ namespace control {
, typename T2
, typename T3
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3> > ///< Accept binding for 3 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3> > ///< Accept binding for 3 Arguments
: BA
{
RET
@ -127,7 +312,7 @@ namespace control {
, typename T3
, typename T4
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4> > ///< Accept binding for 4 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3,T4> > ///< Accept binding for 4 Arguments
: BA
{
RET
@ -145,7 +330,7 @@ namespace control {
, typename T4
, typename T5
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4,T5> > ///< Accept binding for 5 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3,T4,T5> > ///< Accept binding for 5 Arguments
: BA
{
RET
@ -164,7 +349,7 @@ namespace control {
, typename T5
, typename T6
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6> > ///< Accept binding for 6 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6> > ///< Accept binding for 6 Arguments
: BA
{
RET
@ -184,7 +369,7 @@ namespace control {
, typename T6
, typename T7
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7> > ///< Accept binding for 7 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7> > ///< Accept binding for 7 Arguments
: BA
{
RET
@ -205,7 +390,7 @@ namespace control {
, typename T7
, typename T8
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7,T8> > ///< Accept binding for 8 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7,T8> > ///< Accept binding for 8 Arguments
: BA
{
RET
@ -227,7 +412,7 @@ namespace control {
, typename T8
, typename T9
> //________________________________
struct AcceptArgs<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > ///< Accept binding for 9 Arguments
struct AcceptBind<TAR,BA,RET, Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > ///< Accept binding for 9 Arguments
: BA
{
RET
@ -261,19 +446,30 @@ namespace control {
* @param BASE the base class for inheritance chaining
*/
template<typename SIG, class TAR, class BASE =bind_arg::Dummy>
class AcceptArgumentTuple
: public bind_arg::AcceptArgs<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
class AcceptArgumentBinding
: public bind_arg::AcceptBind<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
, typename bind_arg::_Type<SIG>::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<typename RET, typename SIG, class TAR, class BASE =bind_arg::Dummy>
class AcceptArgumentTupleRet
: public bind_arg::AcceptArgs<TAR,BASE, RET
class AcceptArgumentBindingRet
: public bind_arg::AcceptBind<TAR,BASE, RET
, typename bind_arg::_Type<SIG>::Args>
{
};
/** This variation of AcceptArgumentBindingRet mixes in a function call operator
* according to the specified signature SIG
*/
template<typename SIG, class TAR, class BASE =bind_arg::Dummy>
class AcceptArgumentTuple
: public bind_arg::AcceptArgs<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
, typename bind_arg::_Type<SIG>::Args>
{
};

View file

@ -103,10 +103,10 @@ namespace control {
*/
template<typename SIG, typename MEM>
class ArgumentHolder
: public AcceptArgumentTuple< SIG // to derive the desired bind(..) signature
, ArgumentHolder<SIG,MEM> // target class providing the implementation
, CmdClosure // base class to inherit from
>
: public AcceptArgumentBinding< SIG // to derive the desired bind(..) signature
, ArgumentHolder<SIG,MEM> // target class providing the implementation
, CmdClosure // base class to inherit from
>
{
/** copy construction allowed(but no assignment)*/
ArgumentHolder& operator= (ArgumentHolder const&);

View file

@ -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<TAR*> (this) -> bindArg (tuple::makeNullTuple());
return static_cast<TAR*> (this) -> bindArg (tuple::makeNullTuple());
}
template<typename T1>
void //________________________________
TAR& //________________________________
bind (T1 a1) ///< Accept binding with 1 Argument
{
static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
}
template< typename T1
, typename T2
>
void //________________________________
TAR& //________________________________
bind (T1 a1, T2 a2) ///< Accept binding for 2 Arguments
{
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8));
return static_cast<TAR*> (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<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8,a9));
return static_cast<TAR*> (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

View file

@ -87,9 +87,9 @@ namespace control {
template<typename SIG, typename MEM>
struct UndoDefinition
: AcceptArgumentTupleRet< Command&, SIG // Return type and Argument Signature of the \c bind(..) function
, UndoDefinition<SIG,MEM> // target type (this class) providing the implementation \c bindArg(Tuple<..>)
>
: AcceptArgumentBindingRet< Command&, SIG // Return type and Argument Signature of the \c bind(..) function
, UndoDefinition<SIG,MEM> // target type (this class) providing the implementation \c bindArg(Tuple<..>)
>
{
typedef CommandSignature<SIG,MEM> CmdType;
typedef typename CmdType::OperateSig CommandOperationSig;

View file

@ -0,0 +1,162 @@
/*
COMMAND-INVOCATION.hpp - shortcuts and helpers for calling Proc-Layer commands
Copyright (C) Lumiera.org
2009, Hermann Vosseler <Ichthyostega@web.de>
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 <tr1/memory>
#include <tr1/functional>
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<typename SIG>
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<typename SIG>
struct CommandInvoker
: AcceptArgumentTuple< typename _DefineBindFunc<SIG>::SIG_Bind
, CommandInvoker<SIG>
>
{
Command com_;
CommandInvoker (Command c)
: com_(c)
{ }
template<typename TYPES>
ExecResult
bindArg (Tuple<TYPES> 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<typename SIG>
inline
com::CommandInvoker<SIG>
invoke (SIG& operation_func)
{
Command command = Command::get ((FuncPtr)&operation_func);
ASSERT (command);
return com::CommandInvoker<SIG> (command);
}
inline
com::RuntimeCheckedCommandInvoker
invoke (Symbol cmdID)
{
Command command = Command::get (cmdID);
ASSERT (command);
return com::RuntimeCheckedCommandInvoker (command);
}
} // namespace control
#endif

View file

@ -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<typename TYPES>
void bindArg (Tuple<TYPES> const&);
Command& bindArg (Tuple<TYPES> 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());
}

View file

@ -57,22 +57,24 @@ namespace test {
struct Tup
{
typedef typename FunctionSignature< function<SIG> >::Args Args;
typedef typename FunctionSignature< function<SIG> >::Ret Ret;
typedef Tuple<Args> Ty;
};
template<typename SIG>
class TestClass
: public AcceptArgumentTuple< SIG // to derive the desired signature
, TestClass<SIG> // the target class providing the implementation
, typename Tup<SIG>::Ty // base class to inherit from
>
: public AcceptArgumentBinding< SIG // to derive the desired signature
, TestClass<SIG> // the target class providing the implementation
, typename Tup<SIG>::Ty // base class to inherit from
>
{
typedef typename Tup<SIG>::Ty ATuple;
typedef typename Tup<SIG>::Ret RetType;
public:
void
RetType
bindArg (ATuple const& tuple)
{
static_cast<ATuple&> (*this) = tuple;