WIP rearranged some headers

This commit is contained in:
Fischlurch 2008-07-30 03:56:13 +02:00
parent 276ac8e082
commit 847cc9c267
16 changed files with 535 additions and 409 deletions

View file

@ -48,7 +48,7 @@
#include "common/p.hpp"
#include "common/query.hpp"
#include "common/typelistutil.hpp"
#include "common/meta/generator.hpp"
#include "common/singletonsubclass.hpp"
//TODO: is it sensible to bring in the types explicitly here? (it's not necessary, but may be convenient...)

View file

@ -0,0 +1,180 @@
/*
CONFIGFLAGS.hpp - Building classes based on configuration cases
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 configflags.hpp
** Under some circumstances it is necessary to assemble functionality
** out of elementary building blocks. Especially, this assembly can be
** expressed as template specialisations directed by a configuration type.
** Thus, the purpose of this header is to encode a flag-like configuraiton
** as distinct types, which can be used to select such specialisations.
** Each possible configuration can be encoded as a list of flags, which allows
** to generate, filter and process those configurations. The final goal is to
** automatically generate a factory which will deliver objects configured
** according to the configuration in question.
**
** @see proc::engine::config::Strategy usage example
** @see proc::engine::config::ConfigSelector
** @see typelist.hpp
**
*/
#ifndef LUMIERA_META_CONFIGFLAGS_H
#define LUMIERA_META_CONFIGFLAGS_H
#include "common/meta/typelist.hpp"
namespace lumiera {
namespace typelist {
template<char bit> struct Flag { typedef Flag ID; };
template<> struct Flag<0> { typedef NullType ID; };
template< char f1=0
, char f2=0
, char f3=0
, char f4=0
, char f5=0
>
struct Flags
{
typedef typename Types< typename Flag<f1>::ID
, typename Flag<f2>::ID
, typename Flag<f3>::ID
, typename Flag<f4>::ID
, typename Flag<f5>::ID
>::List
Tuple;
typedef Tuple List;
};
template< char f1=0
, char f2=0
, char f3=0
, char f4=0
, char f5=0
>
struct Config ///< distinct type representing a configuration
{
typedef typename Flags<f1,f2,f3,f4,f5>::Tuple Flags;
typedef Flags List;
};
template<char Fl, class CONF>
struct ConfigSetFlag; ///< set (prepend) the Flag to the given config
template< char Fl
, char f1
, char f2
, char f3
, char f4
, char IGN
>
struct ConfigSetFlag<Fl, Config<f1,f2,f3,f4,IGN> >
{
typedef Config<Fl,f1,f2,f3,f4> Config;
};
/** build a configuration type for the given list-of-flags */
template<class FLAGS, class CONF=Config<> >
struct DefineConfigByFlags
{
typedef CONF Config;
typedef Config Type;
};
template<char Fl, class FLAGS, class CONF>
struct DefineConfigByFlags< Node<Flag<Fl>,FLAGS>, CONF>
{
typedef typename ConfigSetFlag< Fl
, typename DefineConfigByFlags<FLAGS,CONF>::Config
>::Config Config;
typedef Config Type;
};
/**
* Helper for calculating values and for
* invoking runtime code based on a given FlagTuple.
* Can also be used on a Typelist of several Configs.
* The latter case is typically used to invoke an operation
* while ennumerating all Flag-Configurations defined in Code.
* An example would be to build (at runtime) an dispatcher table.
* Explanation: For the Case covering a List of Configs, we provide
* a templated visitaion function, which can accept a functor object
* to be invoked on each Configuration.
*/
template<class FLAGS>
struct FlagInfo;
template<char ff, class FLAGS>
struct FlagInfo<Node<Flag<ff>, FLAGS> >
{
enum{ BITS = MAX(ff, FlagInfo<FLAGS>::BITS)
, CODE = (1<<ff) | FlagInfo<FLAGS>::CODE
};
};
template<>
struct FlagInfo<NullType>
{
enum{ BITS = 0
, CODE = 0
};
template<class FUNC>
static typename FUNC::Ret
accept (FUNC& functor)
{
return functor.done();
}
};
template<class CONF, class TAIL>
struct FlagInfo<Node<CONF, TAIL> >
{
typedef typename CONF::Flags ThisFlags;
enum{ BITS = MAX (char(FlagInfo<ThisFlags>::BITS), char(FlagInfo<TAIL>::BITS))
};
template<class FUNC>
static typename FUNC::Ret
accept (FUNC& functor)
{
functor.template visit<CONF>(FlagInfo<ThisFlags>::CODE);
return FlagInfo<TAIL>::accept (functor);
}
};
} // namespace typelist
} // namespace lumiera
#endif

View file

@ -1,5 +1,5 @@
/*
TYPELISTUTIL.hpp - metaprogramming utilities for lists-of-types
GENERATOR.hpp - metaprogramming utilities for generating classes and interfaces
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -38,7 +38,7 @@ This code is heavily inspired by
*/
/** @file typelistutil.hpp
/** @file generator.hpp
** Helpers for working with lumiera::typelist::Types (i.e. lists-of-types).
** The main purpose is to build interfaces and polymorphic implementations
** (using virtual functions) based on templated Types or Collections of types,
@ -50,10 +50,10 @@ This code is heavily inspired by
*/
#ifndef LUMIERA_TYPELISTUTIL_H
#define LUMIERA_TYPELISTUTIL_H
#ifndef LUMIERA_META_GENERATOR_H
#define LUMIERA_META_GENERATOR_H
#include "common/typelist.hpp"
#include "common/meta/typelist.hpp"
@ -196,42 +196,6 @@ namespace lumiera
};
/**
* Metafunction counting the number of Types in the collection
*/
template<class TYPES>
struct count;
template<>
struct count<NullType>
{
enum{ value = 0 };
};
template<class TY, class TYPES>
struct count<Node<TY,TYPES> >
{
enum{ value = 1 + count<TYPES>::value };
};
/**
* Metafunction " max( sizeof(T) ) for T in TYPES "
*/
template<class TYPES>
struct maxSize;
template<>
struct maxSize<NullType>
{
enum{ value = 0 };
};
template<class TY, class TYPES>
struct maxSize<Node<TY,TYPES> >
{
enum{ thisval = sizeof(TY)
, nextval = maxSize<TYPES>::value
, value = nextval > thisval? nextval:thisval
};
};
} // namespace typelist
} // namespace lumiera

View file

@ -53,8 +53,8 @@ This code is heavily inspired by
*/
#ifndef LUMIERA_TYPELIST_H
#define LUMIERA_TYPELIST_H
#ifndef LUMIERA_META_TYPELIST_H
#define LUMIERA_META_TYPELIST_H

View file

@ -0,0 +1,213 @@
/*
TYPELISTUTIL.hpp - Utils for working with lists-of-types
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.
*/
#ifndef LUMIERA_META_TYPELISTUTIL_H
#define LUMIERA_META_TYPELISTUTIL_H
#include "common/meta/typelist.hpp"
namespace lumiera {
namespace typelist {
/**
* Metafunction counting the number of Types in the collection
*/
template<class TYPES>
struct count;
template<>
struct count<NullType>
{
enum{ value = 0 };
};
template<class TY, class TYPES>
struct count<Node<TY,TYPES> >
{
enum{ value = 1 + count<TYPES>::value };
};
/**
* Metafunction " max( sizeof(T) ) for T in TYPES "
*/
template<class TYPES>
struct maxSize;
template<>
struct maxSize<NullType>
{
enum{ value = 0 };
};
template<class TY, class TYPES>
struct maxSize<Node<TY,TYPES> >
{
enum{ thisval = sizeof(TY)
, nextval = maxSize<TYPES>::value
, value = nextval > thisval? nextval:thisval
};
};
/** apply a transformation (template) to each type in the list */
template<class TY, template<class> class _TRANS_>
struct Apply { typedef TY List; };
template< class TY, class TYPES
, template<class> class _TRANS_
>
struct Apply<Node<TY,TYPES>, _TRANS_ > { typedef Node< typename _TRANS_<TY>::Type
, typename Apply<TYPES,_TRANS_>::List
> List; };
template<bool, class T, class TAIL>
struct CondNode { typedef TAIL Next; };
template<class T, class TAIL>
struct CondNode<true, T, TAIL> { typedef Node<T,TAIL> Next; };
/** filter away those types which don't fulfill a predicate metafunction */
template< class TYPES
, template<class> class _P_ ///< a template providing a boolean member \c ::value
>
struct Filter;
template<template<class> class _P_>
struct Filter<NullType,_P_> { typedef NullType List; };
template< class TY, class TYPES
, template<class> class _P_
>
struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode< _P_<TY>::value
, TY
, typename Filter<TYPES,_P_>::List
>::Next
List; };
/** append lists-of-types */
template<class TY1, class TY2>
struct Append { typedef Node<TY1, typename Append<TY2,NullType>::List> List; };
template< class TY, class TYPES
, class TAIL
>
struct Append<Node<TY,TYPES>, TAIL> { typedef Node<TY, typename Append<TYPES, TAIL>::List> List; };
template<class TY, class TYPES>
struct Append<NullType, Node<TY,TYPES> > { typedef Node<TY,TYPES> List; };
template<class TY, class TYPES>
struct Append<Node<TY,TYPES>, NullType> { typedef Node<TY,TYPES> List; };
template<class TY1>
struct Append<TY1,NullType> { typedef Node<TY1,NullType> List; };
template<class TY2>
struct Append<NullType,TY2> { typedef Node<TY2,NullType> List; };
template<>
struct Append<NullType,NullType> { typedef NullType List; };
/**
* prefix each of the elements,
* yielding a list-of lists-of-types
*/
template<class T, class TY>
struct PrefixAll { typedef Node< typename Append<T,TY>::List, NullType> List; };
template<class T>
struct PrefixAll<T, NullType> { typedef NullType List; };
template<class T>
struct PrefixAll<T, NodeNull> { typedef Node< typename Append<T,NodeNull>::List, NullType> List; };
template< class T
, class TY, class TYPES
>
struct PrefixAll<T, Node<TY,TYPES> > { typedef Node< typename Append<T,TY>::List
, typename PrefixAll<T,TYPES>::List
> List; };
template<class TY1,class TY2>
struct Distribute { typedef typename PrefixAll<TY1,TY2>::List List; };
template<class TY>
struct Distribute<NullType,TY> { typedef NullType List; };
template< class TY, class TYPES
, class TAIL
>
struct Distribute<Node<TY,TYPES>,TAIL> { typedef typename Append< typename PrefixAll<TY,TAIL>::List
, typename Distribute<TYPES,TAIL>::List
>::List
List; };
/** use a permutation generator
* for creating a list of all possible combinations
*/
template< class X
, template<class> class _PERMU_>
struct Combine { typedef typename Distribute< typename _PERMU_<X>::List
, Node<NullType,NullType>
>::List List; };
template< template<class> class _PERMU_>
struct Combine<NullType, _PERMU_ > { typedef Node<NullType,NullType> List; };
template< class TY, class TYPES
, template<class> class _PERMU_>
struct Combine<Node<TY,TYPES>,_PERMU_> { typedef typename Distribute< typename _PERMU_<TY>::List
, typename Combine<TYPES,_PERMU_>::List
>::List List; };
/** permutation generator for the Combine metafunction,
* yielding an "on" and "off" case
*/
template<class F>
struct FlagOnOff
{
typedef Node<F, Node<NullType,NullType> > List;
};
/** generate all possible on-off combinations of the given flags */
template<class FLAGS>
struct CombineFlags
{
typedef typename Combine<FLAGS, FlagOnOff>::List List;
};
} // namespace typelist
} // namespace lumiera
#endif

74
src/common/meta/util.hpp Normal file
View file

@ -0,0 +1,74 @@
/*
UTIL.hpp - metaprogramming helpers and 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.
*/
#ifndef LUMIERA_META_UTIL_H
#define LUMIERA_META_UTIL_H
namespace lumiera {
namespace typelist {
/* types for figuring out the overload resolution chosen by the compiler */
typedef char Yes_t;
struct No_t { char padding[8]; };
/** semi-automatic detection if an instantiation is possible.
* Requires help by the template to be tested, which needs to define
* a typedef member \c is_defined. The embedded metafunction Test can be used
* as a predicate for filtering types which may yield a valid instantiation
* of the candidate template in question.
* \par
* A fully automated solution for this problem is impossible by theoretic reasons.
* Any non trivial use of such a \c is_defined trait would break the "One Definition Rule",
* as the state of any type can change from "partially defined" to "fully defined" over
* the course of any translation unit. Thus, even if there may be a \em solution out there,
* we can expect it to break at some point by improvements/fixes to the C++ Language.
*/
template<template<class> class _CandidateTemplate_>
struct Instantiation
{
template<class X>
class Test
{
typedef _CandidateTemplate_<X> Instance;
template<class U>
static Yes_t check(typename U::is_defined *);
template<class U>
static No_t check(...);
public:
static const bool value = (sizeof(Yes_t)==sizeof(check<Instance>(0)));
};
};
} // namespace typelist
} // namespace lumiera
#endif

View file

@ -41,7 +41,7 @@
#define LUMIERA_VARIANT_H
#include "common/typelistutil.hpp"
#include "common/meta/generator.hpp"
#include <boost/noncopyable.hpp>

View file

@ -79,7 +79,7 @@ Credits for many further implementation ideas go to
#include "common/visitorpolicies.hpp"
#include "common/visitordispatcher.hpp"
#include "common/typelist.hpp"
#include "common/meta/typelist.hpp"
namespace lumiera

View file

@ -29,7 +29,7 @@
#include "common/variant.hpp"
#include "common/accesscasted.hpp"
#include "common/typelist.hpp"
#include "common/meta/typelist.hpp"
#include "proc/mobject/placement.hpp"
#include "common/p.hpp"

View file

