got basic diagnostics for type tuples working

This commit is contained in:
Fischlurch 2009-06-20 23:18:02 +02:00
parent 294c254f29
commit ad7c326c9c
5 changed files with 210 additions and 30 deletions

View file

@ -49,6 +49,7 @@
#include "lib/meta/typelist.hpp"
#include "lib/meta/typelistutil.hpp"
#include "lib/meta/util.hpp"
@ -443,6 +444,17 @@ namespace typelist{
}
/** Trait template for detecting a type tuple */
template<typename TUP>
class is_Tuple
{
template<class X> struct Check { typedef No_t It; };
template<class TY> struct Check<Tuple<TY> > { typedef Yes_t It; };
public:
static const bool value = (sizeof(Yes_t)==sizeof(typename Check<TUP>::It));
};
/**

View file

@ -70,6 +70,24 @@ namespace lumiera {
};
/** Trait template for detecting a typelist type.
* For example, this allows to write specialisations with the help of
* boost::enable_if
*/
template<typename TY>
class is_Typelist
{
template<class X>
static Yes_t check(typename X::List *);
template<class>
static No_t check(...);
public:
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
};
} // namespace typelist
} // namespace lumiera

View file

@ -38,48 +38,152 @@
#include "lib/meta/typelist.hpp" ////////////TODO really?
#include "lib/meta/tuple.hpp"
#include "meta/typelist-diagnostics.hpp"
//#include "lib/util.hpp"
#include "lib/util.hpp"
//#include <boost/format.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/format.hpp>
#include <iostream>
using ::test::Test;
using boost::enable_if;
using boost::format;
using boost::str;
using util::unConst;
using std::string;
using std::cout;
using std::endl;
namespace lumiera {
namespace typelist{
namespace test {
namespace { // test data
typedef Types< Num<1>
, Num<2>
, Num<3>
>::List List1;
typedef Types< Num<5>
, Num<6>
, Num<7>
>::List List2;
template<class X> struct CountDown { typedef NullType List; };
template<> struct CountDown<Num<0> > { typedef Node<Num<0>, NullType> List; };
template<int I> struct CountDown<Num<I> > { typedef Node<Num<I>, typename CountDown<Num<I-1> >::List> List; };
, Num<5>
> Types1;
typedef Types< Num<2>
, Num<4>
> Types2;
typedef Types< Num<7> > Types3;
} // (End) test data
namespace { // Diagnostics
template<int i>
string
showTupElement(Num<i> o)
{
static format constElm("(%i)");
static format changedElm("{%i}");
return str ( (o.o_==i? constElm:changedElm) % int(o.o_));
}
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) {}
protected:
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>
string
showDump (Tuple<TYPES> const& tuple)
{
typedef BuildTupleAccessor<TYPES,TupleElementDisplayer> BuildAccessor;
typedef typename BuildAccessor::Accessor Displayer;
return " Tup" + Displayer(tuple).dump();
}
template<typename TUP>
typename enable_if< is_Tuple<TUP>,
string >::type
showType ()
{
typedef InstantiateChained<typename TUP::ArgList, Printer, NullP> DumpPrinter;
return "TYPES-<>"
+ DumpPrinter::print();
}
// see the macros DISPLAY and DUMPVAL defined in typelist-diagnostics.hpp
/*************************************************************************
* @test //////////////////////////////////////////
* - building combinations and permutations
@ -89,8 +193,32 @@ namespace test {
virtual void
run (Arg)
{
check_diagnostics();
UNIMPLEMENTED ("verify type tuples");
}
/** verify the test input data
* @see TypeListManipl_test#check_diagnostics()
* for an explanation of the DISPLAY macro
*/
void
check_diagnostics ()
{
typedef Types1::List L1;
typedef Types2::List L2;
typedef Types3::List L3;
DISPLAY (L1);
DISPLAY (L2);
DISPLAY (L3);
typedef Tuple<Types3> Tup3;
DISPLAY (Tup3);
DUMPVAL (Tup3());
}
};

View file

@ -38,11 +38,16 @@
#include "lib/meta/typelist.hpp"
#include "lib/meta/generator.hpp"
#include "lib/meta/util.hpp"
#include <boost/format.hpp>
#include <boost/utility/enable_if.hpp>
using std::string;
using boost::format;
using boost::enable_if;
namespace lumiera {
@ -54,8 +59,8 @@ namespace typelist{
char o_;
Numz (char x =0) : o_(x) { }
};
/** constant-wrapper type for debugging purposes,
* usable for generating lists of distinguishable types
*/
@ -80,7 +85,7 @@ namespace typelist{
struct Config;
/** helper for generating test lists */
template<class X> struct CountDown { typedef NullType List; };
template<> struct CountDown<Num<0> > { typedef Node<Num<0>, NullType> List; };
@ -88,6 +93,7 @@ namespace typelist{
namespace test { //< unit tests covering typelist manipulating templates
namespace { // hidden internals for diagnostics....
@ -165,17 +171,33 @@ namespace typelist{
};
#define DIAGNOSE(LIST) \
typedef InstantiateChained<LIST::List, Printer, NullP> Contents_##LIST;
#define DISPLAY(NAME) \
DIAGNOSE(NAME); cout << STRINGIFY(NAME) << "\t:" << Contents_##NAME::print() << "\n";
} // (End) internal defs
/* ===== printing types and contents ===== */
template<typename TYPES>
typename enable_if< is_Typelist<TYPES>,
string >::type
showType ()
{
typedef InstantiateChained<typename TYPES::List, Printer, NullP> DumpPrinter;
return DumpPrinter::print();
}
// Note: we define overloads of this function for other types, especially Tuples
#define DISPLAY(NAME) \
cout << STRINGIFY(NAME) << "\t:" << showType<NAME>() << "\n";
#define DUMPVAL(NAME) \
cout << STRINGIFY(NAME) << "\t:" << showDump (NAME) << "\n";
}}} // namespace lumiera::typelist::test
#endif

View file

@ -108,7 +108,7 @@ namespace test {
void
check_diagnostics ()
{
// Explanation: the DISPLAY macro expands as follows....
// Explanation: the DISPLAY macro results in the following definition....
typedef InstantiateChained<List1::List, Printer, NullP > Contents_List1;
cout << "List1" << "\t:" << Contents_List1::print() << "\n";