From e61097b8881bc7e72a5499816cb1199ea274a3ca Mon Sep 17 00:00:00 2001 From: Sebastien Braun Date: Thu, 7 Oct 2010 22:54:10 +0200 Subject: Rework template meta-magic - No more implicit dependency on Boost.MPL - Better documentation for template magic - Move input handler policies to handler definitions where they belong - Separate out event descriptions from handlers --- src/input/detail/Makefile.autogen | 8 +++ src/input/detail/gen/gen_policyChain.cpp | 68 ++++++++++++++++++ src/input/detail/gen/gen_typeList.cpp | 115 +++++++++++++++++++++++++++++++ src/input/detail/policyChain.h | 78 +++++++++++++++++++++ src/input/detail/policyChain_autogen.h | 8 +++ src/input/detail/systemTraits.h | 94 +++++++++++++++++++++++++ src/input/detail/typeList.h | 76 ++++++++++++++++++++ src/input/detail/typeList_autogen.h | 60 ++++++++++++++++ 8 files changed, 507 insertions(+) create mode 100644 src/input/detail/Makefile.autogen create mode 100644 src/input/detail/gen/gen_policyChain.cpp create mode 100644 src/input/detail/gen/gen_typeList.cpp create mode 100644 src/input/detail/policyChain.h create mode 100644 src/input/detail/policyChain_autogen.h create mode 100644 src/input/detail/systemTraits.h create mode 100644 src/input/detail/typeList.h create mode 100644 src/input/detail/typeList_autogen.h (limited to 'src/input/detail') diff --git a/src/input/detail/Makefile.autogen b/src/input/detail/Makefile.autogen new file mode 100644 index 0000000..6d0bfb3 --- /dev/null +++ b/src/input/detail/Makefile.autogen @@ -0,0 +1,8 @@ +all : policyChain_autogen.h typeList_autogen.h +.PHONY : all + +policyChain_autogen.h : gen/gen_policyChain + gen/gen_policyChain > policyChain_autogen.h + +typeList_autogen.h : gen/gen_typeList + gen/gen_typeList > typeList_autogen.h diff --git a/src/input/detail/gen/gen_policyChain.cpp b/src/input/detail/gen/gen_policyChain.cpp new file mode 100644 index 0000000..3e375ec --- /dev/null +++ b/src/input/detail/gen/gen_policyChain.cpp @@ -0,0 +1,68 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # detail/gen/gen_policyChain.cpp: + # - generate the input_policy::detail::PolicyChain class + # -------------------------------------------------------------------------- + */ + +#include + +using namespace std; + +#define NUM_POLICIES 8 + +int main(int, char**) +{ + int i; + + cout << "template\nstruct PolicyChain :\npublic P0::template apply_ >\n"; + cout << "{};\n"; + + // Base case: + cout << "template\n"; + cout << "struct PolicyChain : public BaseCase {};\n"; + + // We need the following in macros: + cout << "#define _autogen_POLICY_TEMPLATE_PARAMS "; + for(i = 0; i < NUM_POLICIES; i++) + { + if(i) + cout << ", "; + cout << "typename P" << i; + } + + cout << "\n#define _autogen_POLICY_TEMPLATE_ARGS "; + for(i = 0; i < NUM_POLICIES; i++) + { + if(i) + cout << ", "; + cout << "P" << i; + } + cout << "\n"; + + return 0; +} diff --git a/src/input/detail/gen/gen_typeList.cpp b/src/input/detail/gen/gen_typeList.cpp new file mode 100644 index 0000000..e092b80 --- /dev/null +++ b/src/input/detail/gen/gen_typeList.cpp @@ -0,0 +1,115 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # detail/gen/gen_policyChain.cpp: + # - generate the input_policy::detail::TypeList class + # -------------------------------------------------------------------------- + */ + +#include + +using namespace std; + +#define NUM_MAX_ENTRIES 16 + +int main(int, char**) +{ + int i; + + cout << "template<"; + for(i = 0; i < NUM_MAX_ENTRIES; i++) + { + if(i) + cout << ", "; + cout << "typename T" << i << " = void"; + } + cout << ">\nstruct TypeList {\n"; + cout << "typedef T0 head;\n"; + cout << "typedef TypeList<"; + for(i = 1; i < NUM_MAX_ENTRIES; i++) + { + if(i > 1) + cout << ", "; + cout << "T" << i; + } + cout << ", void > tail;\n"; + cout << "};\n"; + + // Contains: + cout << "template\n" + "struct Contains { static const int index = -1; static const bool value = false; };\n"; + + for(i = 0; i < NUM_MAX_ENTRIES; i++) + { + int j; + + cout << "template\nstruct Contains >\n{ static const int index = " << i << "; static const bool value = true; };\n"; + } + + // Empty List: + cout << "typedef TypeList<"; + for(i = 0; i < NUM_MAX_ENTRIES; i++) + { + if(i) + cout << ", "; + cout << "void"; + } + cout << " > EmptyList;\n"; + + // Macros: + cout << "#define IMPLICIT_TYPE_LIST_PARAMS(prefix) "; + for(i = 0; i < NUM_MAX_ENTRIES; i++) + { + if(i) + cout << ", "; + cout << "typename prefix##" << i << " = void"; + } + cout << "\n"; + + cout << "#define IMPLICIT_TYPE_LIST_PARAMS_NODEFAULT(prefix) "; + for(i = 0; i < NUM_MAX_ENTRIES; i++) + { + if(i) + cout << ", "; + cout << "typename prefix##" << i; + } + cout << "\n"; + + cout << "#define IMPLICIT_TYPE_LIST_ARGS(prefix) "; + for(i = 0; i < NUM_MAX_ENTRIES; i++) + { + if(i) + cout << ", "; + cout << "prefix##" << i; + } + cout << "\n"; + + cout << "#define IMPLICIT_TYPE_LIST(prefix) ::input_policy::detail::TypeList\n"; + + return 0; +} diff --git a/src/input/detail/policyChain.h b/src/input/detail/policyChain.h new file mode 100644 index 0000000..ae01ff2 --- /dev/null +++ b/src/input/detail/policyChain.h @@ -0,0 +1,78 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # detail/policyChain.h: + # - Tie together the different bits of policy information a handler may + # give us + # -------------------------------------------------------------------------- + */ + +#ifndef POLICYCHAIN_H_ +#define POLICYCHAIN_H_ + +#include "typeList.h" + +namespace input_policy +{ +namespace detail +{ + +template +struct PolicyChain : public PolicyList::head::template apply_ > +{ +}; + +template +struct PolicyChain : public BaseCase +{ +private: + struct This_Should_Not_Work; +public: + static const int test_value = sizeof(This_Should_Not_Work); +}; + +} +} + +///////////////////////////////////////////////////////////////////////// +// Macros that enable specification of policies: +// A policy is declared like this: +// template< PARAM1, PARAM2, ... > +// BEGIN_POLICY_CLASS(MyPolicy) { +// static const int field1 = 2; +// ... +// } END_POLICY_CLASS(MyPolicy); +///////////////////////////////////////////////////////////////////////// +#define BEGIN_POLICY_CLASS(policyName) \ + struct policyName { \ + template \ + struct apply_ : public NextPolicy +#define END_POLICY_CLASS \ + ; }; + +///////////////////////////////////////////////////////////////////////// +// A macro that enables us to use a template parameter list +// in a class using a policy, like this: +// +// template +// struct MyPolicyBasedClass +// { +// typedef USE_POLICY(baseCase) policy_type; +// }; +// +// now, the following type is valid: +// MyPolicyBasedClass +///////////////////////////////////////////////////////////////////////// +#define POLICY_PARAMS IMPLICIT_TYPE_LIST_PARAMS(Policy) +#define POLICY_PARAMS_LIST IMPLICIT_TYPE_LIST(Policy) +#define USE_POLICY(baseCase) ::input_policy::detail::PolicyChain + +#endif /* POLICYCHAIN_H_ */ diff --git a/src/input/detail/policyChain_autogen.h b/src/input/detail/policyChain_autogen.h new file mode 100644 index 0000000..d9503b8 --- /dev/null +++ b/src/input/detail/policyChain_autogen.h @@ -0,0 +1,8 @@ +template +struct PolicyChain : +public P0::template apply_ > +{}; +template +struct PolicyChain : public BaseCase {}; +#define _autogen_POLICY_TEMPLATE_PARAMS typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7 +#define _autogen_POLICY_TEMPLATE_ARGS P0, P1, P2, P3, P4, P5, P6, P7 diff --git a/src/input/detail/systemTraits.h b/src/input/detail/systemTraits.h new file mode 100644 index 0000000..7f5582f --- /dev/null +++ b/src/input/detail/systemTraits.h @@ -0,0 +1,94 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # detail/systemTraits.h: + # - Define system traits and provide a way to match against them + # -------------------------------------------------------------------------- + */ + +#ifndef SYSTEMTRAITS_H_ +#define SYSTEMTRAITS_H_ + +#include "typeList.h" + +#define DEFINE_SYSTEM_TRAIT(name) struct name; +#define BEGIN_SYSTEM_TRAITS typedef TypeList< +#define END_SYSTEM_TRAITS > SystemTraits; + +namespace input_policy +{ + +// Trait names are externally visible. +DEFINE_SYSTEM_TRAIT(UnixLike) +DEFINE_SYSTEM_TRAIT(LinuxSystem) +DEFINE_SYSTEM_TRAIT(X11GUI) +DEFINE_SYSTEM_TRAIT(ConsoleKitSupported) + +namespace detail +{ +BEGIN_SYSTEM_TRAITS +#ifdef __linux +UnixLike, +LinuxSystem, +X11GUI, +ConsoleKitSupported +#endif +END_SYSTEM_TRAITS +} + +///////////////////////////////////////////////////////////////////////// +// Boolean logic as applied to system traits +///////////////////////////////////////////////////////////////////////// +template +struct AllOf; + +template +struct AnyOf; + +namespace detail +{ +///////////////////////////////////////////////////////////////////////// +// Does the list of system traits match what we have given? +///////////////////////////////////////////////////////////////////////// +template +struct Matches +{ + // if Needles is neither AnyOf<...> nor AllOf<...> + // then we need to know if the Haystack contains it: + static const bool value = Contains::value; +}; + +template +struct MatchesPredicate +{ + template + struct apply + { + static const bool value = Matches::value; + }; +}; + +template +struct Matches, Haystack> +{ + static const bool value = ForAnyInTypeList, IMPLICIT_TYPE_LIST(T)>::value; +}; + +template +struct Matches, Haystack> +{ + static const bool value = ForAllInTypeList, IMPLICIT_TYPE_LIST(T)>::value; +}; +} + +} + +#endif /* SYSTEMTRAITS_H_ */ diff --git a/src/input/detail/typeList.h b/src/input/detail/typeList.h new file mode 100644 index 0000000..5b915a9 --- /dev/null +++ b/src/input/detail/typeList.h @@ -0,0 +1,76 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # detail/typeList.h: + # - Compile-time metaprogramming facilities: Type Lists and Member Check + # -------------------------------------------------------------------------- + */ + +#ifndef TYPELIST_H_ +#define TYPELIST_H_ + +namespace input_policy +{ +namespace detail +{ + +///////////////////////////////////////////////////////////////////////// +// TypeList, Contains, EmptyList: +// This class is autogenerated by gen/gen_typeList.cpp +///////////////////////////////////////////////////////////////////////// +#include "typeList_autogen.h" + +///////////////////////////////////////////////////////////////////////// +// Type-level functions that do not need to be autogenerated as they +// do not depend on the maximum number of entries: +// +// ForAnyInTypeList::value == true +// if there is any entry E in List for which +// Predicate::apply::value == true +///////////////////////////////////////////////////////////////////////// +template +struct ForAnyInTypeList +{ + static const bool value = + Predicate::template apply::value || + ForAnyInTypeList::value; +}; + +template +struct ForAnyInTypeList +{ + static const bool value = false; +}; + +///////////////////////////////////////////////////////////////////////// +// ForAllInTypeList::value == true +// if there is not any entry E in List for which +// Predicate::apply::value == false +///////////////////////////////////////////////////////////////////////// +template +struct ForAllInTypeList +{ + static const bool value = + Predicate::template apply::value && + ForAllInTypeList::value; +}; + +template +struct ForAllInTypeList +{ + static const bool value = true; +}; + +} + +} + +#endif /* TYPELIST_H_ */ diff --git a/src/input/detail/typeList_autogen.h b/src/input/detail/typeList_autogen.h new file mode 100644 index 0000000..0f8fdd4 --- /dev/null +++ b/src/input/detail/typeList_autogen.h @@ -0,0 +1,60 @@ +template +struct TypeList { +typedef T0 head; +typedef TypeList tail; +}; +template +struct Contains { static const int index = -1; static const bool value = false; }; +template +struct Contains > +{ static const int index = 0; static const bool value = true; }; +template +struct Contains > +{ static const int index = 1; static const bool value = true; }; +template +struct Contains > +{ static const int index = 2; static const bool value = true; }; +template +struct Contains > +{ static const int index = 3; static const bool value = true; }; +template +struct Contains > +{ static const int index = 4; static const bool value = true; }; +template +struct Contains > +{ static const int index = 5; static const bool value = true; }; +template +struct Contains > +{ static const int index = 6; static const bool value = true; }; +template +struct Contains > +{ static const int index = 7; static const bool value = true; }; +template +struct Contains > +{ static const int index = 8; static const bool value = true; }; +template +struct Contains > +{ static const int index = 9; static const bool value = true; }; +template +struct Contains > +{ static const int index = 10; static const bool value = true; }; +template +struct Contains > +{ static const int index = 11; static const bool value = true; }; +template +struct Contains > +{ static const int index = 12; static const bool value = true; }; +template +struct Contains > +{ static const int index = 13; static const bool value = true; }; +template +struct Contains > +{ static const int index = 14; static const bool value = true; }; +template +struct Contains > +{ static const int index = 15; static const bool value = true; }; +typedef TypeList EmptyList; +#define IMPLICIT_TYPE_LIST_PARAMS(prefix) typename prefix##0 = void, typename prefix##1 = void, typename prefix##2 = void, typename prefix##3 = void, typename prefix##4 = void, typename prefix##5 = void, typename prefix##6 = void, typename prefix##7 = void, typename prefix##8 = void, typename prefix##9 = void, typename prefix##10 = void, typename prefix##11 = void, typename prefix##12 = void, typename prefix##13 = void, typename prefix##14 = void, typename prefix##15 = void +#define IMPLICIT_TYPE_LIST_PARAMS_NODEFAULT(prefix) typename prefix##0, typename prefix##1, typename prefix##2, typename prefix##3, typename prefix##4, typename prefix##5, typename prefix##6, typename prefix##7, typename prefix##8, typename prefix##9, typename prefix##10, typename prefix##11, typename prefix##12, typename prefix##13, typename prefix##14, typename prefix##15 +#define IMPLICIT_TYPE_LIST_ARGS(prefix) prefix##0, prefix##1, prefix##2, prefix##3, prefix##4, prefix##5, prefix##6, prefix##7, prefix##8, prefix##9, prefix##10, prefix##11, prefix##12, prefix##13, prefix##14, prefix##15 +#define IMPLICIT_TYPE_LIST(prefix) ::input_policy::detail::TypeList -- cgit v1.2.3-55-g7522