refactoring(#988): switch correspoinging tests to std::tuple
...with this changeset, our own tuple type should be basically disconnected and not used anymore
This commit is contained in:
parent
0e10ef09ec
commit
f6d04d4d02
12 changed files with 259 additions and 250 deletions
|
|
@ -47,6 +47,14 @@
|
|||
#include <tuple>
|
||||
|
||||
|
||||
namespace util { // forward declaration
|
||||
|
||||
template<typename TY>
|
||||
std::string
|
||||
toString (TY const& val) noexcept;
|
||||
}
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace meta {
|
||||
|
||||
|
|
@ -164,6 +172,18 @@ namespace meta {
|
|||
};
|
||||
|
||||
|
||||
/** trait to detect tuple types */
|
||||
template<typename T>
|
||||
struct is_Tuple
|
||||
: std::false_type
|
||||
{ };
|
||||
|
||||
template<typename...TYPES>
|
||||
struct is_Tuple<std::tuple<TYPES...>>
|
||||
: std::true_type
|
||||
{ };
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -866,7 +886,89 @@ namespace meta {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Helper to dump tuple contents.
|
||||
* Defined to act as "Accessor" for BuildTupleAccessor, this helper template
|
||||
* allows to create a recursive operation to invoke string conversion on
|
||||
* all elements within any given tuple.
|
||||
*/
|
||||
template
|
||||
< typename TY
|
||||
, class BASE
|
||||
, class TUP
|
||||
, uint idx
|
||||
>
|
||||
struct TupleElementDisplayer
|
||||
: BASE
|
||||
{
|
||||
using BASE::BASE;
|
||||
|
||||
std::string
|
||||
dump (std::string const& prefix ="(") const
|
||||
{
|
||||
return BASE::dump (prefix + util::toString(std::get<idx>(*this))+",");
|
||||
}
|
||||
};
|
||||
|
||||
template<class TUP, uint n>
|
||||
struct TupleElementDisplayer<NullType, TUP, TUP, n>
|
||||
: TUP
|
||||
{
|
||||
TupleElementDisplayer (TUP const& tup)
|
||||
: TUP(tup)
|
||||
{ }
|
||||
|
||||
std::string
|
||||
dump (std::string const& prefix ="(") const
|
||||
{
|
||||
if (1 < prefix.length())
|
||||
// remove the trailing comma
|
||||
return prefix.substr (0, prefix.length()-1) +")";
|
||||
else
|
||||
return prefix+")";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* convenience function to dump a given tuple's contents.
|
||||
* Using the BuildTupleAccessor, we layer a stack of Instantiations of
|
||||
* the TupleElementDisplayer temporarily on top of the given tuple,
|
||||
* just to invoke a recursive call chain through this layers
|
||||
* and get a string representation of each element in the
|
||||
* tuple.
|
||||
*/
|
||||
template<typename...TYPES>
|
||||
inline std::string
|
||||
dump (std::tuple<TYPES...> const& tuple)
|
||||
{
|
||||
using BuildAccessor = BuildTupleAccessor<TupleElementDisplayer, Types<TYPES...>>;
|
||||
using Displayer = typename BuildAccessor::Product ;
|
||||
|
||||
return static_cast<Displayer const&> (tuple)
|
||||
.dump();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::meta
|
||||
|
||||
|
||||
// add a specialisation to enable tuple string conversion
|
||||
namespace util {
|
||||
|
||||
template<typename...TYPES>
|
||||
struct StringConv<std::tuple<TYPES...>>
|
||||
{
|
||||
static std::string
|
||||
invoke (std::tuple<TYPES...> const& tuple) noexcept
|
||||
try {
|
||||
return "«"+typeStr(tuple)
|
||||
+ "»──" + lib::meta::dump (tuple);
|
||||
}
|
||||
catch(...) { return FAILURE_INDICATOR; }
|
||||
};
|
||||
|
||||
|
||||
} // namespace util
|
||||
#endif /*LIB_META_TUPLE_HELPER_H*/
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ namespace control {
|
|||
namespace bind_arg { // internals....
|
||||
|
||||
using namespace lib::meta;
|
||||
using std::make_tuple;
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -93,7 +94,7 @@ namespace control {
|
|||
RET
|
||||
operator() ()
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::makeNullTuple() );
|
||||
return static_cast<TAR*> (this) -> bindArg (std::tuple<>() );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ namespace control {
|
|||
RET
|
||||
operator() (T1 a1)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -122,7 +123,7 @@ namespace control {
|
|||
RET
|
||||
operator() (T1 a1, T2 a2)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -138,7 +139,7 @@ namespace control {
|
|||
RET
|
||||
operator() (T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -155,7 +156,7 @@ namespace control {
|
|||
RET
|
||||
operator() (T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -173,7 +174,7 @@ namespace control {
|
|||
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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -192,7 +193,7 @@ namespace control {
|
|||
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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -212,7 +213,7 @@ namespace control {
|
|||
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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -233,7 +234,7 @@ namespace control {
|
|||
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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7,a8));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -255,7 +256,7 @@ namespace control {
|
|||
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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7,a8,a9));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -284,7 +285,7 @@ namespace control {
|
|||
RET
|
||||
bind ()
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::makeNullTuple() );
|
||||
return static_cast<TAR*> (this) -> bindArg (std::tuple<>() );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -298,7 +299,7 @@ namespace control {
|
|||
RET
|
||||
bind (T1 a1)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -313,7 +314,7 @@ namespace control {
|
|||
RET
|
||||
bind (T1 a1, T2 a2)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -329,7 +330,7 @@ namespace control {
|
|||
RET
|
||||
bind (T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -346,7 +347,7 @@ namespace control {
|
|||
RET
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -364,7 +365,7 @@ namespace control {
|
|||
RET
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -383,7 +384,7 @@ namespace control {
|
|||
RET
|
||||
bind (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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -403,7 +404,7 @@ namespace control {
|
|||
RET
|
||||
bind (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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -424,7 +425,7 @@ namespace control {
|
|||
RET
|
||||
bind (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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7,a8));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -446,7 +447,7 @@ namespace control {
|
|||
RET
|
||||
bind (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));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7,a8,a9));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -467,7 +468,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind () ///< Accept dummy binding (0 Arg)
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::makeNullTuple());
|
||||
return static_cast<TAR*> (this) -> bindArg (std::tuple<>());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -475,7 +476,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1) ///< Accept binding with 1 Argument
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -485,7 +486,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2) ///< Accept binding for 2 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -496,7 +497,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3) ///< Accept binding for 3 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -508,7 +509,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4) ///< Accept binding for 4 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -521,7 +522,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) ///< Accept binding for 5 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -535,7 +536,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) ///< Accept binding for 6 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -550,7 +551,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) ///< Accept binding for 7 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -566,7 +567,7 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8) ///< Accept binding for 8 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7,a8));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -583,29 +584,31 @@ namespace control {
|
|||
RET //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9) ///< Accept binding for 9 Arguments
|
||||
{
|
||||
return static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8,a9));
|
||||
return static_cast<TAR*> (this) -> bindArg (make_tuple (a1,a2,a3,a4,a5,a6,a7,a8,a9));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
using lib::meta::Tuple;
|
||||
|
||||
|
||||
template<typename SIG>
|
||||
struct _Type
|
||||
{
|
||||
typedef typename FunctionSignature< function<SIG> >::Args Args;
|
||||
typedef typename FunctionSignature< function<SIG> >::Ret Ret;
|
||||
typedef Tuple<Args> ArgTuple;
|
||||
typedef SIG Sig;
|
||||
using Args = typename FunctionSignature< function<SIG> >::Args;
|
||||
using Ret = typename FunctionSignature< function<SIG> >::Ret;
|
||||
using Sig = SIG;
|
||||
using ArgTuple = Tuple<Args>;
|
||||
};
|
||||
|
||||
template<typename TYPES>
|
||||
struct _Type<Tuple<TYPES> >
|
||||
template<typename...TYPES>
|
||||
struct _Type<std::tuple<TYPES...> >
|
||||
{
|
||||
typedef TYPES Args;
|
||||
typedef void Ret;
|
||||
typedef Tuple<TYPES> ArgTuple;
|
||||
typedef typename FunctionTypedef<void, TYPES>::Sig Sig;
|
||||
using Args = typename Types<TYPES...>::Seq;
|
||||
using Ret = void;
|
||||
using Sig = typename FunctionTypedef<void, Args>::Sig;
|
||||
using ArgTuple = std::tuple<TYPES...>;
|
||||
};
|
||||
|
||||
struct Dummy {};
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
TEST "TypeTuple_test" TypeTuple_test <<END
|
||||
TEST "tuple metaprogramming helpers" TupleHelper_test <<END
|
||||
out-lit: L1 :-<1>-<3>-<5>-
|
||||
out-lit: L2 :-<2>-<4>-
|
||||
out-lit: L3 :-<7>-
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "proc/control/argument-tuple-accept.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
namespace proc {
|
||||
|
|
@ -108,8 +109,8 @@ namespace test {
|
|||
cout << showSizeof(testVoid) << endl;
|
||||
cout << showSizeof(testTime) << endl;
|
||||
|
||||
cout << testTime.getHead() << endl;
|
||||
CHECK (23 == testTime.getTail().getHead());
|
||||
cout << std::get<0> (testTime) << endl;
|
||||
CHECK (23 == std::get<1> (testTime));
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "lib/test/test-helper.hpp"
|
||||
#include "proc/control/command-argument-holder.hpp"
|
||||
#include "lib/scoped-ptrvect.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/util-foreach.hpp"
|
||||
|
|
@ -35,6 +34,7 @@
|
|||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
using util::_Fmt;
|
||||
using util::isnil;
|
||||
|
|
@ -44,6 +44,7 @@ using lib::time::TimeVar;
|
|||
using lib::time::TimeValue;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
using std::make_tuple;
|
||||
using std::rand;
|
||||
|
||||
|
||||
|
|
@ -238,12 +239,12 @@ namespace test {
|
|||
|
||||
for_each (tup, showIt);
|
||||
|
||||
arg1->storeTuple (tuple::makeNullTuple());
|
||||
arg2->storeTuple (tuple::make (rand() % 10));
|
||||
arg3->storeTuple (tuple::make (rand() % 10, TimeVar(randTime())));
|
||||
arg4->storeTuple (tuple::make (rand() % 10, TimeVar(randTime())));
|
||||
arg1->storeTuple (std::tuple<>());
|
||||
arg2->storeTuple (make_tuple (rand() % 10));
|
||||
arg3->storeTuple (make_tuple (rand() % 10, TimeVar(randTime())));
|
||||
arg4->storeTuple (make_tuple (rand() % 10, TimeVar(randTime())));
|
||||
|
||||
arg5->storeTuple (tuple::make (TTime (randTime()), Tstr("glorious"), twoRandomDigits() ));
|
||||
arg5->storeTuple (make_tuple (TTime (randTime()), Tstr("glorious"), twoRandomDigits() ));
|
||||
|
||||
CHECK (!arg5->canUndo());
|
||||
|
||||
|
|
@ -288,23 +289,23 @@ namespace test {
|
|||
two.memento() = one.memento(); // put the same UNDO state in both
|
||||
CHECK (one == two); // ...makes them equal again
|
||||
|
||||
one.storeTuple (tuple::make (1,2));
|
||||
one.storeTuple (make_tuple (1,2));
|
||||
CHECK (one != two); // verify argument tuple comparison
|
||||
CHECK (two != one);
|
||||
CHECK (!isnil (one));
|
||||
CHECK ( isnil (two));
|
||||
|
||||
two.storeTuple (tuple::make (3,4));
|
||||
two.storeTuple (make_tuple (3,4));
|
||||
CHECK (!isnil (two));
|
||||
CHECK (one != two);
|
||||
CHECK (two != one);
|
||||
|
||||
one.storeTuple (tuple::make (1,4));
|
||||
one.storeTuple (make_tuple (1,4));
|
||||
CHECK (!isnil (one));
|
||||
CHECK (one != two);
|
||||
CHECK (two != one);
|
||||
|
||||
one.storeTuple (tuple::make (3,4));
|
||||
one.storeTuple (make_tuple (3,4));
|
||||
CHECK (!isnil (one));
|
||||
CHECK (one == two);
|
||||
CHECK (two == one);
|
||||
|
|
@ -332,7 +333,7 @@ namespace test {
|
|||
|
||||
// store a set of parameter values, later to be used on invocation
|
||||
args.storeTuple (
|
||||
tuple::make (TTime(randTime()), Tstr("Lumiera rocks"), twoRandomDigits() ));
|
||||
make_tuple (TTime(randTime()), Tstr("Lumiera rocks"), twoRandomDigits() ));
|
||||
CHECK (!isnil (args));
|
||||
cout << args << endl;
|
||||
|
||||
|
|
@ -376,7 +377,7 @@ namespace test {
|
|||
protocol << "RESET...";
|
||||
|
||||
args.storeTuple (
|
||||
tuple::make (TTime(TimeValue(123456)), Tstr("unbelievable"), twoRandomDigits() ));
|
||||
make_tuple (TTime(TimeValue(123456)), Tstr("unbelievable"), twoRandomDigits() ));
|
||||
cout << "modified: " << args << endl;
|
||||
cout << "copied : " << argsCopy << endl; // holds still the old params & memento
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "proc/control/command-registry.hpp"
|
||||
#include "proc/control/argument-erasure.hpp"
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/p.hpp"
|
||||
|
|
@ -116,7 +116,7 @@ namespace test {
|
|||
bindRandArgument (CommandImpl& cmd)
|
||||
{
|
||||
typedef Types<int> ArgType;
|
||||
TypedArguments<Tuple<ArgType> > arg (tuple::make (rand() % 10000));
|
||||
TypedArguments<Tuple<ArgType>> arg (std::make_tuple (rand() % 10000));
|
||||
cmd.setArguments (arg);
|
||||
CHECK (cmd.canExec());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,13 +28,14 @@
|
|||
#include "proc/control/argument-erasure.hpp"
|
||||
#include "proc/control/command-argument-holder.hpp"
|
||||
#include "proc/control/memento-tie.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
namespace proc {
|
||||
namespace control {
|
||||
|
|
@ -50,6 +51,7 @@ namespace test {
|
|||
using std::function;
|
||||
using std::bind;
|
||||
using std::string;
|
||||
using std::make_tuple;
|
||||
|
||||
|
||||
|
||||
|
|
@ -81,9 +83,9 @@ namespace test {
|
|||
typedef function<Sig_capt> Fun_c;
|
||||
typedef function<Sig_undo> Fun_u;
|
||||
|
||||
typedef Tuple<Types<char> > ArgTuple;
|
||||
typedef Closure<Sig_oper> ArgHolder;
|
||||
typedef MementoTie<Sig_oper, string> MemHolder;
|
||||
using ArgTuple = Tuple<Types<char>>;
|
||||
using ArgHolder = Closure<Sig_oper>;
|
||||
using MemHolder = MementoTie<Sig_oper, string>;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -168,13 +170,13 @@ namespace test {
|
|||
void
|
||||
verifyClosureEquality()
|
||||
{
|
||||
ArgHolder a1 (tuple::make ('a'));
|
||||
ArgHolder a2 (tuple::make ('z'));
|
||||
ArgHolder a1 (make_tuple ('a'));
|
||||
ArgHolder a2 (make_tuple ('z'));
|
||||
CHECK (a1 == a1);
|
||||
CHECK (a1 != a2);
|
||||
CHECK (a2 != a1);
|
||||
|
||||
TypedArguments<ArgTuple> newArgs (tuple::make ('z'));
|
||||
TypedArguments<ArgTuple> newArgs (make_tuple ('z'));
|
||||
a1.bindArguments(newArgs);
|
||||
CHECK (a1 == a2);
|
||||
CHECK (a2 == a1);
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/command-argument-holder.hpp"
|
||||
#include "proc/control/memento-tie.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
|
@ -90,7 +90,8 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/** @test check the Mutation functor which is bound to our \c testFunc(int) .
|
||||
/** @test check the Mutation functor w#include "lib/meta/typelist.hpp"
|
||||
hich is bound to our \c testFunc(int) .
|
||||
* Then create a argument closure and use this to invoke the Mutation
|
||||
* and verify actually \c testFunc(param) is executed.
|
||||
*/
|
||||
|
|
@ -108,7 +109,7 @@ namespace test {
|
|||
VERIFY_ERROR (UNBOUND_ARGUMENTS, functor(nullClosure) );
|
||||
|
||||
// now create a real closure....
|
||||
Tuple<Types<int> > param = tuple::make(23);
|
||||
Tuple<Types<int> > param = std::make_tuple (23);
|
||||
Closure<void(int)> close_over (param);
|
||||
|
||||
CmdClosure& closure (close_over);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "lib/meta/function-closure.hpp"
|
||||
#include "meta/typelist-diagnostics.hpp"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace lib {
|
||||
namespace meta {
|
||||
|
|
@ -39,6 +40,8 @@ namespace test {
|
|||
using func::bindLast;
|
||||
using func::PApply;
|
||||
using func::BindToArgument;
|
||||
using std::make_tuple;
|
||||
using std::get;
|
||||
|
||||
|
||||
namespace { // test functions
|
||||
|
|
@ -178,17 +181,17 @@ namespace test {
|
|||
|
||||
// Version1: do a direct argument binding----------------- //
|
||||
|
||||
typedef std::_Placeholder<1> PH1; // tr1::function argument placeholders
|
||||
typedef std::_Placeholder<2> PH2;
|
||||
using PH1 = std::_Placeholder<1>; // tr1::function argument placeholders
|
||||
using PH2 = std::_Placeholder<2>;
|
||||
|
||||
PH1 ph1; // these empty structs are used to mark the arguments to be kept "open"
|
||||
PH2 ph2;
|
||||
Num<1> num18 (18); // ...and this value is for closing the first function argument
|
||||
|
||||
F23 fun_23 = std::bind (f, num18 // do the actual binding (i.e. close the first argument with a constant value)
|
||||
, ph1
|
||||
, ph2
|
||||
);
|
||||
F23 fun_23 = std::bind (f, num18 // do the actual binding (i.e. close the first argument with a constant value)
|
||||
, ph1
|
||||
, ph2
|
||||
);
|
||||
|
||||
int res = 0;
|
||||
res = fun_23 (_2_,_3_).o_; // and invoke the resulting functor ("closure"), providing the remaining arguments
|
||||
|
|
@ -198,13 +201,13 @@ namespace test {
|
|||
|
||||
// Version2: extract the binding arguments from a tuple--- //
|
||||
|
||||
typedef Tuple<Types<Num<1>, PH1, PH2> > PartialArg; // Tuple type to hold the binding values. Note the placeholder types
|
||||
PartialArg arg(num18); // Value for partial application (the placeholders are default constructed)
|
||||
using PartialArg = Tuple<Types<Num<1>, PH1, PH2>>; // Tuple type to hold the binding values. Note the placeholder types
|
||||
PartialArg arg(num18, PH1(), PH2()); // Value for partial application (the placeholders are default constructed)
|
||||
|
||||
fun_23 = std::bind (f, tuple::element<0>(arg) // now extract the values to bind from this tuple
|
||||
, tuple::element<1>(arg)
|
||||
, tuple::element<2>(arg)
|
||||
);
|
||||
fun_23 = std::bind (f, get<0>(arg) // now extract the values to bind from this tuple
|
||||
, get<1>(arg)
|
||||
, get<2>(arg)
|
||||
);
|
||||
res = 0;
|
||||
res = fun_23 (_2_,_3_).o_; // and invoke the resulting functor....
|
||||
CHECK (23 == res);
|
||||
|
|
@ -281,7 +284,7 @@ namespace test {
|
|||
|
||||
// Close the trailing 3 arguments of the 5-argument function...
|
||||
function<Sig54> fun_54 = PApply<Sig54321, Args2Close>::bindBack(fun15<5,4,3,2,1>,
|
||||
tuple::make(_3_,_2_,_1_)
|
||||
make_tuple(_3_,_2_,_1_)
|
||||
);
|
||||
|
||||
// apply the remaining argument values
|
||||
|
|
|
|||
|
|
@ -22,164 +22,68 @@
|
|||
|
||||
|
||||
/** @file tuple-diagnostics.hpp
|
||||
** an extension to typelist-diagnostics.hpp, allowing to dump the \em contents
|
||||
** of a Tuple datatype. Any type defining an operator string() may be printed
|
||||
** when used as Tuple member type; special formatting is provided for the
|
||||
** Num<int> test types, which makes typelist and tuples of these types
|
||||
** a good candidate for unit tests.
|
||||
**
|
||||
** @see type-tuple-test.cpp
|
||||
** @see typelist-manip-test.cpp
|
||||
** an extension to typelist-diagnostics.hpp, allowing to dump the \em contents of a Tuple datatype.
|
||||
** With the help of our [generic string converter](\ref util::toString), and the BuildTupleAccessor
|
||||
** defined within tuple-helper.hpp, we're able to show the type and contents of any data record
|
||||
** based on std::tuple. For unit-testing, special formatting is provided for the Num<int>
|
||||
** test types, which makes typelist and tuples of these types a good candidate for tests.
|
||||
**
|
||||
** @see TupleHelper_test
|
||||
** @see FunctionClosure_test
|
||||
** @see TypelistManip_test
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef META_TUPLE_DIAGNOSTICS_H
|
||||
#define META_TUPLE_DIAGNOSTICS_H
|
||||
|
||||
|
||||
#include "meta/typelist-diagnostics.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/format-obj.hpp"
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using boost::enable_if;
|
||||
using boost::lexical_cast;
|
||||
using util::unConst;
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace util {
|
||||
|
||||
template<int i>
|
||||
struct StringConv<lib::meta::Num<i>>
|
||||
{
|
||||
static std::string
|
||||
invoke (lib::meta::Num<i> num) noexcept
|
||||
{
|
||||
static util::_Fmt constElm("(%i)");
|
||||
static util::_Fmt changedElm("{%i}");
|
||||
|
||||
return string( (num.o_==i? constElm:changedElm) % int(num.o_));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace lib {
|
||||
namespace meta {
|
||||
namespace test {
|
||||
|
||||
|
||||
namespace { // Diagnostics
|
||||
|
||||
|
||||
|
||||
template<int i>
|
||||
string
|
||||
showTupElement(Num<i> o)
|
||||
{
|
||||
static util::_Fmt constElm("(%i)");
|
||||
static util::_Fmt changedElm("{%i}");
|
||||
|
||||
return string( (o.o_==i? constElm:changedElm) % int(o.o_));
|
||||
}
|
||||
|
||||
string
|
||||
showTupElement(int i)
|
||||
{
|
||||
return lexical_cast<string>(i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
string
|
||||
showTupElement(T x)
|
||||
{
|
||||
return string(x);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper template which acts as an "accessor".
|
||||
* Using the BuildTupleAccessor, we create a linear chain
|
||||
* of such TupleElementDisplayers as subclass of a given tuple type.
|
||||
* Here this technique is just used for dumping the tuples data fields,
|
||||
* but e.g. the control::Closure uses the same principle for manipulating
|
||||
* the individual datafields of an function argument tuple.
|
||||
*/
|
||||
template
|
||||
< typename TY
|
||||
, class BASE
|
||||
, class TUP
|
||||
, uint idx
|
||||
>
|
||||
class TupleElementDisplayer
|
||||
: public BASE
|
||||
{
|
||||
TY & element() { return BASE::template getAt<idx>(); }
|
||||
TY const& element() const { return unConst(this)->template getAt<idx>(); }
|
||||
|
||||
public:
|
||||
TupleElementDisplayer(TUP const& tuple) : BASE(tuple) {}
|
||||
|
||||
string
|
||||
dump (string const& prefix ="(") const
|
||||
{
|
||||
return BASE::dump (prefix+showTupElement(element())+",");
|
||||
}
|
||||
};
|
||||
|
||||
template<class TUP>
|
||||
class TupleElementDisplayer<NullType, TUP, TUP, 0>
|
||||
: public TUP
|
||||
{
|
||||
public:
|
||||
TupleElementDisplayer(TUP const& tuple) : TUP(tuple) {}
|
||||
|
||||
string
|
||||
dump (string const& prefix ="(") const
|
||||
{
|
||||
if (1 < prefix.length())
|
||||
// removing the trailing comma
|
||||
return prefix.substr (0, prefix.length()-1) +")";
|
||||
else
|
||||
return prefix+")";
|
||||
}
|
||||
};
|
||||
|
||||
} // (END) Diagnostics Helper
|
||||
|
||||
|
||||
|
||||
/* ===== printing Tuple types and contents ===== */
|
||||
|
||||
template<typename TYPES>
|
||||
enable_if< is_TuplePlain<Tuple<TYPES>>,
|
||||
string >
|
||||
showDump (Tuple<TYPES> const& tuple)
|
||||
{
|
||||
typedef BuildTupleAccessor<TYPES,TupleElementDisplayer> BuildAccessor;
|
||||
typedef typename BuildAccessor::Accessor Displayer;
|
||||
|
||||
return "...Tuple" + Displayer(tuple).dump();
|
||||
}
|
||||
|
||||
template<typename TYPES>
|
||||
enable_if< is_TupleListType<Tuple<TYPES>>,
|
||||
string >
|
||||
showDump (Tuple<TYPES> const& tuple)
|
||||
{
|
||||
typedef typename Types<TYPES>::Seq TypeSeq;
|
||||
Tuple<TypeSeq> plainTuple (tuple);
|
||||
|
||||
typedef BuildTupleAccessor<TypeSeq, TupleElementDisplayer> BuildAccessor;
|
||||
typedef typename BuildAccessor::Accessor Displayer;
|
||||
|
||||
return "...Tuple" + Displayer(plainTuple).dump();
|
||||
}
|
||||
|
||||
template<typename TUP>
|
||||
enable_if< is_TuplePlain<TUP>,
|
||||
string >
|
||||
inline enable_if<is_Tuple<TUP>,
|
||||
string >
|
||||
showType ()
|
||||
{
|
||||
typedef InstantiateChained<typename TUP::ArgList, Printer, NullP> DumpPrinter;
|
||||
return "TYPES-<>"
|
||||
+ DumpPrinter::print();
|
||||
}
|
||||
|
||||
template<typename TUP>
|
||||
enable_if< is_TupleListType<TUP>,
|
||||
string >
|
||||
showType ()
|
||||
{
|
||||
typedef InstantiateChained<typename TUP::ArgList, Printer, NullP> DumpPrinter;
|
||||
return "TYPES-[]"
|
||||
using TypeList = typename Types<TUP>::List;
|
||||
using DumpPrinter = InstantiateChained<TypeList, Printer, NullP>;
|
||||
|
||||
return "TUPLE"
|
||||
+ DumpPrinter::print();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
TypeTuple(Test) - checking type tuples and records based on them
|
||||
TupleHelper(Test) - verify helpers for working with tuples and type sequences
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
|
@ -21,12 +21,10 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file type-tuple-test.cpp
|
||||
** Interplay of typelists, type tuples and simple record
|
||||
** data types build on top of them.
|
||||
/** @file tuple-helpers-test.cpp
|
||||
** Interplay of typelists, type tuples and std::tuple.
|
||||
**
|
||||
** @see lib::meta::Tuple
|
||||
** @see tuple.hpp
|
||||
** @see tuple-helper.hpp
|
||||
** @see function-closure.hpp
|
||||
** @see control::CmdClosure real world usage example
|
||||
**
|
||||
|
|
@ -34,7 +32,7 @@
|
|||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "meta/typelist-diagnostics.hpp"
|
||||
#include "meta/tuple-diagnostics.hpp"
|
||||
|
||||
|
|
@ -71,33 +69,25 @@ namespace test {
|
|||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @test Cover various aspects of the type tuple.
|
||||
* Check the metaprogramming behaviour...
|
||||
* - build a tuple type from an existing typelist
|
||||
* - create sub tuple types and types with shifted parameters
|
||||
* Additionally, check the behaviour when creating tuple instances
|
||||
* at runtime. Effectively, these are simple record types, which
|
||||
* are synthesised by recursion over the related typelist.
|
||||
* - diagnostics through TupleAccessor retrieving stored values
|
||||
* - creating tuples by direct function call, providing values
|
||||
* - creating tuples partially from an existing sub-argument tuple
|
||||
* - copy and copy construct
|
||||
* - access the "head" and access values by numeric index
|
||||
* - create a tuple with shifted values
|
||||
* @test Cover various aspects of the integration of our type sequences
|
||||
* with the tuple type from the standard library
|
||||
* - verify our generic tuple access decorator
|
||||
* - TODO
|
||||
* @todo to be written
|
||||
*/
|
||||
class TypeTuple_test : public Test
|
||||
class TupleHelper_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
check_diagnostics();
|
||||
check_tuple_from_Typelist();
|
||||
check_sub_tuple_types();
|
||||
check_shiftedTuple();
|
||||
check_tuple_creation();
|
||||
check_build_from_subTuple();
|
||||
check_tuple_copy();
|
||||
check_value_access();
|
||||
// check_tuple_from_Typelist();
|
||||
// check_sub_tuple_types();
|
||||
// check_shiftedTuple();
|
||||
// check_tuple_creation();
|
||||
// check_build_from_subTuple();
|
||||
// check_tuple_copy();
|
||||
// check_value_access();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -117,7 +107,7 @@ namespace test {
|
|||
DISPLAY (L3);
|
||||
|
||||
typedef Tuple<Types1> Tup1;
|
||||
Tup1 tup1x (Num<1>(11));
|
||||
Tup1 tup1x (Num<1>(11), Num<3>(), Num<5>());
|
||||
|
||||
DISPLAY (Tup1); // prints the type
|
||||
DUMPVAL (Tup1()); // prints the contents
|
||||
|
|
@ -125,6 +115,7 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////OBSOLETE :: TICKET #988
|
||||
void
|
||||
check_tuple_from_Typelist()
|
||||
{
|
||||
|
|
@ -446,12 +437,13 @@ namespace test {
|
|||
TupT& tupXcast (tupX.tupleCast()); // (down)cast list-style to plain tuple
|
||||
DUMPVAL (tupXcast);
|
||||
}
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////OBSOLETE :: TICKET #988
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (TypeTuple_test, "unit meta");
|
||||
LAUNCHER (TupleHelper_test, "unit meta");
|
||||
|
||||
|
||||
|
||||
|
|
@ -185,8 +185,8 @@ namespace meta {
|
|||
/* ===== printing types and contents ===== */
|
||||
|
||||
template<typename TYPES>
|
||||
enable_if< is_Typelist<TYPES>,
|
||||
string >
|
||||
inline enable_if< is_Typelist<TYPES>,
|
||||
string >
|
||||
showType ()
|
||||
{
|
||||
typedef InstantiateChained<typename TYPES::List, Printer, NullP> DumpPrinter;
|
||||
|
|
@ -196,11 +196,11 @@ namespace meta {
|
|||
// Note: we define overloads of this function for other types, especially Tuples
|
||||
|
||||
|
||||
#define DISPLAY(NAME) \
|
||||
cout << STRINGIFY(NAME) << "\t:" << showType<NAME>() << endl;
|
||||
#define DISPLAY(_IT_) \
|
||||
cout << STRINGIFY(_IT_) << "\t:" << showType<_IT_>() << endl;
|
||||
|
||||
#define DUMPVAL(NAME) \
|
||||
cout << STRINGIFY(NAME) << "\t:" << showDump (NAME) << endl;
|
||||
#define DUMPVAL(_IT_) \
|
||||
cout << STRINGIFY(_IT_) << "\t:" << util::toString(_IT_) << endl;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue