/* COMMAND-SIGNATURE.hpp - deriving suitable command function signatures 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-signature.hpp ** Metaprogramming helpers for deriving the precise function signatures ** necessary to implement a given command. Basically, commands can be implemented ** by arbitrary functions, but the signatures of the operation function, the ** undo function and the undo state capturing function are required to obey ** fixed relationships. Thus, at various stages of the command definition, ** we need to accept functor objects with a very specific and predetermined ** signature, thus allowing for strict type checking by the compiler. ** ** \par Relation of function signatures ** - operation: void(P1,..PN) ** - captureUndo: MEM(P1,..PN) ** - undoOperation void(P1,..PN,MEM) ** - bind takes the arguments:(P1,..PN) ** ** @see Command ** @see CommandDef ** */ #ifndef CONTROL_COMMAND_SIGNATURE_H #define CONTROL_COMMAND_SIGNATURE_H //#include "pre.hpp" //#include "include/symbol.hpp" #include "lib/meta/function.hpp" #include "lib/meta/typelist.hpp" #include "lib/meta/typelist-util.hpp" #include "lib/meta/typeseq-util.hpp" //#include "lib/meta/tuple.hpp" //#include #include namespace control { // using lumiera::Symbol; // using std::tr1::shared_ptr; using std::tr1::function; using lumiera::typelist::FunctionSignature; using lumiera::typelist::FunctionTypedef; using lumiera::typelist::Types; //using lumiera::typelist::NullType; //using lumiera::typelist::Tuple; using lumiera::typelist::Append; using lumiera::typelist::SplitLast; /** * Metaprogramming helper for building Command function signatures. * The complete definition context of any command is templated to the signature * of the actual command operation and to the memento type. The typedefs embedded * within CommandSignature allows accepting suitable typed functions * to implement the command in question. */ template class CommandSignature { typedef typename FunctionSignature< function >::Args Args; typedef typename Args::List ArgList; typedef typename Append::List ExtendedArglist; typedef typename Types::Seq ExtendedArgs; public: typedef typename FunctionTypedef::Sig OperateSig; typedef typename FunctionTypedef::Sig CaptureSig; typedef typename FunctionTypedef::Sig UndoOp_Sig; typedef MEM Memento; }; /** * Type analysis helper template. * Used for dissecting a given type signature to derive * the related basic operation signature, the signature of a possible Undo-function * and the signature necessary for capturing undo information. The implementation * relies on re-binding an embedded type defining template, based on the actual * case, as identified by the structure of the given parameter signature. */ template class UndoSignature { typedef typename FunctionSignature< function >::Args Args; typedef typename FunctionSignature< function >::Ret Ret; /** Case1: defining the Undo-Capture function */ template struct Case { typedef RET Memento; typedef typename Append::List ExtendedArglist; typedef typename Types::Seq ExtendedArgs; typedef typename FunctionTypedef::Sig OperateSig; typedef typename FunctionTypedef::Sig CaptureSig; typedef typename FunctionTypedef::Sig UndoOp_Sig; }; /** Case2: defining the actual Undo function */ template struct Case { typedef typename ARG::List Args; typedef typename SplitLast::Type Memento; typedef typename SplitLast::List OperationArglist; typedef typename Types::Seq OperationArgs; typedef typename FunctionTypedef::Sig OperateSig; typedef typename FunctionTypedef::Sig CaptureSig; typedef typename FunctionTypedef::Sig UndoOp_Sig; }; public: typedef typename Case::CaptureSig CaptureSig; typedef typename Case::UndoOp_Sig UndoOp_Sig; typedef typename Case::OperateSig OperateSig; typedef typename Case::Memento Memento; }; } // namespace control #endif