refactoring(#988): switch command framework to std::tuple
this was rather easy, since the stadard tuple is a drop-in replacement, and we do nothing special here, beyond inheriting from a tuple type
This commit is contained in:
parent
fd2d56ca45
commit
0e10ef09ec
6 changed files with 172 additions and 102 deletions
|
|
@ -28,7 +28,7 @@
|
||||||
** with the Tuples provided by the standard library.
|
** with the Tuples provided by the standard library.
|
||||||
**
|
**
|
||||||
** @see control::CommandDef usage example
|
** @see control::CommandDef usage example
|
||||||
** @see tuple-test.cpp
|
** @see TupleHelper_test
|
||||||
** @see typelist.hpp
|
** @see typelist.hpp
|
||||||
** @see function.hpp
|
** @see function.hpp
|
||||||
** @see generator.hpp
|
** @see generator.hpp
|
||||||
|
|
@ -50,7 +50,68 @@
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace meta {
|
namespace meta {
|
||||||
|
|
||||||
namespace {
|
/**
|
||||||
|
* temporary workaround:
|
||||||
|
* alternative definition of "type sequence",
|
||||||
|
* already using variadic template parameters.
|
||||||
|
* @remarks the problem with our existing type sequence type
|
||||||
|
* is that it fills the end of each sequence with NullType,
|
||||||
|
* which was the only way to get a flexible type sequence
|
||||||
|
* prior to C++11. Unfortunately these trailing NullType
|
||||||
|
* entries do not play well with other variadic defs.
|
||||||
|
* @deprecated when we switch our primary type sequence type
|
||||||
|
* to variadic parameters, this type will be superfluous.
|
||||||
|
*/
|
||||||
|
template<typename...TYPES>
|
||||||
|
struct TySeq
|
||||||
|
{
|
||||||
|
using Seq = TySeq;
|
||||||
|
using List = typename Types<TYPES...>::List;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* temporary workaround: additional specialisation for the template
|
||||||
|
* `Prepend` to work also with the (alternative) variadic TySeq.
|
||||||
|
* @see typeseq-util.hpp
|
||||||
|
*/
|
||||||
|
template<typename T, typename...TYPES>
|
||||||
|
struct Prepend<T, TySeq<TYPES...>>
|
||||||
|
{
|
||||||
|
using Seq = TySeq<T, TYPES...>;
|
||||||
|
using List = typename Types<T, TYPES...>::List;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* temporary workaround: strip trailing NullType entries from a
|
||||||
|
* type sequence, to make it compatible with new-style variadic
|
||||||
|
* template definitions.
|
||||||
|
* @note the result type is a TySec, to keep it apart from our
|
||||||
|
* legacy (non-variadic) lib::meta::Types
|
||||||
|
* @deprecated necessary for the transition to variadic sequences
|
||||||
|
*/
|
||||||
|
template<typename SEQ>
|
||||||
|
struct StripNullType;
|
||||||
|
|
||||||
|
template<typename T, typename...TYPES>
|
||||||
|
struct StripNullType<Types<T,TYPES...>>
|
||||||
|
{
|
||||||
|
using TailSeq = typename StripNullType<Types<TYPES...>>::Seq;
|
||||||
|
|
||||||
|
using Seq = typename Prepend<T, TailSeq>::Seq;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename...TYPES>
|
||||||
|
struct StripNullType<Types<NullType, TYPES...>>
|
||||||
|
{
|
||||||
|
using Seq = TySeq<>; // NOTE: this causes the result to be a TySeq
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace { // rebinding helper to create std::tuple from a type sequence
|
||||||
|
|
||||||
template<typename SEQ>
|
template<typename SEQ>
|
||||||
struct BuildTupleType
|
struct BuildTupleType
|
||||||
|
|
@ -58,21 +119,57 @@ namespace meta {
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template<typename...TYPES>
|
template<typename...TYPES>
|
||||||
struct BuildTupleType<Types<TYPES...>>
|
struct BuildTupleType<TySeq<TYPES...>>
|
||||||
{
|
{
|
||||||
using Type = std::tuple<TYPES...>;
|
using Type = std::tuple<TYPES...>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* temporary workaround: strip trailing NullType entries
|
||||||
|
* prior to rebinding to the `std::tuple` type.
|
||||||
|
*/
|
||||||
|
template<typename...TYPES>
|
||||||
|
struct BuildTupleType<Types<TYPES...>>
|
||||||
|
{
|
||||||
|
using VariadicSeq = typename StripNullType<Types<TYPES...>>::Seq;
|
||||||
|
|
||||||
|
using Type = typename BuildTupleType<VariadicSeq>::Type;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename...TYPES>
|
/** Build a `std::tuple` from types given as type sequence
|
||||||
|
* @remarks for Lumiera, we deliberately use a dedicated template `Types`
|
||||||
|
* to mark a type sequence of types as such. This allows to pass such a
|
||||||
|
* sequence as first-class citizen. The standard library often (ab)uses
|
||||||
|
* the std::tuple for this purpose, which is an understandable, yet
|
||||||
|
* inferior design choice. We should always favour dedicated types
|
||||||
|
* over clever re-use of existing types.
|
||||||
|
*/
|
||||||
|
template<typename TYPES>
|
||||||
using Tuple = typename BuildTupleType<TYPES>::Type;
|
using Tuple = typename BuildTupleType<TYPES>::Type;
|
||||||
|
|
||||||
|
|
||||||
|
using std::tuple_size;
|
||||||
|
using std::tuple_element;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** match and rebind the type sequence from a tuple */
|
||||||
|
template<typename...TYPES>
|
||||||
|
struct Types<std::tuple<TYPES...>>
|
||||||
|
{
|
||||||
|
using Seq = typename Types<TYPES...>::Seq;
|
||||||
|
using List = typename Seq::List;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Hold a sequence of index numbers as template parameters */
|
/** Hold a sequence of index numbers as template parameters */
|
||||||
template<size_t...idx>
|
template<size_t...idx>
|
||||||
struct IndexSeq
|
struct IndexSeq
|
||||||
{
|
{
|
||||||
template<size_t i>
|
template<size_t i>
|
||||||
using AppendElm = IndexSeq<idx..., i>;
|
using AppendElm = IndexSeq<idx..., i>;
|
||||||
|
|
@ -80,16 +177,16 @@ namespace meta {
|
||||||
|
|
||||||
/** build an `IndexSeq<0, 1, 2, ..., n-1>` */
|
/** build an `IndexSeq<0, 1, 2, ..., n-1>` */
|
||||||
template<size_t n>
|
template<size_t n>
|
||||||
struct BuildIndexSeq
|
struct BuildIndexSeq
|
||||||
{
|
{
|
||||||
using Ascending = typename BuildIndexSeq<n-1>::Ascending::AppendElm<n>;
|
using Ascending = typename BuildIndexSeq<n-1>::Ascending::template AppendElm<n-1>;
|
||||||
|
|
||||||
template<size_t i>
|
template<size_t i>
|
||||||
using FilledWith = typename BuildIndexSeq<n-1>::FilledWith<i>::AppendElm<i>;
|
using FilledWith = typename BuildIndexSeq<n-1>::template FilledWith<i>::template AppendElm<i>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct BuildIndexSeq<0>
|
struct BuildIndexSeq<0>
|
||||||
{
|
{
|
||||||
using Ascending = IndexSeq<>;
|
using Ascending = IndexSeq<>;
|
||||||
|
|
||||||
|
|
@ -709,60 +806,49 @@ namespace meta {
|
||||||
public:
|
public:
|
||||||
static const bool value = (sizeof(Yes_t)== Check<TUP>::result);
|
static const bool value = (sizeof(Yes_t)== Check<TUP>::result);
|
||||||
};
|
};
|
||||||
|
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////OBSOLETE :: TICKET #988
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorating a tuple type with auxiliary data access operations.
|
* Decorating a tuple type with auxiliary data access operations.
|
||||||
* This helper template builds up a subclass of the given TUP (base) type
|
* This helper template builds up a subclass of the given TUP (base) type
|
||||||
* (which is assumed to be a Tuple or at least need to be copy constructible
|
* (which is assumed to be a Tuple or at least need to be copy constructible
|
||||||
* from \c Tuple<TYPES> ). The purpose is to use the Tuple as storage, but
|
* from `Tuple<TYPES>` ). The purpose is to use the Tuple as storage record, but
|
||||||
* to add a layer of access functions, which in turn might rely on the exact
|
* to add a layer of access functions, which in turn might rely on the exact
|
||||||
* type of the individual elements within the Tuple. To achieve this, for each
|
* type of the individual elements within the Tuple. To achieve this, for each
|
||||||
* type within the Tuple, the TUP type is decorated with an instance of the
|
* type within the Tuple, the TUP type is decorated with an instance of the
|
||||||
* template passed in as template template parameter _X_. Each of these
|
* template passed in as template template parameter _X_. Each of these
|
||||||
* decorating instances is provided with a index allowing to access "his"
|
* decorating instances is provided with an index number, allowing to
|
||||||
* specific element within the underlying tuple.
|
* access "his" specific element within the underlying tuple.
|
||||||
*
|
*
|
||||||
* The decorating template _X_ need to take its own base class as template
|
* The decorating template _X_ need to take its own base class as template
|
||||||
* parameter. Typically, operations on _X_ will be defined in a recursive fashion,
|
* parameter. Typically, operations on _X_ will be defined in a recursive fashion,
|
||||||
* calling down into this templated base class. To support this, an instantiation
|
* calling down into this templated base class. To support this, an instantiation
|
||||||
* of _X_ with the empty type sequence is generated for detecting recursion end
|
* of _X_ with the empty type sequence is generated for detecting recursion end
|
||||||
* (built as innermost decorator, i.e. immediate subclass of TUP)
|
* (built as innermost decorator, i.e. the immediate subclass of TUP)
|
||||||
*/
|
*/
|
||||||
template
|
template
|
||||||
< typename TYPES ///< Type sequence to use within the Accessor (usually the Tuple Types)
|
< template<class,class,class, uint> class _X_ ///< user provided template<Type, Base, TupleType, arg-idx>
|
||||||
, template<class,class,class, uint> class _X_ ///< user provided template<Type, Base, TupleType, arg-No>
|
, typename TYPES ///< Sequence of types to use within the Accessor
|
||||||
, class TUP =Tuple<TYPES> ///< the tuple type to build on
|
, class TUP =Tuple<TYPES> ///< the tuple type to build on
|
||||||
, uint i = 0 ///< tuple element index counter
|
, uint i = 0 ///< tuple element index counter
|
||||||
>
|
>
|
||||||
class BuildTupleAccessor
|
class BuildTupleAccessor
|
||||||
{
|
{
|
||||||
typedef Tuple<TYPES> ArgTuple;
|
// prepare recursion...
|
||||||
typedef typename ArgTuple::HeadType Head;
|
using Head = typename Split<TYPES>::Head;
|
||||||
typedef typename ArgTuple::TailType Tail;
|
using Tail = typename Split<TYPES>::Tail;
|
||||||
typedef BuildTupleAccessor<Tail,_X_,TUP, i+1> NextBuilder;
|
using NextBuilder = BuildTupleAccessor<_X_, Tail,TUP, i+1>;
|
||||||
typedef typename NextBuilder::Accessor NextAccessor;
|
using NextAccessor = typename NextBuilder::Product;
|
||||||
|
|
||||||
ArgTuple const& argData_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** type of the product created by this template.
|
/** type of the product created by this template.
|
||||||
* Will be a subclass of TUP */
|
* Will be a subclass of TUP */
|
||||||
typedef _X_< Head // the type to use for this accessor
|
using Product = _X_< Head // the type to use for this accessor
|
||||||
, NextAccessor // the base type to inherit from
|
, NextAccessor // the base type to inherit from
|
||||||
, TUP // the tuple type we build upon
|
, TUP // the tuple type we build upon
|
||||||
, i // current element index
|
, i // current element index
|
||||||
> Accessor;
|
>;
|
||||||
|
|
||||||
|
|
||||||
BuildTupleAccessor (ArgTuple const& tup)
|
|
||||||
: argData_(tup)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/** used to get the product of this builder template... */
|
|
||||||
operator Accessor() { return Accessor(argData_); }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -771,24 +857,13 @@ namespace meta {
|
||||||
, class TUP
|
, class TUP
|
||||||
, uint i
|
, uint i
|
||||||
>
|
>
|
||||||
class BuildTupleAccessor<Types<>, _X_, TUP, i>
|
class BuildTupleAccessor< _X_, Types<>, TUP, i>
|
||||||
{
|
{
|
||||||
typedef Tuple<Types<> > ArgTuple;
|
|
||||||
ArgTuple const& argData_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef _X_<NullType, TUP, TUP, 0> Accessor;
|
using Product = _X_<NullType, TUP, TUP, i>; // Note: i == tuple size
|
||||||
|
|
||||||
BuildTupleAccessor (ArgTuple const& tup)
|
|
||||||
: argData_(tup)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/** used to get the product of this builder template... */
|
|
||||||
operator Accessor() { return Accessor(argData_); }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////OBSOLETE :: TICKET #988
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,9 @@
|
||||||
|
|
||||||
#include "lib/meta/typelist.hpp"
|
#include "lib/meta/typelist.hpp"
|
||||||
#include "lib/meta/function.hpp"
|
#include "lib/meta/function.hpp"
|
||||||
#include "lib/meta/tuple.hpp"
|
#include "lib/meta/tuple-helper.hpp"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -624,8 +626,7 @@ namespace control {
|
||||||
class AcceptArgumentTuple
|
class AcceptArgumentTuple
|
||||||
: public bind_arg::AcceptArgs<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
|
: public bind_arg::AcceptArgs<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
|
||||||
, typename bind_arg::_Type<SIG>::Args>
|
, typename bind_arg::_Type<SIG>::Args>
|
||||||
{
|
{ };
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** Helper Template for Proc-Layer control::Command : mix in a \c bind(...) function
|
/** Helper Template for Proc-Layer control::Command : mix in a \c bind(...) function
|
||||||
|
|
@ -637,8 +638,7 @@ namespace control {
|
||||||
class AcceptArgumentBinding
|
class AcceptArgumentBinding
|
||||||
: public bind_arg::AcceptBind<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
|
: public bind_arg::AcceptBind<TAR,BASE, typename bind_arg::_Type<SIG>::Ret
|
||||||
, typename bind_arg::_Type<SIG>::Args>
|
, typename bind_arg::_Type<SIG>::Args>
|
||||||
{
|
{ };
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** Variation of AcceptArgumentBinding, allowing to control the return type
|
/** Variation of AcceptArgumentBinding, allowing to control the return type
|
||||||
|
|
@ -648,8 +648,7 @@ namespace control {
|
||||||
class AcceptArgumentBindingRet
|
class AcceptArgumentBindingRet
|
||||||
: public bind_arg::AcceptBind<TAR,BASE, RET
|
: public bind_arg::AcceptBind<TAR,BASE, RET
|
||||||
, typename bind_arg::_Type<SIG>::Args>
|
, typename bind_arg::_Type<SIG>::Args>
|
||||||
{
|
{ };
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** Helper Template for control::Command, mix-in complete set of \c bind(...) functions
|
/** Helper Template for control::Command, mix-in complete set of \c bind(...) functions
|
||||||
|
|
@ -663,8 +662,7 @@ namespace control {
|
||||||
>
|
>
|
||||||
class AcceptAnyBinding
|
class AcceptAnyBinding
|
||||||
: public bind_arg::AcceptAnyBind<TAR,BASE,RET>
|
: public bind_arg::AcceptAnyBind<TAR,BASE,RET>
|
||||||
{
|
{ };
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
#include "lib/meta/function.hpp"
|
#include "lib/meta/function.hpp"
|
||||||
#include "lib/meta/function-closure.hpp"
|
#include "lib/meta/function-closure.hpp"
|
||||||
#include "lib/meta/function-erasure.hpp"
|
#include "lib/meta/function-erasure.hpp"
|
||||||
#include "lib/meta/tuple.hpp"
|
#include "lib/meta/tuple-helper.hpp"
|
||||||
#include "lib/meta/maybe-compare.hpp"
|
#include "lib/meta/maybe-compare.hpp"
|
||||||
#include "lib/format-cout.hpp"
|
#include "lib/format-cout.hpp"
|
||||||
#include "lib/util.hpp"
|
#include "lib/util.hpp"
|
||||||
|
|
@ -165,14 +165,11 @@ namespace control {
|
||||||
class ParamAccessor
|
class ParamAccessor
|
||||||
: public BASE
|
: public BASE
|
||||||
{
|
{
|
||||||
TY & element() { return BASE::template getAt<idx>(); }
|
TY & element() { return std::get<idx> (*this); }
|
||||||
TY const& element() const { return unConst(this)->template getAt<idx>(); }
|
TY const& element() const { return std::get<idx> (*this); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using BASE::BASE;
|
||||||
ParamAccessor(TUP const& tuple)
|
|
||||||
: BASE(tuple)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////TODO the real access operations (e.g. for serialising) go here
|
////////////////////TODO the real access operations (e.g. for serialising) go here
|
||||||
|
|
@ -195,13 +192,13 @@ namespace control {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class TUP>
|
template<class TUP, uint n>
|
||||||
class ParamAccessor<NullType, TUP, TUP, 0> ///< used for recursion end of implementation functions
|
class ParamAccessor<NullType, TUP, TUP, n> ///< used for recursion end of implementation functions
|
||||||
: public TUP
|
: public TUP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParamAccessor(TUP const& tuple)
|
ParamAccessor (TUP const& tup)
|
||||||
: TUP(tuple)
|
: TUP(tup)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
////////////////////TODO the recursion-end of the access operations goes here
|
////////////////////TODO the recursion-end of the access operations goes here
|
||||||
|
|
@ -225,11 +222,10 @@ namespace control {
|
||||||
class Closure
|
class Closure
|
||||||
: public AbstractClosure
|
: public AbstractClosure
|
||||||
{
|
{
|
||||||
typedef typename FunctionSignature< function<SIG> >::Args Args;
|
using Args = typename FunctionSignature< function<SIG> >::Args;
|
||||||
|
using Builder = BuildTupleAccessor<ParamAccessor, Args>;
|
||||||
|
|
||||||
|
using ParamStorageTuple =typename Builder::Product;
|
||||||
typedef BuildTupleAccessor<Args,ParamAccessor> Builder;
|
|
||||||
typedef typename Builder::Accessor ParamStorageTuple;
|
|
||||||
|
|
||||||
ParamStorageTuple params_;
|
ParamStorageTuple params_;
|
||||||
|
|
||||||
|
|
@ -237,7 +233,7 @@ namespace control {
|
||||||
typedef Tuple<Args> ArgTuple;
|
typedef Tuple<Args> ArgTuple;
|
||||||
|
|
||||||
Closure (ArgTuple const& args)
|
Closure (ArgTuple const& args)
|
||||||
: params_(Builder (args))
|
: params_(args)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/** create a clone copy of this, without disclosing the exact type */
|
/** create a clone copy of this, without disclosing the exact type */
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
#include "lib/meta/function.hpp"
|
#include "lib/meta/function.hpp"
|
||||||
#include "lib/meta/typelist.hpp"
|
#include "lib/meta/typelist.hpp"
|
||||||
#include "lib/meta/typelist-manip.hpp"
|
#include "lib/meta/typelist-manip.hpp"
|
||||||
#include "lib/meta/tuple.hpp"
|
#include "lib/meta/tuple-helper.hpp"
|
||||||
#include "lib/util.hpp"
|
#include "lib/util.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
@ -83,15 +83,16 @@ namespace control {
|
||||||
using std::function;
|
using std::function;
|
||||||
using std::bind;
|
using std::bind;
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
using std::tuple_size;
|
||||||
using lib::Symbol;
|
using lib::Symbol;
|
||||||
using util::cStr;
|
using util::cStr;
|
||||||
|
|
||||||
using lib::meta::FunctionSignature;
|
using lib::meta::FunctionSignature;
|
||||||
using lib::meta::FunctionTypedef;
|
using lib::meta::FunctionTypedef;
|
||||||
using lib::meta::Types;
|
|
||||||
using lib::meta::NullType;
|
using lib::meta::NullType;
|
||||||
|
using lib::meta::Types;
|
||||||
|
using lib::meta::TySeq;
|
||||||
using lib::meta::Tuple;
|
using lib::meta::Tuple;
|
||||||
using lib::meta::tuple::makeNullTuple;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -161,8 +162,8 @@ namespace control {
|
||||||
void
|
void
|
||||||
maybeArm_if_zero_parameters()
|
maybeArm_if_zero_parameters()
|
||||||
{
|
{
|
||||||
if (0 == Tuple<CmdArgs>::SIZE )
|
if (0 == tuple_size<Tuple<CmdArgs>>::value )
|
||||||
prototype_.bindArg (makeNullTuple());
|
prototype_.bindArg<> (std::tuple<>());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@
|
||||||
#include "proc/control/argument-erasure.hpp"
|
#include "proc/control/argument-erasure.hpp"
|
||||||
#include "proc/control/argument-tuple-accept.hpp"
|
#include "proc/control/argument-tuple-accept.hpp"
|
||||||
#include "proc/control/handling-pattern.hpp"
|
#include "proc/control/handling-pattern.hpp"
|
||||||
|
#include "lib/meta/tuple-helper.hpp"
|
||||||
#include "lib/bool-checkable.hpp"
|
#include "lib/bool-checkable.hpp"
|
||||||
#include "lib/meta/tuple.hpp"
|
|
||||||
#include "lib/handle.hpp"
|
#include "lib/handle.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -75,6 +75,7 @@ namespace control {
|
||||||
using lib::Symbol;
|
using lib::Symbol;
|
||||||
using std::shared_ptr;
|
using std::shared_ptr;
|
||||||
using lib::meta::Tuple;
|
using lib::meta::Tuple;
|
||||||
|
using lib::meta::Types;
|
||||||
|
|
||||||
|
|
||||||
LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS); ///< Command functor not yet usable, because arguments aren't bound
|
LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS); ///< Command functor not yet usable, because arguments aren't bound
|
||||||
|
|
@ -130,8 +131,8 @@ namespace control {
|
||||||
|
|
||||||
/* === command lifecycle === */
|
/* === command lifecycle === */
|
||||||
|
|
||||||
template<typename TYPES>
|
template<typename...TYPES>
|
||||||
Command& bindArg (Tuple<TYPES> const&);
|
Command& bindArg (std::tuple<TYPES...> const&);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////TICKET #798 : we need a second overload to take the arguments as lib::diff::Record.
|
/////////////////////////////////////////////////////////////TICKET #798 : we need a second overload to take the arguments as lib::diff::Record.
|
||||||
///////////////////////////////////////////////////////////// : this needs to be built into the ParamAccessor within Closure (command-closure.hpp)
|
///////////////////////////////////////////////////////////// : this needs to be built into the ParamAccessor within Closure (command-closure.hpp)
|
||||||
|
|
@ -204,14 +205,14 @@ namespace control {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename TYPES>
|
template<typename...TYPES>
|
||||||
inline Command&
|
inline Command&
|
||||||
Command::bindArg (Tuple<TYPES> const& tuple)
|
Command::bindArg (std::tuple<TYPES...> const& tuple)
|
||||||
{
|
{
|
||||||
TypedArguments<Tuple<TYPES> > args(tuple);
|
TypedArguments<std::tuple<TYPES...>> args(tuple);
|
||||||
this->setArguments (args);
|
this->setArguments (args);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -219,9 +220,9 @@ namespace control {
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
Command::defined (Symbol cmdID)
|
Command::defined (Symbol cmdID)
|
||||||
{
|
{
|
||||||
return fetchDef(cmdID).isValid();
|
return fetchDef(cmdID).isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define _FAILSAFE_COMMAND_QUERY(_ID_, _QUERY_) \
|
#define _FAILSAFE_COMMAND_QUERY(_ID_, _QUERY_) \
|
||||||
|
|
@ -238,16 +239,16 @@ namespace control {
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
Command::canExec (Symbol cmdID)
|
Command::canExec (Symbol cmdID)
|
||||||
{
|
{
|
||||||
_FAILSAFE_COMMAND_QUERY (cmdID, canExec() );
|
_FAILSAFE_COMMAND_QUERY (cmdID, canExec() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
Command::canUndo (Symbol cmdID)
|
Command::canUndo (Symbol cmdID)
|
||||||
{
|
{
|
||||||
_FAILSAFE_COMMAND_QUERY (cmdID, canUndo() );
|
_FAILSAFE_COMMAND_QUERY (cmdID, canUndo() );
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef _FAILSAFE_COMMAND_QUERY
|
#undef _FAILSAFE_COMMAND_QUERY
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,6 @@ namespace test {
|
||||||
// using lumiera::P;
|
// using lumiera::P;
|
||||||
|
|
||||||
|
|
||||||
//using lib::meta::BuildTupleAccessor;
|
|
||||||
// using lumiera::error::LUMIERA_ERROR_EXTERNAL;
|
// using lumiera::error::LUMIERA_ERROR_EXTERNAL;
|
||||||
|
|
||||||
namespace { // test data and helpers...
|
namespace { // test data and helpers...
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue