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:
Fischlurch 2016-01-17 23:55:41 +01:00
parent 0e10ef09ec
commit f6d04d4d02
12 changed files with 259 additions and 250 deletions

View file

@ -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*/

View file

@ -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 {};

View file

@ -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>-

View file

@ -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));
}
};

View file

@ -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

View file

@ -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());
}

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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();
}

View file

@ -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");

View file

@ -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;