some header-renaming
This commit is contained in:
parent
006c29c625
commit
a565bfef73
10 changed files with 589 additions and 223 deletions
214
src/lib/meta/function-erasure.hpp
Normal file
214
src/lib/meta/function-erasure.hpp
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
FUNCTION-ERASURE.hpp - wrapping a functor object for inline storage while hiding the signature
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file function-erasure.hpp
|
||||
** Partial function application and building a complete function closure.
|
||||
** This is a small addendum to (and thin wrapper for) tr1/functional, supporting
|
||||
** the case when a function should be closed over (all) arguments, where especially
|
||||
** the parameter values to close on are provided as a tuple.
|
||||
**
|
||||
** @see control::CommandDef usage example
|
||||
** @see function.hpp
|
||||
** @see tuple.hpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LUMIERA_META_FUNCTION_ERASURE_H
|
||||
#define LUMIERA_META_FUNCTION_ERASURE_H
|
||||
|
||||
#include "lib/meta/typelist.hpp" /////////////TODO
|
||||
#include "lib/meta/generator.hpp" /////////////TODO
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
|
||||
#include <tr1/functional>
|
||||
|
||||
#include "lib/util.hpp" ////////////////////////TODO
|
||||
#include "lib/error.hpp"
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist{
|
||||
|
||||
using std::tr1::bind;
|
||||
//using std::tr1::placeholders::_1;
|
||||
//using std::tr1::placeholders::_2;
|
||||
using std::tr1::function;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generic wrapper carrying a function object
|
||||
* while hiding the actual function signature
|
||||
* @note not statically typesafe. Depending on
|
||||
* the actual embedded container type,
|
||||
* it \em might be run-time typesafe.
|
||||
*/
|
||||
template<class FH>
|
||||
struct FunErasure
|
||||
: FH
|
||||
{
|
||||
template<typename FUN>
|
||||
FunErasure (FUN const& functor)
|
||||
: FH(functor)
|
||||
{ }
|
||||
};
|
||||
|
||||
/**
|
||||
* Policy for FunErasure: store an embedded tr1::function
|
||||
* Using this policy allows to store arbitrary complex functor objects
|
||||
* embedded within a neutral container and retrieving them later type-safe.
|
||||
* The price to pay is vtable access and heap storage of function arguments.
|
||||
*/
|
||||
class StoreFunction
|
||||
{
|
||||
/** Helper: type erasure */
|
||||
struct Holder
|
||||
{
|
||||
enum { SIZE = sizeof(function<void(void)>) };
|
||||
char storage_[SIZE];
|
||||
virtual ~Holder() {}
|
||||
};
|
||||
|
||||
/** embedding the concrete functor object */
|
||||
template<typename SIG>
|
||||
struct FunctionHolder : Holder
|
||||
{
|
||||
typedef function<SIG> Functor;
|
||||
FunctionHolder (SIG& fun)
|
||||
{
|
||||
REQUIRE (SIZE >= sizeof(Functor));
|
||||
new(&storage_) Functor (fun);
|
||||
}
|
||||
~FunctionHolder()
|
||||
{
|
||||
get()->~Functor();
|
||||
}
|
||||
Functor&
|
||||
get()
|
||||
{
|
||||
return static_cast<Functor*> (&storage_);
|
||||
}
|
||||
};
|
||||
|
||||
/** embedded buffer actually holding
|
||||
* the concrete Functor object */
|
||||
Holder holder_;
|
||||
|
||||
public:
|
||||
template<typename SIG>
|
||||
StoreFunction (SIG& fun)
|
||||
{
|
||||
new(&holder_) FunctionHolder<SIG> (fun);
|
||||
}
|
||||
|
||||
template<typename SIG>
|
||||
function<SIG>&
|
||||
getFun ()
|
||||
{
|
||||
REQUIRE (INSTANCEOF (FunctionHolder<SIG>, &holder_));
|
||||
return static_cast<FunctionHolder<SIG>&> (holder_).get();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Policy for FunErasure: store a bare function pointer.
|
||||
* Using this policy allows to store a conventional function ptr,
|
||||
* while still being able to re-access it later with run-time typecheck.
|
||||
* The price to pay is vtable access.
|
||||
*/
|
||||
class StoreFunPtr
|
||||
{
|
||||
/** Helper: type erasure */
|
||||
struct Holder
|
||||
{
|
||||
void *fun_;
|
||||
virtual ~Holder() {}
|
||||
};
|
||||
|
||||
/** storing and retrieving concrete function ptr */
|
||||
template<typename SIG>
|
||||
struct FunctionHolder : Holder
|
||||
{
|
||||
FunctionHolder (SIG& fun)
|
||||
{
|
||||
fun_ = &fun;
|
||||
}
|
||||
SIG&
|
||||
get()
|
||||
{
|
||||
return reinterpret_cast<SIG*> (&fun_);
|
||||
}
|
||||
};
|
||||
|
||||
/** embedded container holding the pointer */
|
||||
Holder holder_;
|
||||
|
||||
public:
|
||||
template<typename SIG>
|
||||
StoreFunPtr (SIG& fun)
|
||||
{
|
||||
new(&holder_) FunctionHolder<SIG> (fun);
|
||||
}
|
||||
|
||||
template<typename SIG>
|
||||
function<SIG>&
|
||||
getFun ()
|
||||
{
|
||||
REQUIRE (INSTANCEOF (FunctionHolder<SIG>, &holder_));
|
||||
return static_cast<FunctionHolder<SIG>&> (holder_).get();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Policy for FunErasure: store an unchecked bare function pointer.
|
||||
* Using this policy allows to store a conventional function ptr,
|
||||
* and to retrieve it without overhead, but also without safety.
|
||||
*/
|
||||
class StoreUncheckedFunPtr
|
||||
{
|
||||
void *fun_;
|
||||
|
||||
public:
|
||||
template<typename SIG>
|
||||
StoreUncheckedFunPtr (SIG& fun)
|
||||
{
|
||||
fun_ = &fun;
|
||||
}
|
||||
|
||||
template<typename SIG>
|
||||
SIG&
|
||||
getFun ()
|
||||
{
|
||||
return reinterpret_cast<SIG*> (&fun_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace lumiera::typelist
|
||||
#endif
|
||||
|
|
@ -46,10 +46,12 @@ test_lib_SOURCES = \
|
|||
$(testlib_srcdir)/helloworldtest.cpp \
|
||||
$(testlib_srcdir)/lifecycletest.cpp \
|
||||
$(testlib_srcdir)/mainsuite.cpp \
|
||||
$(testlib_srcdir)/meta/typelisttest.cpp \
|
||||
$(testlib_srcdir)/meta/typelistmaniptest.cpp \
|
||||
$(testlib_srcdir)/meta/generatortest.cpp \
|
||||
$(testlib_srcdir)/meta/configflagstest.cpp \
|
||||
$(testlib_srcdir)/meta/typelist-test.cpp \
|
||||
$(testlib_srcdir)/meta/typelist-manip-test.cpp \
|
||||
$(testlib_srcdir)/meta/function-closure-test.cpp \
|
||||
$(testlib_srcdir)/meta/function-erasure-test.cpp \
|
||||
$(testlib_srcdir)/meta/generator-test.cpp \
|
||||
$(testlib_srcdir)/meta/config-flags-test.cpp \
|
||||
$(testlib_srcdir)/query/queryutilstest.cpp \
|
||||
$(testlib_srcdir)/removefromsettest.cpp \
|
||||
$(testlib_srcdir)/sanitizedidentifiertest.cpp \
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file configflagstest.cpp
|
||||
/** @file config-flags-test.cpp
|
||||
** \par build a type representing a single configuration defined by a set of flags
|
||||
**
|
||||
** The semi-automatic assembly of processing node invocation code utilises some
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
#include "lib/meta/generator.hpp"
|
||||
#include "lib/meta/typelistutil.hpp"
|
||||
#include "lib/meta/configflags.hpp"
|
||||
#include "meta/typelistdiagnostics.hpp"
|
||||
#include "meta/typelist-diagnostics.hpp"
|
||||
#include "proc/engine/nodewiringconfig.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -55,8 +55,8 @@ using std::cout;
|
|||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist {
|
||||
namespace test {
|
||||
namespace typelist{
|
||||
namespace test {
|
||||
|
||||
|
||||
namespace { // internal definitions
|
||||
|
|
@ -332,8 +332,4 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace typelist
|
||||
|
||||
} // namespace lumiera
|
||||
}}} // namespace lumiera::typelist::test
|
||||
90
tests/lib/meta/function-closure-test.cpp
Normal file
90
tests/lib/meta/function-closure-test.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
FunctionClosure(Test) - appending, mixing and filtering typelists
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file function-closure-test.cpp
|
||||
** bla
|
||||
**
|
||||
** @see function-closure.hpp
|
||||
** @see control::CmdClosure real world usage example
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using ::test::Test;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist{
|
||||
namespace test {
|
||||
|
||||
|
||||
namespace { // test data
|
||||
|
||||
} // (End) test data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* @test //////////////////////////////////////////
|
||||
* - building combinations and permutations
|
||||
*/
|
||||
class FunctionClosure_test : public Test
|
||||
{
|
||||
virtual void run(Arg arg)
|
||||
{
|
||||
check_distribute();
|
||||
check_combine();
|
||||
}
|
||||
|
||||
|
||||
void check_distribute()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void check_combine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (FunctionClosure_test, "unit common");
|
||||
|
||||
|
||||
|
||||
}}} // namespace lumiera::typelist::test
|
||||
90
tests/lib/meta/function-erasure-test.cpp
Normal file
90
tests/lib/meta/function-erasure-test.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
FunctionErasure(Test) - verify the wrapping of functor object with type erasure
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file function-erasure-test.cpp
|
||||
** bla
|
||||
**
|
||||
** @see control::FunErasure
|
||||
** @see command-mutation.hpp real world usage example
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/meta/function-erasure.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using ::test::Test;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist{
|
||||
namespace test {
|
||||
|
||||
|
||||
namespace { // test data
|
||||
|
||||
} // (End) test data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* @test //////////////////////////////////////////
|
||||
* - building combinations and permutations
|
||||
*/
|
||||
class FunctionErasure_test : public Test
|
||||
{
|
||||
virtual void run(Arg arg)
|
||||
{
|
||||
check_distribute();
|
||||
check_combine();
|
||||
}
|
||||
|
||||
|
||||
void check_distribute()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void check_combine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (FunctionErasure_test, "unit common");
|
||||
|
||||
|
||||
|
||||
}}} // namespace lumiera::typelist::test
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file generatortest.cpp
|
||||
/** @file generator-test.cpp
|
||||
** \par what are we doing here??
|
||||
**
|
||||
** the following test composes both an interface and the corresponding implementation
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
** in the list. (remember: normally the number and signature of all virtual functions
|
||||
** need to be absolutely fixed in the class definition)
|
||||
**
|
||||
** @see typelisttest.cpp
|
||||
** @see typelist-test.cpp
|
||||
** @see generator.hpp
|
||||
** @see lumiera::query::ConfigRules a real world usage example
|
||||
**
|
||||
|
|
@ -47,12 +47,9 @@ using std::string;
|
|||
using std::cout;
|
||||
|
||||
|
||||
namespace lumiera
|
||||
{
|
||||
namespace typelist
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
namespace lumiera {
|
||||
namespace typelist{
|
||||
namespace test {
|
||||
|
||||
/** template for generating lots of different test types */
|
||||
template<int I>
|
||||
|
|
@ -89,7 +86,7 @@ namespace lumiera
|
|||
virtual ~DoIt() { cout << "dtor DoIt<"<< X::name << " >\n";}
|
||||
public:
|
||||
void eat (X& x) { cout << x.talk() << "\n";}
|
||||
using BASE::eat; // prevent shaddowing
|
||||
using BASE::eat; // prevent shadowing
|
||||
};
|
||||
|
||||
typedef Types< Block<1>
|
||||
|
|
@ -148,8 +145,4 @@ namespace lumiera
|
|||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace typelist
|
||||
|
||||
} // namespace lumiera
|
||||
}}} // namespace lumiera::typelist::test
|
||||
162
tests/lib/meta/typelist-diagnostics.hpp
Normal file
162
tests/lib/meta/typelist-diagnostics.hpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
TYPELIST-DIAGNOSTICS - helper for testing the typelist based utilities
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file typelist-diagnostics.hpp
|
||||
** a Printer template usable for debugging the structure of a typelist built
|
||||
** upon some simple debugging-style types. Examples being a Num<int> template,
|
||||
** or the Flag type. A Printer type generated from this template provides
|
||||
** a static \c print() function returning a string visualising the structure
|
||||
** of the typelist provided as parameter to the Printer template.
|
||||
**
|
||||
** @see typelist-manip-test.cpp
|
||||
** @see config-flags-test.cpp
|
||||
**
|
||||
*/
|
||||
#ifndef META_TYPELIST_DIAGNOSTICS_H
|
||||
#define META_TYPELIST_DIAGNOSTICS_H
|
||||
|
||||
|
||||
#include "lib/meta/generator.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
using std::string;
|
||||
using boost::format;
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist{
|
||||
|
||||
/** constant-wrapper type for debugging purposes,
|
||||
* usable for generating lists of distinguishable types
|
||||
*/
|
||||
template<int I>
|
||||
struct Num
|
||||
{
|
||||
enum{ VAL=I };
|
||||
};
|
||||
|
||||
|
||||
/* some forwards used by config-flags-test.cpp */
|
||||
template<char bit> struct Flag;
|
||||
template< char f1
|
||||
, char f2
|
||||
, char f3
|
||||
, char f4
|
||||
, char f5
|
||||
>
|
||||
struct Config;
|
||||
|
||||
|
||||
|
||||
namespace test {
|
||||
namespace { // hidden internals
|
||||
|
||||
using boost::format;
|
||||
|
||||
format fmt ("-<%u>%s");
|
||||
|
||||
struct NullP
|
||||
{
|
||||
static string print () { return "-"; }
|
||||
};
|
||||
|
||||
/** debugging template,
|
||||
* printing the "number" used for instantiation on ctor call
|
||||
*/
|
||||
template<class NUM=NullType, class BASE=NullP>
|
||||
struct Printer;
|
||||
|
||||
template<class BASE>
|
||||
struct Printer<NullType, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print () { return str( fmt % "·" % BASE::print()); }
|
||||
};
|
||||
|
||||
template<class BASE, int I>
|
||||
struct Printer<Num<I>, BASE> ///< display the presence of a Num instance in the typelist
|
||||
: BASE
|
||||
{
|
||||
static string print () { return str( fmt % uint(Num<I>::VAL) % BASE::print()); }
|
||||
};
|
||||
|
||||
template<class BASE, char Fl>
|
||||
struct Printer<Flag<Fl>, BASE> ///< display the presence of a Flag in the typelist
|
||||
: BASE
|
||||
{
|
||||
static string print () { return str( fmt % uint(Fl) % BASE::print()); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** call the debug-print for a typelist
|
||||
* utilising the Printer template */
|
||||
template<class L>
|
||||
string
|
||||
printSublist ()
|
||||
{
|
||||
typedef InstantiateChained<L, Printer, NullP> SubList;
|
||||
return SubList::print();
|
||||
}
|
||||
|
||||
/** Specialisation for debug-printing of a nested sublist */
|
||||
template<class TY, class TYPES, class BASE>
|
||||
struct Printer<Node<TY,TYPES>, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print ()
|
||||
{
|
||||
typedef Node<TY,TYPES> List;
|
||||
return string("\n\t+--") + printSublist<List>()+"+"
|
||||
+ BASE::print();
|
||||
}
|
||||
};
|
||||
|
||||
template<char f1, char f2, char f3, char f4, char f5, class BASE>
|
||||
struct Printer<Config<f1,f2,f3,f4,f5>, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print ()
|
||||
{
|
||||
typedef typename Config<f1,f2,f3,f4,f5>::Flags FlagList;
|
||||
return string("\n\t+-Conf-[") + printSublist<FlagList>()+"]"
|
||||
+ BASE::print();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
}}} // namespace lumiera::typelist::test
|
||||
#endif
|
||||
|
|
@ -21,17 +21,17 @@
|
|||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file typelistmaniptest.cpp
|
||||
/** @file typelist-manip-test.cpp
|
||||
** \par checking the correct working of simple list manipulation metafunctions
|
||||
**
|
||||
** The semi-automatic assembly of processing node invocation code utilizes some
|
||||
** The semi-automatic assembly of processing node invocation code utilises some
|
||||
** metaprogramming magic built upon simple list manipulation. As template metaprogramming
|
||||
** is kind-of functional programming, most of this is done by recursion.
|
||||
** To check the correct working, this test uses some constant-wrapper types and a debugging
|
||||
** template which will print these constant numbers, thus allowing to verify in the output
|
||||
** if various lists of such constant-wrapper types were manipulated as expected.
|
||||
**
|
||||
** @see typelisttest.cpp
|
||||
** @see typelist-test.cpp
|
||||
** @see typelistutil.hpp
|
||||
** @see nodewiringconfig.hpp real world usage example
|
||||
**
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "lib/meta/generator.hpp"
|
||||
#include "lib/meta/typelistutil.hpp"
|
||||
#include "meta/typelistdiagnostics.hpp"
|
||||
#include "meta/typelist-diagnostics.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
|
@ -53,8 +53,8 @@ using std::cout;
|
|||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist {
|
||||
namespace test {
|
||||
namespace typelist{
|
||||
namespace test {
|
||||
|
||||
|
||||
namespace { // test data
|
||||
|
|
@ -69,7 +69,7 @@ namespace lumiera {
|
|||
, 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; };
|
||||
|
|
@ -91,7 +91,7 @@ namespace lumiera {
|
|||
* - append lists, single elements and NullType
|
||||
* in various combinations
|
||||
* - filtering out some types from a typelist by
|
||||
* using a "predicate template" (metafuction)
|
||||
* using a "predicate template" (metafunction)
|
||||
* - building combinations and permutations
|
||||
*/
|
||||
class TypeListManipl_test : public Test
|
||||
|
|
@ -224,7 +224,7 @@ namespace lumiera {
|
|||
typedef CombineFlags<List1::List> OnOff;
|
||||
DISPLAY (OnOff);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -234,8 +234,4 @@ namespace lumiera {
|
|||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace typelist
|
||||
|
||||
} // namespace lumiera
|
||||
}}} // namespace lumiera::typelist::test
|
||||
|
|
@ -30,12 +30,9 @@ using std::string;
|
|||
using std::cout;
|
||||
|
||||
|
||||
namespace lumiera
|
||||
{
|
||||
namespace typelist
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
namespace lumiera {
|
||||
namespace typelist{
|
||||
namespace test {
|
||||
|
||||
template<int I>
|
||||
struct Block
|
||||
|
|
@ -46,7 +43,7 @@ namespace lumiera
|
|||
{
|
||||
Zero() { cout << "- The End -"; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef Types< Block<1>
|
||||
, Block<2>
|
||||
|
|
@ -94,8 +91,4 @@ namespace lumiera
|
|||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace typelist
|
||||
|
||||
} // namespace lumiera
|
||||
}}} // namespace lumiera::typelist::test
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
TYPELISTDIAGNOSTICS - helper for testing the typelist based utilities
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
/** @file typelistdiagnostics.hpp
|
||||
** a Printer template usable for debugging the structure of a typelist built
|
||||
** upon some simple debugging-style types. Examples being a Num<int> template,
|
||||
** or the Flag type. A Printer type generated from this template provides
|
||||
** a static \c print() function returing a string visualizing the structure
|
||||
** of the typelist provided as parameter to the Printer template.
|
||||
**
|
||||
** @see typelistmaniptest.cpp
|
||||
** @see configflagstest.cpp
|
||||
**
|
||||
*/
|
||||
#ifndef META_TYPELISTDIAGNOSTICS_H
|
||||
#define META_TYPELISTDIAGNOSTICS_H
|
||||
|
||||
|
||||
#include "lib/meta/generator.hpp"
|
||||
|
||||
//#include "lib/meta/typelistutil.hpp"
|
||||
//#include "lib/meta/util.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
using std::string;
|
||||
using boost::format;
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace typelist {
|
||||
|
||||
/** constant-wrapper type for debugging purposes,
|
||||
* usable for generating lists of distinguishable types
|
||||
*/
|
||||
template<int I>
|
||||
struct Num
|
||||
{
|
||||
enum{ VAL=I };
|
||||
};
|
||||
|
||||
|
||||
/* some forwards used by configflagstest.cpp */
|
||||
template<char bit> struct Flag;
|
||||
template< char f1
|
||||
, char f2
|
||||
, char f3
|
||||
, char f4
|
||||
, char f5
|
||||
>
|
||||
struct Config;
|
||||
|
||||
|
||||
|
||||
namespace test {
|
||||
namespace { // internal definitions
|
||||
|
||||
using boost::format;
|
||||
|
||||
format fmt ("-<%u>%s");
|
||||
|
||||
struct NullP
|
||||
{
|
||||
static string print () { return "-"; }
|
||||
};
|
||||
|
||||
/** debugging template,
|
||||
* printing the "number" used for intantiation on ctor call
|
||||
*/
|
||||
template<class NUM=NullType, class BASE=NullP>
|
||||
struct Printer;
|
||||
|
||||
template<class BASE>
|
||||
struct Printer<NullType, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print () { return str( fmt % "·" % BASE::print()); }
|
||||
};
|
||||
|
||||
template<class BASE, int I>
|
||||
struct Printer<Num<I>, BASE> ///< display the presence of a Num instance in the typelist
|
||||
: BASE
|
||||
{
|
||||
static string print () { return str( fmt % uint(Num<I>::VAL) % BASE::print()); }
|
||||
};
|
||||
|
||||
template<class BASE, char Fl>
|
||||
struct Printer<Flag<Fl>, BASE> ///< display the presence of a Flag in the typelist
|
||||
: BASE
|
||||
{
|
||||
static string print () { return str( fmt % uint(Fl) % BASE::print()); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** call the debug-print for a typelist
|
||||
* utilizing the Printer template */
|
||||
template<class L>
|
||||
string
|
||||
printSublist ()
|
||||
{
|
||||
typedef InstantiateChained<L, Printer, NullP> SubList;
|
||||
return SubList::print();
|
||||
}
|
||||
|
||||
/** Spezialisation for debug-printing of a nested sublist */
|
||||
template<class TY, class TYPES, class BASE>
|
||||
struct Printer<Node<TY,TYPES>, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print ()
|
||||
{
|
||||
typedef Node<TY,TYPES> List;
|
||||
return string("\n\t+--") + printSublist<List>()+"+"
|
||||
+ BASE::print();
|
||||
}
|
||||
};
|
||||
|
||||
template<char f1, char f2, char f3, char f4, char f5, class BASE>
|
||||
struct Printer<Config<f1,f2,f3,f4,f5>, BASE>
|
||||
: BASE
|
||||
{
|
||||
static string print ()
|
||||
{
|
||||
typedef typename Config<f1,f2,f3,f4,f5>::Flags FlagList;
|
||||
return string("\n\t+-Conf-[") + printSublist<FlagList>()+"]"
|
||||
+ BASE::print();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace typelist
|
||||
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
Loading…
Reference in a new issue