diff --git a/src/lib/meta/util.hpp b/src/lib/meta/util.hpp index e8a6e533f..4988b7600 100644 --- a/src/lib/meta/util.hpp +++ b/src/lib/meta/util.hpp @@ -38,14 +38,29 @@ #define LIB_META_UTIL_H -#include +#include + +namespace std { // forward declaration for std::string... + + template + struct char_traits; + + template + class allocator; + + template + class basic_string; + + using string = basic_string, allocator>; +} + namespace lib { namespace meta { - /* types for figuring out the overload resolution chosen by the compiler */ + /** helper types to detect the overload resolution chosen by the compiler */ typedef char Yes_t; struct No_t { char more_than_one[4]; }; @@ -53,29 +68,12 @@ namespace meta { - /** Compile-time Type equality: - * Simple Trait template to pick up types considered - * \em identical by the compiler. - * @warning identical, not sub-type! - */ - template - struct is_sameType - { - static const bool value = false; - }; - - template - struct is_sameType - { - static const bool value = true; - }; - /** detect possibility of a conversion to string. * Naive implementation just trying the direct conversion. * The embedded constant #value will be true in case this succeeds. * Might fail in more tricky situations (references, const, volatile) - * @see \ref format-conv.hpp more elaborate solution including lexical_cast + * @see \ref format-obj.hpp more elaborate solution including lexical_cast */ template struct can_convertToString @@ -120,37 +118,6 @@ namespace meta { - /** 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. - * @remarks - * 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 class _CandidateTemplate_> - struct Instantiation - { - - template - class Test - { - typedef _CandidateTemplate_ Instance; - - template - static Yes_t check(typename U::is_defined *); - template - static No_t check(...); - - public: - static const bool value = (sizeof(Yes_t)==sizeof(check(0))); - }; - }; - /** Trait template for detecting a typelist type. * For example, this allows to write specialisations with the help of diff --git a/src/lib/time/control-policy.hpp b/src/lib/time/control-policy.hpp index c29a58d36..a0fdb3b82 100644 --- a/src/lib/time/control-policy.hpp +++ b/src/lib/time/control-policy.hpp @@ -32,11 +32,11 @@ ** The header control-impl.hpp defines the building blocks for time::Control ** and then includes this header here to get the concrete template specialisations ** for time::mutation::Policy. This policy class is templated by time entity types - ** - for \c TI, the \em nominal value type used on the time::Control interface - ** - for \c SRC, the actual type of values to impose as \em change + ** - for \c TI, the _nominal_ value type used on the time::Control interface + ** - for \c SRC, the actual type of values to impose _as change_ ** - for \c TAR, the target time value's type, receiving those changes. ** - ** \par mutating a time value entity + ** ## mutating a time value entity ** ** Actually imposing a change to the attached time value entity involves several ** steps. Each of these steps might be adapted specifically, in accordance to @@ -55,26 +55,26 @@ ** point of the time interval given by the TimeSpan. ** ** Incoming changes might be of any of the aforementioned types, and in addition, - ** we might receive \em nudging, which means to increment or decrement the target + ** we might receive *nudging*, which means to increment or decrement the target ** time value in discrete steps. After maybe adapting these incoming change values, - ** they may be actually \em imposed to the target. In all cases, this is delegated + ** they may be actually _imposed_ on the target. In all cases, this is delegated ** to the time::Mutation base class, which is declared fried to TimeValue and thus ** has the exceptional ability to manipulate time values, which otherwise are defined ** to be immutable. Additionally, these protected functions in the time::Mutation - ** baseclass also know how to handle \em nudge values, either by using the native + ** baseclass also know how to handle _nudge values_, either by using the native ** (embedded) time grid of a quantised time value, or by falling back to a standard ** nudging grid, defined in the session context (TODO as of 6/2011). //////////////////////TICKET #810 ** - ** After (maybe) imposing a change to the target, the change \em notification value + ** After (maybe) imposing a change to the target, the _change notification_ value ** needs to be built. This is the time value entity to be forwarded to registered - ** listeners. This notification value has to be given as the type \c TI, in accordance - ** to the \c time::Control frontend definition used in the concrete usage situation. - ** As this type \c TI might be different to the actual target type, and again different + ** listeners. This notification value has to be given as the type `TI`, in accordance + ** to the `time::Control` frontend definition used in the concrete usage situation. + ** As this type `TI` might be different to the actual target type, and again different ** to the type of the change handed in, in some cases this involves a second conversion - ** step, to represent the current state of the target \c TAR in terms of the interface - ** type \c TI. + ** step, to represent the current state of the target `TAR` in terms of the interface + ** type `TI`. ** - ** \par changing quantised (grid aligned) time entities + ** ## changing quantised (grid aligned) time entities ** ** The time::Control element includes the capability to handle grid aligned time values, ** both as target and as change/notification value. This ability is compiled in conditionally, @@ -101,11 +101,11 @@ #ifndef LIB_TIME_CONTROL_POLICY_H #define LIB_TIME_CONTROL_POLICY_H -#include "lib/meta/util.hpp" #include "lib/time/mutation.hpp" #include "lib/time/timevalue.hpp" #include +#include #include @@ -115,7 +115,8 @@ namespace time { namespace mutation { using boost::disable_if; - using lib::meta::is_sameType; + using std::__or_; + using std::is_same; using std::placeholders::_1; using std::function; using std::bind; @@ -129,14 +130,14 @@ namespace mutation { inline bool isDuration() { - return is_sameType::value; + return is_same::value; } template inline bool isTimeSpan() { - return is_sameType::value; + return is_same::value; } template @@ -306,18 +307,18 @@ namespace mutation { namespace { template struct canMutateDuration - { - static const bool value = is_sameType::value - || is_sameType::value - || is_sameType::value; - }; + : __or_< is_same + , is_same + , is_same + > + { }; template struct canReceiveDuration - { - static const bool value = is_sameType::value - || is_sameType::value; - }; + : __or_< is_same + , is_same + > + { }; } diff --git a/src/proc/common.hpp b/src/proc/common.hpp index df2d1ef7e..a93f893a3 100644 --- a/src/proc/common.hpp +++ b/src/proc/common.hpp @@ -92,7 +92,16 @@ namespace proc { * A good deal of the active engine code is outside the scope of the * Proc-Layer, e.g. code located in backend services and plugins. */ - namespace engine { } + namespace engine { + + + /** + * Policies, definitions and tweaks to control the actual setup + * and behaviour of the render engine, and the way, render nodes + * are wired and instantiated + */ + namespace config { } + } diff --git a/src/proc/engine/nodewiring-config.hpp b/src/proc/engine/nodewiring-config.hpp index 6282e6198..44f61dc3f 100644 --- a/src/proc/engine/nodewiring-config.hpp +++ b/src/proc/engine/nodewiring-config.hpp @@ -53,6 +53,7 @@ #include "lib/meta/configflags.hpp" +#include "lib/meta/util.hpp" #include "lib/util.hpp" #include @@ -184,5 +185,50 @@ namespace config { + + using lib::meta::Yes_t; + using lib::meta::No_t; + + /** + * Helper template for semi-automatic detection if instantiation is possible. + * Requires help by the template to be tested, which needs to define a type member + * `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. + * @todo 1/2016 is there no better way to achieve this, based on new language features /////////////TICKET #986 + * Basically we want a SFINAE helper not only to check if a specific instantiation + * can be formed (which would be trivial), but rather, if a specific instantiation + * has _already been defined_. An automated solution for this problem seems questionable + * by theoretic reasons; such would endanger the "One Definition Rule", since the state + * of definedness of any type may change during the course of a translation unit from + * "unknown" to "declared", "partially defined" to "fully defined". To hinge the existence + * of another type on this transitory state would introduce a dangerous statefulness into + * the meta-language, which is assumed to be stateless. + * @todo what _could_ be done though is to detect if a given template can be _default constructed_, + * which, by logical weakening, implies it has be defined at all. Would that satisfy our + * purpose here? + * @todo 1/2016 also I'm not happy with the name "Instantiation". It should be something like `is_XYZ` + */ + template class _CandidateTemplate_> + struct Instantiation + { + + template + class Test + { + typedef _CandidateTemplate_ Instance; + + template + static Yes_t check(typename U::is_defined *); + template + static No_t check(...); + + public: + static const bool value = (sizeof(Yes_t)==sizeof(check(0))); + }; + }; + + + }}} // namespace proc::engine::config #endif diff --git a/src/proc/engine/nodewiring.cpp b/src/proc/engine/nodewiring.cpp index 47b4acab9..c6d596ba0 100644 --- a/src/proc/engine/nodewiring.cpp +++ b/src/proc/engine/nodewiring.cpp @@ -37,7 +37,6 @@ namespace engine { using lib::meta::Flags; using lib::meta::CombineFlags; using lib::meta::DefineConfigByFlags; - using lib::meta::Instantiation; using lib::meta::Apply; using lib::meta::Filter; diff --git a/tests/basics/time/time-control-test.cpp b/tests/basics/time/time-control-test.cpp index 6d07b8cf9..77b32b74c 100644 --- a/tests/basics/time/time-control-test.cpp +++ b/tests/basics/time/time-control-test.cpp @@ -30,7 +30,6 @@ #include "lib/meta/generator-combinations.hpp" #include "proc/asset/meta/time-grid.hpp" #include "lib/scoped-holder.hpp" -#include "lib/meta/util.hpp" #include "lib/util.hpp" #include @@ -195,20 +194,19 @@ namespace test{ namespace { // Implementation: Matrix of individual test combinations - using lib::meta::is_sameType; template inline bool isDuration() { - return is_sameType::value; + return std::is_same::value; } template inline bool isQuTime() { - return is_sameType::value; + return std::is_same::value; } template diff --git a/tests/library/meta/config-flags-test.cpp b/tests/library/meta/config-flags-test.cpp index f97b8870b..1129f0b60 100644 --- a/tests/library/meta/config-flags-test.cpp +++ b/tests/library/meta/config-flags-test.cpp @@ -38,7 +38,6 @@ #include "lib/test/run.hpp" -#include "lib/meta/util.hpp" #include "lib/format-string.hpp" #include "lib/meta/generator.hpp" #include "lib/meta/typelist-manip.hpp" @@ -60,6 +59,7 @@ namespace lib { namespace meta { namespace test { + using proc::engine::config::Instantiation; namespace { // internal definitions diff --git a/tests/library/meta/typelist-manip-test.cpp b/tests/library/meta/typelist-manip-test.cpp index 5d8cc3974..6a863e078 100644 --- a/tests/library/meta/typelist-manip-test.cpp +++ b/tests/library/meta/typelist-manip-test.cpp @@ -43,9 +43,11 @@ #include "lib/meta/typelist-manip.hpp" #include "meta/typelist-diagnostics.hpp" +#include #include using ::test::Test; +using std::is_same; using std::cout; using std::endl; @@ -139,9 +141,9 @@ namespace test { CHECK (6 == e1); CHECK (7 == e2); - CHECK ((is_sameType ::value)); - CHECK ((is_sameType ::value)); - CHECK ((is_sameType::value)); + CHECK ((is_same ::value)); + CHECK ((is_same ::value)); + CHECK ((is_same::value)); }