@ -62,7 +62,6 @@
#include "proc/engine/buffhandle.hpp"
#include "proc/engine/bufftable.hpp"
#include "proc/engine/nodeinvocation.hpp"
#include "proc/engine/nodewiringconfig.hpp"
@ -230,6 +229,18 @@ namespace engine {
/* === declare the possible Assembly of these elementary steps === */
enum Cases
{
CACHING = 1,
PROCESS,
INPLACE,
NOT_SET = 0,
NUM_Cases = INPLACE
};
template<char CACHE_Fl=0, char INPLACE_Fl=0>
struct SelectBuffProvider;

View file

@ -19,369 +19,49 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file nodewiringconfig.hpp
** Sometimes we need to coose a different implementation for dealing with
** some special cases. While for simple cases, just testing a flag or using a
** switch statement will do the job, matters get more difficult when we have to
** employ a completely different execution path for each of the different cases,
** while using a set of common building blocks.
** \par
** In the Lumiera render engine, right on the critical path, we need some glue code
** for invoking the predecessor nodes when pulling a given processing node. The actual
** sequence is quite dependant on the specific situation each node is wired up, regarding
** buffer allocation, cache querying and the possible support for GPU processing and
** render farms. The solution is to define specialisations of a Strategy template
** using the specific configuration as template argument. Based on these, we can
** create a collection of factories, which in turn will build the internal wiring
** for the individual ProcNode instances in accordance to the situation determined
** for this node, expressed as a set of flags. As a net result, each node has an
** indivudual configuration (as opposed to creating a lot of hand-written individual
** ProcNode subclasses), but parts of this configuration assembly is done already at
** compile time, allowing for additional checks by typing and for possible optimisation.
**
** @see proc::engine::config::Strategy
** @see nodewiring.hpp
** @see configflags.hpp
**
*/
#ifndef ENGINE_NODEWIRINGCONFIG_H
#define ENGINE_NODEWIRINGCONFIG_H
#include "common/util.hpp"
#include "common/meta/configflags.hpp"
//#include <cstddef>
#include <algorithm>
#include <vector>
#include <bitset>
#include <map>
#include <boost/scoped_ptr.hpp>
#include <boost/lexical_cast.hpp>
/////////////////TODO: library
#include "common/typelistutil.hpp"
namespace lumiera {
namespace typelist {
template<class TY, template<class> class _TRANS_>
struct Apply { typedef TY List; };
template< class TY, class TYPES
, template<class> class _TRANS_
>
struct Apply<Node<TY,TYPES>, _TRANS_ > { typedef Node< typename _TRANS_<TY>::Type
, typename Apply<TYPES,_TRANS_>::List
> List; };
template<bool, class T, class TAIL>
struct CondNode { typedef TAIL Next; };
template<class T, class TAIL>
struct CondNode<true, T, TAIL> { typedef Node<T,TAIL> Next; };
template< class TYPES , template<class> class _P_>
struct Filter;
template<template<class> class _P_>
struct Filter<NullType,_P_> { typedef NullType List; };
template< class TY, class TYPES
, template<class> class _P_
>
struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode< _P_<TY>::value
, TY
, typename Filter<TYPES,_P_>::List
>::Next
List; };
template<class TY1, class TY2>
struct Append { typedef Node<TY1, typename Append<TY2,NullType>::List> List; };
template< class TY, class TYPES
, class TAIL
>
struct Append<Node<TY,TYPES>, TAIL> { typedef Node<TY, typename Append<TYPES, TAIL>::List> List; };
template<class TY, class TYPES>
struct Append<NullType, Node<TY,TYPES> > { typedef Node<TY,TYPES> List; };
template<class TY, class TYPES>
struct Append<Node<TY,TYPES>, NullType> { typedef Node<TY,TYPES> List; };
template<class TY1>
struct Append<TY1,NullType> { typedef Node<TY1,NullType> List; };
template<class TY2>
struct Append<NullType,TY2> { typedef Node<TY2,NullType> List; };
template<>
struct Append<NullType,NullType> { typedef NullType List; };
template<class T, class TY>
struct PrefixAll { typedef Node< typename Append<T,TY>::List, NullType> List; };
template<class T>
struct PrefixAll<T, NullType> { typedef NullType List; };
template<class T>
struct PrefixAll<T, NodeNull> { typedef Node< typename Append<T,NodeNull>::List, NullType> List; };
template< class T
, class TY, class TYPES
>
struct PrefixAll<T, Node<TY,TYPES> > { typedef Node< typename Append<T,TY>::List
, typename PrefixAll<T,TYPES>::List
> List; };
template<class TY1,class TY2>
struct Distribute { typedef typename PrefixAll<TY1,TY2>::List List; };
template<class TY>
struct Distribute<NullType,TY> { typedef NullType List; };
template< class TY, class TYPES
, class TAIL
>
struct Distribute<Node<TY,TYPES>,TAIL> { typedef typename Append< typename PrefixAll<TY,TAIL>::List
, typename Distribute<TYPES,TAIL>::List
>::List
List; };
template< class X
, template<class> class _PERMU_>
struct Combine { typedef typename Distribute< typename _PERMU_<X>::List
, Node<NullType,NullType>
>::List List; };
template< template<class> class _PERMU_>
struct Combine<NullType, _PERMU_ > { typedef Node<NullType,NullType> List; };
template< class TY, class TYPES
, template<class> class _PERMU_>
struct Combine<Node<TY,TYPES>,_PERMU_> { typedef typename Distribute< typename _PERMU_<TY>::List
, typename Combine<TYPES,_PERMU_>::List
>::List List; };
template<class F>
struct FlagOnOff
{
typedef Node<F, Node<NullType,NullType> > List;
};
template<class FLAGS>
struct CombineFlags
{
typedef typename Combine<FLAGS, FlagOnOff>::List List;
};
/////////// meta utils
typedef char Yes_t;
struct No_t { char padding[8]; };
/** semi-automatic detection if an instantiation is possible.
* Requires help by the template to be tested, which needs to define
* a typedef member \c is_defined. The embedded metafunction Test can be used
* as a predicate for filtering types which may yield a valid instantiation
* of the candidate template in question.
* \par
* A fully automated solution for this problem is impossible by theoretic reasons.
* Any non trivial use of such a \c is_defined trait would break the "One Definition Rule",
* as the state of any type can change from "partially defined" to "fully defined" over
* the course of any translation unit. Thus, even if there may be a \em solution out there,
* we can expect it to break at some point by improvements/fixes to the C++ Language.
*/
template<template<class> class _CandidateTemplate_>
struct Instantiation
{
template<class X>
class Test
{
typedef _CandidateTemplate_<X> Instance;
template<class U>
static Yes_t check(typename U::is_defined *);
template<class U>
static No_t check(...);
public:
static const bool value = (sizeof(Yes_t)==sizeof(check<Instance>(0)));
};
};
template<char bit> struct Flag { typedef Flag ID; };
template<> struct Flag<0> { typedef NullType ID; };
template< char f1=0
, char f2=0
, char f3=0
, char f4=0
, char f5=0
>
struct Flags
{
typedef typename Types< typename Flag<f1>::ID
, typename Flag<f2>::ID
, typename Flag<f3>::ID
, typename Flag<f4>::ID
, typename Flag<f5>::ID
>::List
Tuple;
typedef Tuple List;
};
template< char f1=0
, char f2=0
, char f3=0
, char f4=0
, char f5=0
>
struct Config
{
typedef typename Flags<f1,f2,f3,f4,f5>::Tuple Flags;
typedef Flags List;
};
template<char Fl, class CONF>
struct ConfigSetFlag;
template< char Fl
, char f1
, char f2
, char f3
, char f4
, char IGN
>
struct ConfigSetFlag<Fl, Config<f1,f2,f3,f4,IGN> >
{
typedef Config<Fl,f1,f2,f3,f4> Config;
};
template<class FLAGS, class CONF=Config<> >
struct DefineConfigByFlags
{
typedef CONF Config;
typedef Config Type;
};
template<char Fl, class FLAGS, class CONF>
struct DefineConfigByFlags< Node<Flag<Fl>,FLAGS>, CONF>
{
typedef typename ConfigSetFlag< Fl
, typename DefineConfigByFlags<FLAGS,CONF>::Config
>::Config Config;
typedef Config Type;
};
/**
* Helper for calculating values and for
* invoking runtime code based on a given FlagTuple.
* Can also be used on a Typelist of several Configs.
* The latter case is typically used to invoke an operation
* while ennumerating all Flag-Configurations defined in Code.
* An example would be to build (at runtime) an dispatcher table.
* Explanation: For the Case covering a List of Configs, we provide
* a templated visitaion function, which can accept a functor object
* to be invoked on each Configuration.
*/
template<class FLAGS>
struct FlagInfo;
template<char ff, class FLAGS>
struct FlagInfo<Node<Flag<ff>, FLAGS> >
{
enum{ BITS = MAX(ff, FlagInfo<FLAGS>::BITS)
, CODE = (1<<ff) | FlagInfo<FLAGS>::CODE
};
};
template<>
struct FlagInfo<NullType>
{
enum{ BITS = 0
, CODE = 0
};
template<class FUNC>
static typename FUNC::Ret
accept (FUNC& functor)
{
return functor.done();
}
};
template<class CONF, class TAIL>
struct FlagInfo<Node<CONF, TAIL> >
{
typedef typename CONF::Flags ThisFlags;
enum{ BITS = MAX (char(FlagInfo<ThisFlags>::BITS), char(FlagInfo<TAIL>::BITS))
};
template<class FUNC>
static typename FUNC::Ret
accept (FUNC& functor)
{
functor.template visit<CONF>(FlagInfo<ThisFlags>::CODE);
return FlagInfo<TAIL>::accept (functor);
}
};
} // namespace typelist
} // namespace lumiera
/////////////////TODO: library(end)
#include <map>
namespace engine {
class WiringFactory;
///////TODO
using lumiera::typelist::Config;
using lumiera::typelist::FlagInfo;
using lumiera::typelist::DefineConfigByFlags;
///////TODO
using boost::lexical_cast;
using util::contains;
enum Cases
{
CACHING = 1,
PROCESS,
INPLACE,
NOT_SET = 0,
NUM_Cases = INPLACE
};
typedef std::bitset<NUM_Cases> Bits;
/**
* Helper type used to describe the \em situation on which to base
* the selection of the wiring and configuration of a ProcNode.
* It is based on a tuple of elementary parameters (here of type bool);
* a combination of these describes the situation and is used to select
* a strategy, which in turn determines what concret operations to use
* while pulling the node, and how to combine these operations.
* @see engine::Strategy ///TODO namespace....
*/
// template<bool caching, bool process, bool inplace>
// struct Config
// {
// static Bits getRepr () { return getCaseRepresentation(caching,process,inplace); }
// };
/**
* Helper for fabricating ProcNode Wiring configurations.
@ -439,7 +119,7 @@ namespace engine {
};
typedef boost::shared_ptr<FacFunctor> PFunc;
typedef std::tr1::shared_ptr<FacFunctor> PFunc;
typedef std::map<size_t, PFunc> ConfigTable;
ConfigTable possibleConfig_; ///< Table of factories

View file

@ -32,7 +32,7 @@ using boost::is_base_of;
#include <boost/type_traits/is_polymorphic.hpp>
#include "common/typelistutil.hpp"
#include "common/meta/generator.hpp"
using lumiera::typelist::NullType;
using lumiera::typelist::Node;
using lumiera::typelist::Types;

View file

@ -38,10 +38,10 @@
#include "common/test/run.hpp"
#include "common/typelistutil.hpp"
#include "common/meta/generator.hpp"
#include "common/meta/typelistutil.hpp"
#include "proc/engine/nodewiringconfig.hpp"
#include "common/util.hpp"
//#include "common/typelist/typelistmanip.hpp"
#include "proc/engine/nodewiringconfig.hpp" ///////////TODO move to configflags.hpp
#include <boost/format.hpp>
#include <iostream>
@ -343,6 +343,10 @@ namespace lumiera {
};
/** @test use the ConfigSelector template to build a set of factories,
* based on a set of configurations. Then invoke the apropriate
* factory by specifying the configuration bit code
*/
void check_ConfigSelector()
{
cout << "\n==== check_ConfigSelector()\n";

View file

@ -1,5 +1,5 @@
/*
TypeListUtil(Test) - check the typelist helpers
Generator(Test) - build an interface + implementation directed by a typelis
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -21,7 +21,7 @@
* *****************************************************/
/** @file typelistutiltest.cpp
/** @file generatortest.cpp
** \par what are we doing here??
**
** the following test composes both an interface and the corresponding implementation
@ -31,14 +31,14 @@
** need to be absolutely fixed in the class definition)
**
** @see typelisttest.cpp
** @see typelistutil.hpp
** @see generator.hpp
** @see lumiera::query::ConfigRules a real world usage example
**
*/
#include "common/test/run.hpp"
#include "common/typelistutil.hpp"
#include "common/meta/generator.hpp"
#include <boost/format.hpp>
#include <iostream>
@ -118,7 +118,7 @@ namespace lumiera
* for a collection of classes</li>
* </ul>
*/
class TypeListUtil_test : public Test
class TypeListGenerator_test : public Test
{
virtual void run(Arg arg)
{
@ -144,7 +144,7 @@ namespace lumiera
/** Register this test class... */
LAUNCHER (TypeListUtil_test, "unit common");
LAUNCHER (TypeListGenerator_test, "unit common");

View file

@ -39,9 +39,9 @@
#include "common/test/run.hpp"
#include "common/typelistutil.hpp"
#include "common/meta/generator.hpp"
#include "common/meta/typelistutil.hpp"
#include "common/util.hpp"
#include "proc/engine/nodewiringconfig.hpp" ///////////TODO move to typelistutil.hpp
#include <boost/format.hpp>
#include <iostream>

View file

@ -22,7 +22,7 @@
#include "common/test/run.hpp"
#include "common/typelist.hpp"
#include "common/meta/typelist.hpp"
#include <iostream>