/* ARGUMENT-TUPLE-ACCEPT.hpp - helper template providing a bind(...) member function 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 argument-tuple-accept.hpp ** The AcceptArgumentTuple 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 ** defining Proc-Layer commands. ** ** @see CommandDef ** @see ArgumentHolder ** @see argument-tuple-accept-test.cpp ** */ #ifndef CONTROL_ARGUMENT_TUPLE_ACCEPT_H #define CONTROL_ARGUMENT_TUPLE_ACCEPT_H #include "lib/meta/typelist.hpp" #include "lib/meta/function.hpp" #include "lib/meta/tuple.hpp" namespace control { namespace bind_arg { // internals.... using namespace lumiera::typelist; /** @internal mix in a \c bind() function */ template< class TAR, class BA, class RET , typename TYPES > struct AcceptArgs ; /* specialisations for 0...9 Arguments.... */ template< class TAR, class BA, class RET > //____________________________________ struct AcceptArgs > ///< 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 AcceptArgs > ///< Accept binding for 1 Argument : BA { RET bind (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 bind (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 bind (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 bind (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 bind (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 bind (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 bind (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 bind (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 bind (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)); } }; template struct _Type { typedef typename FunctionSignature< function >::Args Args; typedef typename FunctionSignature< function >::Ret Ret; typedef Tuple ArgTuple; }; struct Dummy {}; } // (END) impl details /** 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 >) * @param BASE the base class for inheritance chaining */ template class AcceptArgumentTuple : public bind_arg::AcceptArgs::Ret , typename bind_arg::_Type::Args> { }; /** Variation of AcceptArgumentTuple, allowing to control the return type * of the generated \c bind(...) functions independently from SIG */ template class AcceptArgumentTupleRet : public bind_arg::AcceptArgs::Args> { }; } // namespace control #endif