diff --git a/src/include/lifecycle.h b/src/include/lifecycle.h index b91ce5619..40634bc95 100644 --- a/src/include/lifecycle.h +++ b/src/include/lifecycle.h @@ -61,7 +61,7 @@ namespace lumiera { * define and register a callback for a specific lifecycle event. * The purpose of this class is to be defined as a static variable in the implementation * of some subsystem (i.e. in the cpp file), providing the ctor with the pointer to a - * callback function. Thus the callback gets enrolled when the corresponding object file + * callback function. Thus the callback gets enroled when the corresponding object file * is loaded. The event ON_BASIC_INIT is handled specifically, firing off the referred * callback function as soon as possible. All other labels are just arbitrary (string) * constants and it is necessary that "someone" cares to fire off the lifecycle events diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 4fa99136d..7a371da5a 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -41,7 +41,6 @@ liblumiera_la_SOURCES = \ $(liblumiera_la_srcdir)/lifecycle.cpp \ $(liblumiera_la_srcdir)/nobug-init.cpp \ $(liblumiera_la_srcdir)/util.cpp \ - $(liblumiera_la_srcdir)/visitor.cpp \ $(liblumiera_la_srcdir)/query.cpp \ $(liblumiera_la_srcdir)/streamtype.cpp \ $(liblumiera_la_srcdir)/test/testoption.cpp \ diff --git a/src/lib/lifecycle.cpp b/src/lib/lifecycle.cpp index 2a0a5f099..553a9fc32 100644 --- a/src/lib/lifecycle.cpp +++ b/src/lib/lifecycle.cpp @@ -46,7 +46,7 @@ namespace lumiera { void LifecycleHook::add (Symbol eventLabel, Callback callbackFun) { - bool isNew = LifecycleRegistry::instance().enroll (eventLabel,callbackFun); + bool isNew = LifecycleRegistry::instance().enrol (eventLabel,callbackFun); if (isNew && !strcmp(ON_BASIC_INIT, eventLabel)) callbackFun(); // when this code executes, diff --git a/src/lib/lifecycleregistry.hpp b/src/lib/lifecycleregistry.hpp index 4e1bcef7c..3d14e2209 100644 --- a/src/lib/lifecycleregistry.hpp +++ b/src/lib/lifecycleregistry.hpp @@ -74,7 +74,7 @@ namespace lumiera { /** @note only one copy of each distinct callback remembered */ - bool enroll (const string label, Hook toCall) + bool enrol (const string label, Hook toCall) { return table_[label] .insert(toCall) diff --git a/src/lib/query.cpp b/src/lib/query.cpp index f47b9819a..59be860a3 100644 --- a/src/lib/query.cpp +++ b/src/lib/query.cpp @@ -54,7 +54,7 @@ namespace lumiera { void normaliseID (string& id) { - id = util::sanitize(id); + id = util::sanitise(id); if (isnil(id) || !is_alpha (id[0])) id.insert(0, "o"); diff --git a/src/lib/query.hpp b/src/lib/query.hpp index 783992ade..911acaabf 100644 --- a/src/lib/query.hpp +++ b/src/lib/query.hpp @@ -66,7 +66,7 @@ namespace lumiera { { /** ensure standard format for a given id string. - * Trim, sanitize and ensure the first letter is lower case. + * Trim, sanitise and ensure the first letter is lower case. * @note modifies the given string ref in place */ void normaliseID (string& id); diff --git a/src/lib/test/run.hpp b/src/lib/test/run.hpp index 930e3592f..cd7621c89 100644 --- a/src/lib/test/run.hpp +++ b/src/lib/test/run.hpp @@ -84,7 +84,7 @@ namespace test class Launch : public Launcher { public: - Launch (string testID, string groups) { Suite::enroll (this,testID,groups); }; + Launch (string testID, string groups) { Suite::enrol (this,testID,groups); }; virtual auto_ptr operator() () { return auto_ptr (new TEST ); }; }; diff --git a/src/lib/test/suite.cpp b/src/lib/test/suite.cpp index f6107fafc..d1d383d71 100644 --- a/src/lib/test/suite.cpp +++ b/src/lib/test/suite.cpp @@ -39,30 +39,30 @@ -namespace test - { +namespace test { + using std::map; using std::vector; using std::auto_ptr; using std::tr1::shared_ptr; using boost::algorithm::trim; - + using util::isnil; using util::contains; typedef map TestMap; typedef shared_ptr PTestMap; typedef map GroupMap; - + /** helper to collect and manage the test cases. * Every testcase class should create a Launch instance - * which causes a call to Suite::enroll(), so we can add a + * which causes a call to Suite::enrol(), so we can add a * pointer to this Launcher into a map indexed by the * provided testIDs and groupIDs. * This enables us to build a Suite instance for any - * requested group and then instantiiate and invoke + * requested group and then instantiate and invoke * individual testcases accordingly. */ class Registry @@ -93,16 +93,16 @@ namespace test /** register the given test-launcher, so it can be later accessed - * either as a member of one of the specified groups, or direcly + * either as a member of one of the specified groups, or directly * by its testID. Any test is automatically added to the groupID * #ALLGROUP * @param test the Launcher object used to run this test - * @param testID unique ID to refere to this test (will be used as std::map key) + * @param testID unique ID to refer to this test (will be used as std::map key) * @param groups List of group-IDs selected by whitespace * */ void - Suite::enroll (Launcher* test, string testID, string groups) + Suite::enrol (Launcher* test, string testID, string groups) { REQUIRE( test ); REQUIRE( !isnil(testID) ); @@ -112,7 +112,7 @@ namespace test while (ss >> group ) testcases.add2group(test, testID, group); - // Magic: allways add any testcas to groupID="ALL" + // Magic: always add any testcase to groupID="ALL" testcases.add2group(test,testID, ALLGROUP); } @@ -122,7 +122,7 @@ namespace test /** create a suite comprised of all the testcases - * previously @link #enroll() registered @endlink with this + * previously @link #enrol() registered @endlink with this * this group. * @see #run() running tests in a Suite */ @@ -138,14 +138,14 @@ namespace test } #define VALID(test,testID) \ - ASSERT ((test), "NULL testcase laucher for test '%s' found in testsuite '%s'", groupID_.c_str(),testID.c_str()); + ASSERT ((test), "NULL testcase launcher for test '%s' found in testsuite '%s'", groupID_.c_str(),testID.c_str()); /** run all testcases contained in this Suite. * The first argument in the commandline, if present, * will select one single testcase with a matching ID. * In case of invoking a single testcase, the given cmdline - * will be forwarded to the testcase, after removind the + * will be forwarded to the testcase, after removing the * testcaseID from cmdline[0]. Otherwise, every testcase * in this suite is invoked with a empty cmdline vector. * @param cmdline ref to the vector of commandline tokens @@ -173,7 +173,7 @@ namespace test } } // no test-ID was specified. - // instantiiate all tests cases and execute them. + // Instantiate all tests cases and execute them. for ( TestMap::iterator i=tests->begin(); i!=tests->end(); ++i ) { std::cout << "\n ----------"<< i->first<< "----------\n"; @@ -184,7 +184,7 @@ namespace test } - /** print to stdout an ennumeration of all testcases in this suite, + /** print to stdout an enumeration of all testcases in this suite, * in a format suitable for use with Cehteh's ./test.sh */ void @@ -195,7 +195,7 @@ namespace test ASSERT (tests); std::cout << "TESTING \"Component Test Suite: " << groupID_ << "\" ./test-components\n\n"; - + for ( TestMap::iterator i=tests->begin(); i!=tests->end(); ++i ) { string key (i->first); @@ -214,7 +214,7 @@ namespace test std::cout << "END\n"; } } - - - + + + } // namespace test diff --git a/src/lib/test/suite.hpp b/src/lib/test/suite.hpp index afdb9e3d6..ad378b54a 100644 --- a/src/lib/test/suite.hpp +++ b/src/lib/test/suite.hpp @@ -42,7 +42,7 @@ namespace test /** * Enables running a collection of tests. - * An internal registration service #enroll() is provided + * An internal registration service #enrol() is provided * for the individual Test - inscances to be recognized as * testcases. The groupID passed to the constructor selects * all testcases declared as belonging to this Group. @@ -55,7 +55,7 @@ namespace test Suite (string groupID); void run (Arg cmdline); void describe (); - static void enroll (Launcher *test, string testID, string groups); + static void enrol (Launcher *test, string testID, string groups); static const string ALLGROUP; }; diff --git a/src/lib/util.cpp b/src/lib/util.cpp index aa2871c17..5c52cf6ad 100644 --- a/src/lib/util.cpp +++ b/src/lib/util.cpp @@ -24,8 +24,7 @@ #include "lib/util.hpp" #include -#include -#include +#include using boost::algorithm::trim_right_copy_if; using boost::algorithm::is_any_of; @@ -33,19 +32,21 @@ using boost::algorithm::is_alnum; using boost::algorithm::is_space; -namespace util - { +namespace util { - typedef boost::function ChPredicate; - ChPredicate operator! (ChPredicate p) { return ! boost::bind(p,_1); } + using std::tr1::function; + using std::tr1::placeholders::_1; + + typedef function ChPredicate; + ChPredicate operator! (ChPredicate p) { return ! bind(p,_1); } - // character classes used for sanitizing a string + // character classes used for sanitising a string ChPredicate isValid (is_alnum() || is_any_of("-_.:+$'()@")); ///< characters to be retained ChPredicate isPunct (is_space() || is_any_of(",;#*~´`?\\=/&%![]{}")); ///< punctuation to be replaced by '_' string - sanitize (const string& org) + sanitise (const string& org) { string res (trim_right_copy_if(org, !isValid )); string::iterator j = res.begin(); diff --git a/src/lib/util.hpp b/src/lib/util.hpp index 595d945c7..bdee6ea5d 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -245,8 +245,9 @@ namespace util { "mixed Ω garbage" --> 'mixed_garbage' "Bääääh!!" --> 'Bh' \endverbatim + * @see sanitised-identifier-test.cpp */ - string sanitize (const string& org); + string sanitise (const string& org); diff --git a/src/lib/visitor-dispatcher.hpp b/src/lib/visitor-dispatcher.hpp new file mode 100644 index 000000000..4ec682ea4 --- /dev/null +++ b/src/lib/visitor-dispatcher.hpp @@ -0,0 +1,217 @@ +/* + VISITOR-DISPATCHER.hpp - visitor implementation details + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + 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_VISITOR_DISPATCHER_H +#define LUMIERA_VISITOR_DISPATCHER_H + +#include "lib/error.hpp" +#include "lib/util.hpp" +#include "lib/sync-classlock.hpp" +#include "lib/singleton.hpp" +#include "lib/util.hpp" + +#include + + +namespace lumiera { +namespace visitor { + + using lib::ClassLock; + + + template class Tag; + + + template + struct TagTypeRegistry + { + static Tag tag; + }; + + /** + * Type tag for concrete visiting tool classes. + * Used to access the previously registered dispatcher + * trampoline function when handling a visitor invocation. + */ + template + class Tag + { + size_t tagID; ///< tag value + static size_t lastRegisteredID; + + private: + static void + generateID (size_t& id) + { + ClassLock guard(); + if (!id) + id = ++lastRegisteredID; + } + + public: + Tag() : tagID(0) { } + operator size_t() const { return tagID; } + + + template + static Tag& + get (TOOLImpl* const =0) + { + Tag& t = TagTypeRegistry::tag; + if (!t) generateID (t.tagID); + return t; + } + + }; + + + + /** storage for the Tag registry for each concrete tool */ + template + Tag TagTypeRegistry::tag; + + template + size_t Tag::lastRegisteredID (0); + + + + + + + + + /** + * For each possible call entry point via some subclass of the visitable hierarchy, + * we maintain a dispatcher table to keep track of all concrete tool implementations + * able to receive and process calls on objects of this subclass. + * @param TAR the concrete target (subclass) type within the visitable hierarchy + * @param TOOL the overall tool family (base class of all concrete tools) + */ + template + class Dispatcher + { + typedef typename TOOL::ReturnType ReturnType; + + /** generator for Trampoline functions, + * used to dispatch calls down to the + * right "treat"-Function on the correct + * concrete tool implementation class + */ + template + static ReturnType + callTrampoline (TAR& obj, TOOL& tool) + { + // cast down to real implementation type + REQUIRE (INSTANCEOF (TOOLImpl, &tool)); + TOOLImpl& toolObj = static_cast (tool); + + // trigger (compile time) overload resolution + // based on concrete type, then dispatch the call. + // Note this may cause obj to be upcasted. + return toolObj.treat (obj); + } + + typedef ReturnType (*Trampoline) (TAR&, TOOL& ); + + + /** VTable for storing the Trampoline pointers */ + std::vector table_; + + + void + accomodate (size_t index) + { + ClassLock guard(); // note: this lock is also used for the singleton! + if (index > table_.size()) + table_.resize (index); // performance bottleneck?? TODO: measure the real impact! + } + + inline bool + is_known (size_t id) + { + return id<=table_.size() && table_[id-1]; + } + + inline void + storePtr (size_t id, Trampoline func) + { + REQUIRE (func); + REQUIRE (0 < id); + if (id>table_.size()) + accomodate (id); + table_[id-1] = func; + } + + inline Trampoline + storedTrampoline (size_t id) + { + if (id<=table_.size() && table_[id-1]) + return table_[id-1]; + else + return &errorHandler; + } + + static ReturnType + errorHandler (TAR& target, TOOL& tool) + { + return tool.onUnknown (target); + } + + + public: + static Singleton > instance; + + inline ReturnType + forwardCall (TAR& target, TOOL& tool) + { + // get concrete type via tool's VTable + Tag index = tool.getTag(); + return (*storedTrampoline(index)) (target, tool); + } + + template + inline void + enrol(TOOLImpl* typeref) + { + Tag& index = Tag::get (typeref); + if (is_known (index)) + return; + else + { + Trampoline func = &callTrampoline; + storePtr (index, func); + } + + } + }; + + /** storage for the dispatcher table(s) */ + template + Singleton > Dispatcher::instance; + + + + +}} // namespace lumiera::visitor +#endif diff --git a/src/lib/visitorpolicies.hpp b/src/lib/visitor-policies.hpp similarity index 51% rename from src/lib/visitorpolicies.hpp rename to src/lib/visitor-policies.hpp index 04034df4e..63e6324cf 100644 --- a/src/lib/visitorpolicies.hpp +++ b/src/lib/visitor-policies.hpp @@ -1,5 +1,5 @@ /* - VISITOR.hpp - Acyclic Visitor library + VISITOR-POLICIES.hpp - Acyclic Visitor library Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -21,7 +21,7 @@ */ -/** @file visitorpolicies.hpp +/** @file visitor-policies.hpp ** Policies usable for configuring the lumiera::visitor::Tool for different kinds of error handling. ** @see buildertool.hpp for another flavour (calling an catch-all-function there) ** @@ -29,49 +29,46 @@ -#ifndef LUMIERA_VISITORPOLICIES_H -#define LUMIERA_VISITORPOLICIES_H +#ifndef LUMIERA_VISITOR_POLICIES_H +#define LUMIERA_VISITOR_POLICIES_H #include "lib/error.hpp" -namespace lumiera - { - namespace visitor +namespace lumiera { +namespace visitor { + + /** + * Policy returning just the default return value in case + * of encountering an unknown Visitor (typically caused by + * adding a new class to the visitable hierarchy) + */ + template + struct UseDefault { - /** - * Policy returning just the default return value in case - * of encountering an unknown Visitor (typically caused by - * adding a new class to the visitable hierarchy) - */ - template - struct UseDefault - { - template - RET - onUnknown (TAR&) - { - return RET(); - } - }; - - /** - * Policy to throw when encountering an unknown visiting tool - */ - template - struct ThrowException - { - template - RET - onUnknown (TAR&) - { - throw lumiera::error::Config("unable to decide what tool operation to call"); - } - }; - - - - } // namespace visitor - -} // namespace lumiera + template + RET + onUnknown (TAR&) + { + return RET(); + } + }; + + /** + * Policy to throw when encountering an unknown visiting tool + */ + template + struct ThrowException + { + template + RET + onUnknown (TAR&) + { + throw lumiera::error::Config("unable to decide what tool operation to call"); + } + }; + + + +}} // namespace lumiera::visitor #endif diff --git a/src/lib/visitor.cpp b/src/lib/visitor.cpp deleted file mode 100644 index 996d22c16..000000000 --- a/src/lib/visitor.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - Vistitable,Tool,Applicable - Acyclic Visitor library - - Copyright (C) Lumiera.org - 2008, Hermann Vosseler - - 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. - -* *****************************************************/ - - -#include "lib/visitor.hpp" - -namespace lumiera - { - namespace visitor - { - - - - } // namespace visitor - -} // namespace lumiera diff --git a/src/lib/visitor.hpp b/src/lib/visitor.hpp index 52fdc4f7d..a36ca00e1 100644 --- a/src/lib/visitor.hpp +++ b/src/lib/visitor.hpp @@ -36,11 +36,11 @@ Credits for many further implementation ideas go to /** @file visitor.hpp - ** A library implementation of the Visitor Pattern taylored specifically + ** A library implementation of the Visitor Pattern tailored specifically ** to Lumiera's needs within the Proc Layer. Visitor enables double dispatch ** calls, based both on the concrete type of some target object and the concrete type of ** a tool object being applied to this target. The code carrying out this tool application - ** (and thus triggering the double dispatch) need not know any of these concret types and is + ** (and thus triggering the double dispatch) need not know any of these concrete types and is ** thus completely decoupled form implementation details encapsulated within the visiting tool. ** The visiting tool implementation class provides specific "treat(ConcreteVisitable&)" functions, ** and this visitor lib will dispatch the call to the* correct "treat"-function based on the @@ -60,13 +60,13 @@ Credits for many further implementation ideas go to **
  • any concrete Visitable subclass wanting to be treated by some concrete tool ** needs to use the DECLARE_PROCESSABLE_BY(TOOLBASE) macro. By this, it gets an ** virtual \code apply(TOOLBASE&) function. Otherwise, it will be treated by the - ** interface of the next base clas using this macro.
  • + ** interface of the next base class using this macro. ** ** For design questions and more detailed implementation notes, see the Proc Layer Tiddly Wiki. ** ** @see visitingtooltest.cpp test cases using our lib implementation - ** @see BuilderTool one especially important instantiiation - ** @see visitordispatcher.hpp + ** @see BuilderTool one especially important instantiation + ** @see visitor-dispatcher.hpp ** @see typelist.hpp ** */ @@ -76,158 +76,154 @@ Credits for many further implementation ideas go to #ifndef LUMIERA_VISITOR_H #define LUMIERA_VISITOR_H -#include "lib/visitorpolicies.hpp" -#include "lib/visitordispatcher.hpp" +#include "lib/visitor-policies.hpp" +#include "lib/visitor-dispatcher.hpp" #include "lib/meta/typelist.hpp" -namespace lumiera - { - namespace visitor +namespace lumiera { +namespace visitor { + + + /** + * Marker interface / base class for all "visiting tools". + * When applying such a tool to some concrete instance + * derived from Visitable, a special function treating + * this concrete subclass will be selected on the + * concrete visiting tool instance. + */ + template + < typename RET = void + , template class ERR = UseDefault + > + class Tool : public ERR { + public: + typedef RET ReturnType; ///< Tool function invocation return type + typedef Tool ToolBase; ///< for templating the Tag and Dispatcher + + virtual ~Tool () { }; ///< use RTTI for all visiting tools + + /** allows discovery of the concrete Tool type when dispatching a + * visitor call. Can be implemented by inheriting from ToolTag */ + virtual Tag getTag() = 0; + }; - /** - * Marker interface / base class for all "visiting tools". - * When applying such a tool to some concrete instance - * derived from Visitable, a special function treating - * this concrete subclass will be selected on the - * concrete visiting tool instance. - */ - template - < typename RET = void, - template class ERR = UseDefault - > - class Tool : public ERR - { - public: - typedef RET ReturnType; ///< Tool function invocation return type - typedef Tool ToolBase; ///< for templating the Tag and Dispatcher - - virtual ~Tool () { }; ///< use RTTI for all visiting tools - - /** allows discovery of the concrete Tool type when dispatching a - * visitor call. Can be implemented by inheriting from ToolTag */ - virtual Tag getTag() = 0; - }; - - - - - /** - * Marker template to declare that some "visiting tool" - * wants to treat a set of concrete Visitable classes. - * - * Each "first class" concrete visiting tool implementation has - * to inherit from an instance of this template parametrized with - * the desired types; for each of the mentioned types, calls will - * be dispatched to the tool implementation. (To make it clear: - * Calls to all other types not marked by such an "Applicable" - * won't ever be dispatched to this tool class.). - * A Sideeffect of inheriting from such an "Applicable" is that - * the tool gets an unique Tag entry, which is used internally - * as index in the dispatcher tables. And the automatic ctor call - * allows us to record the type information and preregister the - * dispatcher entry. - */ - template - < class TOOLImpl, // concrete tool implementation type - class TYPES, // List of applicable Types goes here... - class BASE=Tool<> // "visiting tool" base class - > - class Applicable; - - template // recursion end: inherit from BASE - < class TOOLImpl, - class BASE - > - class Applicable - : public BASE - { } - ; - - template - < class TOOLImpl, - class TAR, class TYPES, - class BASE - > - class Applicable, BASE> - : public Applicable - { - - typedef typename BASE::ToolBase ToolBase; - - protected: - virtual ~Applicable () {} - Applicable () - { - TOOLImpl* typeref = 0; - Dispatcher::instance().enroll (typeref); - } - - public: - virtual Tag - getTag () - { - TOOLImpl* typeref = 0; - return Tag::get (typeref); - } - }; - - using typelist::Types; // convienience for the user of "Applicable" - - + + + /** + * Marker template to declare that some "visiting tool" + * wants to treat a set of concrete Visitable classes. + * + * Each "first class" concrete visiting tool implementation has + * to inherit from an instance of this template parametrised with + * the desired types; for each of the mentioned types, calls will + * be dispatched to the tool implementation. (To make it clear: + * Calls to all other types not marked by such an "Applicable" + * won't ever be dispatched to this tool class.). + * A Sideeffect of inheriting from such an "Applicable" is that + * the tool gets an unique Tag entry, which is used internally + * as index in the dispatcher tables. And the automatic ctor call + * allows us to record the type information and pre-register the + * dispatcher entry. + */ + template + < class TOOLImpl, // concrete tool implementation type + class TYPES, // List of applicable Types goes here... + class BASE=Tool<> // "visiting tool" base class + > + class Applicable; + + template // recursion end: inherit from BASE + < class TOOLImpl, + class BASE + > + class Applicable + : public BASE + { } + ; + + template + < class TOOLImpl, + class TAR, class TYPES, + class BASE + > + class Applicable, BASE> + : public Applicable + { - /** - * Marker interface or base class for all "Visitables". - * Concrete types to be treated by a "visiting tool" derive from - * this interface and need to implement an #apply(Tool&), forwarding - * to the (internal, static, templated) #dispatchOp. This is done - * best by using the #DEFINE_PROCESSABLE_BY macro. - */ - template - < class TOOL = Tool<> - > - class Visitable - { - protected: - virtual ~Visitable () { }; - - /// @note may differ from TOOL - typedef typename TOOL::ToolBase ToolBase; - typedef typename TOOL::ReturnType ReturnType; - - /** @internal used by the #DEFINE_PROCESSABLE_BY macro. - * Dispatches to the actual operation on the - * "visiting tool" (visitor implementation) - * Note: creates a context templated on concrete TAR. - */ - template - static inline ReturnType - dispatchOp (TAR& target, TOOL& tool) - { - return Dispatcher::instance().forwardCall (target,tool); - } - - public: - /** to be defined by the DEFINE_PROCESSABLE_BY macro - * in all classes wanting to be treated by some tool */ - virtual ReturnType apply (TOOL&) = 0; - }; + typedef typename BASE::ToolBase ToolBase; + protected: + virtual ~Applicable () {} + Applicable () + { + TOOLImpl* typeref = 0; + Dispatcher::instance().enrol (typeref); + } + + public: + virtual Tag + getTag () + { + TOOLImpl* typeref = 0; + return Tag::get (typeref); + } + }; + + using typelist::Types; // convenience for the user of "Applicable" + + + + /** + * Marker interface or base class for all "Visitables". + * Concrete types to be treated by a "visiting tool" derive from + * this interface and need to implement an #apply(Tool&), forwarding + * to the (internal, static, templated) #dispatchOp. This is done + * best by using the #DEFINE_PROCESSABLE_BY macro. + */ + template + < class TOOL = Tool<> + > + class Visitable + { + protected: + virtual ~Visitable () { }; + + /// @note may differ from TOOL + typedef typename TOOL::ToolBase ToolBase; + typedef typename TOOL::ReturnType ReturnType; + + /** @internal used by the #DEFINE_PROCESSABLE_BY macro. + * Dispatches to the actual operation on the + * "visiting tool" (visitor implementation) + * Note: creates a context templated on concrete TAR. + */ + template + static inline ReturnType + dispatchOp (TAR& target, TOOL& tool) + { + return Dispatcher::instance().forwardCall (target,tool); + } + + public: + /** to be defined by the DEFINE_PROCESSABLE_BY macro + * in all classes wanting to be treated by some tool */ + virtual ReturnType apply (TOOL&) = 0; + }; + -/** mark a Visitable subclass as actually treatable by some +/** mark a Visitable subclass as actually treat-able by some * "visiting tool" base interface. Defines the apply-function, * which is the actual access point to invoke the visiting */ #define DEFINE_PROCESSABLE_BY(TOOL) \ virtual ReturnType apply (TOOL& tool) \ { return dispatchOp (*this, tool); } - - - - } // namespace visitor - -} // namespace lumiera + + + +}} // namespace lumiera::visitor #endif diff --git a/src/lib/visitordispatcher.hpp b/src/lib/visitordispatcher.hpp deleted file mode 100644 index 0eae85168..000000000 --- a/src/lib/visitordispatcher.hpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - VISITORDISPATCHER.hpp - visitor implementation details - - Copyright (C) Lumiera.org - 2008, Hermann Vosseler - - 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_VISITORDISPATCHER_H -#define LUMIERA_VISITORDISPATCHER_H - -#include "lib/error.hpp" -#include "lib/util.hpp" -#include "lib/sync-classlock.hpp" -#include "lib/singleton.hpp" -#include "lib/util.hpp" - -#include - - -namespace lumiera { - namespace visitor { - - using lib::ClassLock; - - - template class Tag; - - - template - struct TagTypeRegistry - { - static Tag tag; - }; - - /** - * Type tag for concrete visiting tool classes. - * Used to access the previously registered dispatcher - * trampoline function when handling a visitor invocation. - */ - template - class Tag - { - size_t tagID; ///< tag value - static size_t lastRegisteredID; - - private: - static void - generateID (size_t& id) - { - ClassLock guard(); - if (!id) - id = ++lastRegisteredID; - } - - public: - Tag() : tagID(0) { } - operator size_t() const { return tagID; } - - - template - static Tag& - get (TOOLImpl* const =0) - { - Tag& t = TagTypeRegistry::tag; - if (!t) generateID (t.tagID); - return t; - } - - }; - - - - /** storage for the Tag registry for each concrete tool */ - template - Tag TagTypeRegistry::tag; - - template - size_t Tag::lastRegisteredID (0); - - - - - - - - - /** - * For each possible call entry point via some subclass of the visitable hierarchy, - * we maintain a dispatcher table to keep track of all concrete tool implementations - * able to receive and process calls on objects of this subclass. - * @param TAR the concrete target (subclass) type within the visitable hierarchy - * @param TOOL the overall tool family (base class of all concrete tools) - */ - template - class Dispatcher - { - typedef typename TOOL::ReturnType ReturnType; - - /** generator for Trampoline functions, - * used to dispatch calls down to the - * right "treat"-Function on the correct - * concrete tool implementation class - */ - template - static ReturnType - callTrampoline (TAR& obj, TOOL& tool) - { - // cast down to real implementation type - REQUIRE (INSTANCEOF (TOOLImpl, &tool)); - TOOLImpl& toolObj = static_cast (tool); - - // trigger (compile time) overload resolution - // based on concrete type, then dispatch the call. - // Note this may cause obj to be upcasted. - return toolObj.treat (obj); - } - - typedef ReturnType (*Trampoline) (TAR&, TOOL& ); - - - /** VTable for storing the Trampoline pointers */ - std::vector table_; - - - void - accomodate (size_t index) - { - ClassLock guard(); // note: this lock is also used for the singleton! - if (index > table_.size()) - table_.resize (index); // performance bottleneck?? TODO: measure the real impact! - } - - inline bool - is_known (size_t id) - { - return id<=table_.size() && table_[id-1]; - } - - inline void - storePtr (size_t id, Trampoline func) - { - REQUIRE (func); - REQUIRE (0 < id); - if (id>table_.size()) - accomodate (id); - table_[id-1] = func; - } - - inline Trampoline - storedTrampoline (size_t id) - { - if (id<=table_.size() && table_[id-1]) - return table_[id-1]; - else - return &errorHandler; - } - - static ReturnType - errorHandler (TAR& target, TOOL& tool) - { - return tool.onUnknown (target); - } - - - public: - static Singleton > instance; - - inline ReturnType - forwardCall (TAR& target, TOOL& tool) - { - // get concrete type via tool's VTable - Tag index = tool.getTag(); - return (*storedTrampoline(index)) (target, tool); - } - - template - inline void - enroll(TOOLImpl* typeref) - { - Tag& index = Tag::get (typeref); - if (is_known (index)) - return; - else - { - Trampoline func = &callTrampoline; - storePtr (index, func); - } - - } - }; - - /** storage for the dispatcher table(s) */ - template - Singleton > Dispatcher::instance; - - - - - } // namespace visitor - -} // namespace lumiera -#endif diff --git a/src/pre.hpp b/src/pre.hpp index d1495d952..6b12ea67f 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -41,9 +41,8 @@ #include #include #include -#include +#include #include -#include #include "proc/common.hpp" diff --git a/src/pre_a.hpp b/src/pre_a.hpp index 2d032c03c..1bac10969 100644 --- a/src/pre_a.hpp +++ b/src/pre_a.hpp @@ -38,9 +38,8 @@ #include #include #include -#include +#include #include -#include #include "proc/common.hpp" #include "proc/asset.hpp" diff --git a/src/proc/asset.cpp b/src/proc/asset.cpp index 8da1f0eb8..77fe6ace6 100644 --- a/src/proc/asset.cpp +++ b/src/proc/asset.cpp @@ -25,14 +25,14 @@ #include "proc/assetmanager.hpp" #include "lib/util.hpp" -#include #include -#include +#include -using boost::bind; +using std::tr1::function; +using std::tr1::placeholders::_1; +using std::tr1::bind; using boost::format; -using boost::function; using util::contains; using util::removeall; using util::for_each; @@ -44,13 +44,13 @@ namespace asset { using ::NOBUG_FLAG(memory); NOBUG_CPP_DEFINE_FLAG_PARENT(assetmem, memory); - - + + Asset::Ident::Ident(const string& n, const Category& cat, const string& o, const uint ver) - : name(util::sanitize (n)), + : name(util::sanitise (n)), category(cat), org(o), version(ver) { } - + /** Asset is a Interface class; usually, objects of * concrete subclasses are created via specialized Factories @@ -147,7 +147,7 @@ namespace asset { void Asset::unlink () { - function forget_me = bind(&Asset::unregister, this,_1); + function forget_me = bind(&Asset::unregister, this, _1); for_each (parents, forget_me); dependants.clear(); diff --git a/src/proc/asset/clip.cpp b/src/proc/asset/clip.cpp index ddaa5a22a..b5052a718 100644 --- a/src/proc/asset/clip.cpp +++ b/src/proc/asset/clip.cpp @@ -41,7 +41,7 @@ namespace asset const Asset::Ident createClipIdent (const Media& mediaref) { - string name (mediaref.ident.name + "-clip"); // TODO something sensible here; append number, sanitize etc. + string name (mediaref.ident.name + "-clip"); // TODO something sensible here; append number, sanitise etc. Category category (mediaref.ident.category); category.setPath(CLIP_SUBFOLDER); return Asset::Ident (name, category, diff --git a/src/proc/asset/media.cpp b/src/proc/asset/media.cpp index e8c6ac12b..198e8ed2e 100644 --- a/src/proc/asset/media.cpp +++ b/src/proc/asset/media.cpp @@ -50,7 +50,7 @@ namespace asset namespace // Implementation details { /** helper: extract a name token out of a given path/filename - * @return sanitized token based on the name (minus extension), + * @return sanitised token based on the name (minus extension), * empty string if not the common filename pattern. */ string extractName (const string& path) @@ -59,7 +59,7 @@ namespace asset smatch match; if (regex_search (path, match, pathname_pattern)) - return util::sanitize (string (match[1])); + return util::sanitise (string (match[1])); else return ""; } diff --git a/src/proc/asset/preview.cpp b/src/proc/asset/preview.cpp index 2753f8cc9..82247149e 100644 --- a/src/proc/asset/preview.cpp +++ b/src/proc/asset/preview.cpp @@ -37,7 +37,7 @@ namespace asset const Asset::Ident createProxyIdent (const Asset::Ident& mediaref) { - string name (mediaref.name + "-proxy"); // TODO something sensible here; append number, sanitize etc. + string name (mediaref.name + "-proxy"); // TODO something sensible here; append number, sanitise etc. Category category (mediaref.category); TODO ("put it in another subfolder within the same category??"); return Asset::Ident (name, category, diff --git a/src/proc/assetmanager.cpp b/src/proc/assetmanager.cpp index 6c46e9b6a..e8fd45352 100644 --- a/src/proc/assetmanager.cpp +++ b/src/proc/assetmanager.cpp @@ -27,15 +27,13 @@ #include "lib/sync.hpp" #include "lib/util.hpp" -#include - +#include #include -#include using std::tr1::static_pointer_cast; -using boost::function; +using std::tr1::function; +using std::tr1::placeholders::_1; using boost::format; -using boost::bind; using util::for_each; using lumiera::Singleton; diff --git a/src/proc/control/command-argument-holder.hpp b/src/proc/control/command-argument-holder.hpp index d3c37860e..7f3fb056a 100644 --- a/src/proc/control/command-argument-holder.hpp +++ b/src/proc/control/command-argument-holder.hpp @@ -48,6 +48,7 @@ #include "proc/control/argument-tuple-accept.hpp" #include "proc/control/command-closure.hpp" #include "proc/control/memento-tie.hpp" +#include "lib/opaque-holder.hpp" //#include //#include @@ -67,6 +68,8 @@ namespace control { // using std::ostream; using boost::noncopyable; using std::string; + using lib::InPlaceBuffer; + namespace { // empty state marker objects for ArgumentHolder @@ -118,38 +121,49 @@ namespace control { , ArgumentHolder // target class providing the implementation , CmdClosure // base class to inherit from > - , noncopyable + , private noncopyable { - Closure arguments_; - MementoTie memento_; - typedef typename Closure::ArgTuple ArgTuple; + typedef Closure ArgHolder; + typedef MementoTie MemHolder; + + typedef InPlaceBuffer > ArgumentBuff; + typedef InPlaceBuffer > MementoBuff; + + typedef typename ArgHolder::ArgTuple ArgTuple; - /* === proxied CmdClosure interface === */ + /* ====== in-place storage buffers ====== */ + + ArgumentBuff arguments_; + MementoBuff memento_; + + + + /* ==== proxied CmdClosure interface ==== */ virtual bool isValid () const { - return bool(arguments_); + return arguments_->isValid(); } virtual CmdFunctor bindArguments (CmdFunctor& func) { - if (!arguments_) + if (!isValid()) throw lumiera::error::State ("Lifecycle error: can't bind functor, " "command arguments not yet provided", LUMIERA_ERROR_UNBOUND_ARGUMENTS); - return arguments_.bindArguments(func); + return arguments_->bindArguments(func); } virtual operator string() const { return "Command-State{ arguments=" - + (arguments_? string(arguments_) : "unbound") - + (memento_ ? ", }" : " }") + + (*arguments_? string(*arguments_) : "unbound") + + (*memento_ ? ", }" : "·noUNDO·}") ; } @@ -161,13 +175,13 @@ namespace control { * whereas the undo functions will be wired by #tie */ ArgumentHolder () - : arguments_(MissingArguments() ) - , memento_(UntiedMemento() ) + : arguments_() + , memento_() { } /** has undo state capturing been invoked? */ - bool canUndo () const { return bool(memento_); } - bool empty () const { return !arguments_; } + bool canUndo () const { return memento_->isValid(); } + bool empty () const { return !arguments_->isValid(); } /** store a new argument tuple within this ArgumentHolder, @@ -175,7 +189,7 @@ namespace control { void bindArg (ArgTuple argTup) { - this->arguments_ = Closure (argTup); + arguments_.template create (argTup); } @@ -186,11 +200,21 @@ namespace control { * @note any bound undo/capture functions based on the previously held MementoTie * are silently invalidated; using them will likely cause memory corruption! */ MementoTie& - tie (function const& undoFunc, + tiesi (function const& undoFunc, function const& captureFunc) { - return this->memento_ = MementoTie (undoFunc,captureFunc); + return memento_.template create (undoFunc,captureFunc); } + + /** @may be called directly referencing an function */ + MementoTie& + tie (SIG_undo& undoFunc, SIG_cap& captureFunc) + { + return tiesi ( function(undoFunc) + , function(captureFunc) + ); + } + /** direct "backdoor" access to stored memento value. @@ -198,7 +222,7 @@ namespace control { MEM& memento () { - return memento_.getState(); + return memento_->getState(); } }; diff --git a/src/proc/engine/nodewiringconfig.hpp b/src/proc/engine/nodewiringconfig.hpp index 29bb9504a..56a7d1618 100644 --- a/src/proc/engine/nodewiringconfig.hpp +++ b/src/proc/engine/nodewiringconfig.hpp @@ -21,7 +21,7 @@ */ /** @file nodewiringconfig.hpp - ** Sometimes we need to coose a different implementation for dealing with + ** Sometimes we need to choose 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, @@ -29,14 +29,14 @@ ** \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 + ** sequence is quite dependent 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 + ** individual 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. ** @@ -54,7 +54,7 @@ #include "lib/util.hpp" #include "lib/meta/configflags.hpp" -#include +#include #include #include @@ -95,9 +95,9 @@ namespace engine { * configuration. The intention is to to drive this selection by * the use of template metaprogramming for extracting all * currently defined StateProxy object configurations. - * @todo as the facories live only within the enclosed table (map) + * @todo as the factories live only within the enclosed table (map) * we could allocate them in-place. Unfortunately this is - * non-trivial, because the stl containers employ + * non-trivial, because the STL containers employ * value semantics and thus do a copy even on insert. * Thus, for now we use a shared_ptr to hold the factory * heap allocated. @@ -108,7 +108,7 @@ namespace engine { > class ConfigSelector { - typedef boost::function FacFunction; + typedef std::tr1::function FacFunction; template struct FactoryHolder diff --git a/tests/components/proc/asset/assetdiagnostics.hpp b/tests/components/proc/asset/asset-diagnostics.hpp similarity index 85% rename from tests/components/proc/asset/assetdiagnostics.hpp rename to tests/components/proc/asset/asset-diagnostics.hpp index 326da5e8d..ef135f560 100644 --- a/tests/components/proc/asset/assetdiagnostics.hpp +++ b/tests/components/proc/asset/asset-diagnostics.hpp @@ -1,5 +1,5 @@ /* - ASSETDIAGNOSTICS.hpp - collection of test and debug helpers + ASSET-DIAGNOSTICS.hpp - collection of test and debug helpers Copyright (C) Lumiera.org 2008, Hermann Vosseler @@ -20,8 +20,8 @@ */ -/** @file assetdiagnostics.hpp - ** Small helper and diagnosic functions related to Asset and AssetManager +/** @file asset-diagnostics.hpp + ** Small helper and diagnostic functions related to Asset and AssetManager ** ** @see assetmanager.hpp ** @see CreateAsset_test @@ -29,21 +29,22 @@ */ -#ifndef ASSET_ASSETDIAGNOSTICS_H -#define ASSET_ASSETDIAGNOSTICS_H +#ifndef ASSET_ASSET_DIAGNOSTICS_H +#define ASSET_ASSET_DIAGNOSTICS_H #include "proc/assetmanager.hpp" #include "lib/util.hpp" #include -#include +#include #include using util::contains; using util::for_each; +using std::tr1::placeholders::_1; +using std::tr1::bind; using boost::format; -using boost::bind; using std::string; using std::cout; diff --git a/tests/components/proc/asset/basicpipetest.cpp b/tests/components/proc/asset/basicpipetest.cpp index 132502a42..616d100e1 100644 --- a/tests/components/proc/asset/basicpipetest.cpp +++ b/tests/components/proc/asset/basicpipetest.cpp @@ -30,7 +30,7 @@ #include "lib/query.hpp" #include "proc/assetmanager.hpp" #include "proc/mobject/session.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" #include #include diff --git a/tests/components/proc/asset/compoundmediatest.cpp b/tests/components/proc/asset/compoundmediatest.cpp index e6e045895..d3a2324f8 100644 --- a/tests/components/proc/asset/compoundmediatest.cpp +++ b/tests/components/proc/asset/compoundmediatest.cpp @@ -29,7 +29,7 @@ #include "proc/asset/media.hpp" #include "proc/asset/proc.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" using util::isnil; using std::string; diff --git a/tests/components/proc/asset/createassettest.cpp b/tests/components/proc/asset/createassettest.cpp index c2eb633f8..70b0fa808 100644 --- a/tests/components/proc/asset/createassettest.cpp +++ b/tests/components/proc/asset/createassettest.cpp @@ -29,7 +29,7 @@ #include "proc/asset/media.hpp" #include "proc/asset/proc.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" using util::isnil; using std::string; diff --git a/tests/components/proc/asset/dependent-assets-test.cpp b/tests/components/proc/asset/dependent-assets-test.cpp index 8900592cf..e2234602d 100644 --- a/tests/components/proc/asset/dependent-assets-test.cpp +++ b/tests/components/proc/asset/dependent-assets-test.cpp @@ -23,7 +23,7 @@ #include "lib/test/run.hpp" #include "proc/asset/testasset.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" #include "proc/asset/media.hpp" #include "proc/asset/clip.hpp" #include "lib/util.hpp" diff --git a/tests/components/proc/asset/identityofassetstest.cpp b/tests/components/proc/asset/identityofassetstest.cpp index 98ba41e84..d2fb11911 100644 --- a/tests/components/proc/asset/identityofassetstest.cpp +++ b/tests/components/proc/asset/identityofassetstest.cpp @@ -29,7 +29,7 @@ #include "proc/asset/media.hpp" #include "proc/asset/proc.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" using util::isnil; using std::string; diff --git a/tests/components/proc/asset/makecliptest.cpp b/tests/components/proc/asset/makecliptest.cpp index 0da91b126..7f9d0581c 100644 --- a/tests/components/proc/asset/makecliptest.cpp +++ b/tests/components/proc/asset/makecliptest.cpp @@ -28,7 +28,7 @@ #include "proc/assetmanager.hpp" #include "proc/asset/media.hpp" #include "proc/mobject/session/clip.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" using util::contains; using util::isnil; diff --git a/tests/components/proc/asset/mediastructurequerytest.cpp b/tests/components/proc/asset/mediastructurequerytest.cpp index c19ff7a91..2f5a58c53 100644 --- a/tests/components/proc/asset/mediastructurequerytest.cpp +++ b/tests/components/proc/asset/mediastructurequerytest.cpp @@ -28,7 +28,7 @@ #include "proc/asset/media.hpp" #include "proc/asset/proc.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" using util::isnil; using std::string; diff --git a/tests/components/proc/asset/orderingofassetstest.cpp b/tests/components/proc/asset/orderingofassetstest.cpp index b3c9a726f..d87b00d3b 100644 --- a/tests/components/proc/asset/orderingofassetstest.cpp +++ b/tests/components/proc/asset/orderingofassetstest.cpp @@ -28,7 +28,7 @@ #include "proc/asset/media.hpp" #include "proc/asset/proc.hpp" -#include "proc/asset/assetdiagnostics.hpp" +#include "proc/asset/asset-diagnostics.hpp" using util::isnil; using std::string; diff --git a/tests/components/proc/mobject/session/rebuildfixturetest.cpp b/tests/components/proc/mobject/session/rebuildfixturetest.cpp index 8a0612a0b..ae287786c 100644 --- a/tests/components/proc/mobject/session/rebuildfixturetest.cpp +++ b/tests/components/proc/mobject/session/rebuildfixturetest.cpp @@ -28,11 +28,11 @@ #include "lib/util.hpp" //#include -#include +#include #include //using boost::format; -using boost::bind; +using std::tr1::bind; using util::contains; using util::for_each; using std::string; diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index 25e794d0f..429abef00 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -59,14 +59,14 @@ test_lib_SOURCES = \ $(testlib_srcdir)/meta/config-flags-test.cpp \ $(testlib_srcdir)/query/queryutilstest.cpp \ $(testlib_srcdir)/removefromsettest.cpp \ - $(testlib_srcdir)/sanitizedidentifiertest.cpp \ + $(testlib_srcdir)/sanitised-identifier-test.cpp \ $(testlib_srcdir)/opaque-unchecked-buffer-test.cpp \ $(testlib_srcdir)/opaque-holder-test.cpp \ $(testlib_srcdir)/scoped-holder-test.cpp \ $(testlib_srcdir)/scopedholdertransfertest.cpp \ $(testlib_srcdir)/scoped-ptrvect-test.cpp \ - $(testlib_srcdir)/singletonsubclasstest.cpp \ - $(testlib_srcdir)/singletontest.cpp \ + $(testlib_srcdir)/singleton-subclass-test.cpp \ + $(testlib_srcdir)/singleton-test.cpp \ $(testlib_srcdir)/singletontestmocktest.cpp \ $(testlib_srcdir)/streamtypebasicstest.cpp \ $(testlib_srcdir)/streamtypelifecycletest.cpp \ diff --git a/tests/lib/meta/function-erasure-test.cpp b/tests/lib/meta/function-erasure-test.cpp index 4c0922e2e..3320dcc72 100644 --- a/tests/lib/meta/function-erasure-test.cpp +++ b/tests/lib/meta/function-erasure-test.cpp @@ -39,6 +39,8 @@ namespace typelist{ namespace test { using std::tr1::function; + using std::tr1::placeholders::_1; + using std::tr1::placeholders::_2; using std::tr1::bind; diff --git a/tests/lib/query/queryutilstest.cpp b/tests/lib/query/queryutilstest.cpp index b46447b7c..f7691edf0 100644 --- a/tests/lib/query/queryutilstest.cpp +++ b/tests/lib/query/queryutilstest.cpp @@ -28,7 +28,7 @@ #include "lib/query.hpp" #include "query/querydiagnostics.hpp" -#include +#include #include #include @@ -38,7 +38,8 @@ using util::isnil; using util::contains; using util::for_each; -using boost::bind; +using std::tr1::placeholders::_1; +using std::tr1::bind; using std::string; using std::cout; diff --git a/tests/lib/sanitizedidentifiertest.cpp b/tests/lib/sanitised-identifier-test.cpp similarity index 54% rename from tests/lib/sanitizedidentifiertest.cpp rename to tests/lib/sanitised-identifier-test.cpp index 058807661..7913795f1 100644 --- a/tests/lib/sanitizedidentifiertest.cpp +++ b/tests/lib/sanitised-identifier-test.cpp @@ -30,38 +30,34 @@ using std::cout; -namespace util - { - namespace test - { - +namespace util { +namespace test { - class SanitizedIdentifier_test : public Test - { - virtual void run (Arg) - { - print_clean ("Word"); - print_clean ("a Sentence"); - print_clean ("trailing Withespace\n \t"); - print_clean ("with a \t lot\n of Whitespace"); - print_clean ("with\"much (punctuation)[]!"); - print_clean ("§&Ω%€ leading garbage"); - print_clean ("mixed Ω garbage"); - print_clean ("Bääääh!!"); - print_clean ("§&Ω%€"); - } - - /** @test print the original and the sanitized string */ - void print_clean (const string org) + + class SanitizedIdentifier_test : public Test + { + virtual void run (Arg) { - cout << "'" << org << "' --> '" << sanitize(org) << "'\n"; + print_clean ("Word"); + print_clean ("a Sentence"); + print_clean ("trailing Withespace\n \t"); + print_clean ("with a \t lot\n of Whitespace"); + print_clean ("with\"much (punctuation)[]!"); + print_clean ("§&Ω%€ leading garbage"); + print_clean ("mixed Ω garbage"); + print_clean ("Bääääh!!"); + print_clean ("§&Ω%€"); } - }; - - LAUNCHER (SanitizedIdentifier_test, "unit common"); - - } // namespace test - -} // namespace util + /** @test print the original and the sanitised string */ + void print_clean (const string org) + { + cout << "'" << org << "' --> '" << sanitise(org) << "'\n"; + } + }; + + LAUNCHER (SanitizedIdentifier_test, "unit common"); + + +}} // namespace util::test diff --git a/tests/lib/singleton-subclass-test.cpp b/tests/lib/singleton-subclass-test.cpp new file mode 100644 index 000000000..3a925b70e --- /dev/null +++ b/tests/lib/singleton-subclass-test.cpp @@ -0,0 +1,162 @@ +/* + SingletonSubclass(Test) - actually creating a subclass of the Singleton Type + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + 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. + +* *****************************************************/ + + +#include "lib/test/run.hpp" +#include "lib/util.hpp" + +#include "testtargetobj.hpp" +#include "lib/singletonsubclass.hpp" + +#include +#include +#include + +using boost::lexical_cast; +using boost::format; +using util::isnil; +using std::string; +using std::cout; + + +namespace lumiera { +namespace test { + + + /** + * Target object to be instantiated as Singleton + * Allocates a variable amount of additional heap memory + * and prints diagnostic messages. + */ + class Interface : public TestTargetObj + { + public: + static int cnt; + static void setCountParam (uint c) { Interface::cnt = c; } + + virtual string identify() { return "Interface"; } + + protected: + Interface () : TestTargetObj(cnt) {} + virtual ~Interface() {} + + friend class singleton::StaticCreate; + friend class singleton::HeapCreate; + }; + + int Interface::cnt = 0; + + + class Impl : public Interface + { + public: + virtual string identify() { return "Implementation"; } + }; + + + // for checking the safety..... + class Impl_XXX : public Impl { }; + class Unrelated { }; + + + + + /******************************************************************* + * @test specialised variant of the Singleton Factory, for creating + * subclasses (implementation classes) without coupling the + * caller to the concrete class type. + * Expected results: an instance of the subclass is created. + * @see lumiera::Singleton + * @see lumiera::SingletonSubclassFactory + * @see lumiera::singleton::Adapter + */ + class SingletonSubclass_test : public Test + { + + virtual void run(Arg arg) + { + uint num= isnil(arg)? 1 : lexical_cast(arg[1]); + + cout << format("using the Singleton should create TargetObj(%d)...\n") % num; + + Interface::setCountParam(num); + + // marker to declare the concrete type to be created + singleton::UseSubclass typeinfo; + + // define an instance of the Singleton factory, + // Specialised to create the concrete Type passed in + SingletonSubclassFactory instance (typeinfo); + + // Now use the Singleton factory... + // Note: we get the Base type + Interface& t1 = instance(); + Interface& t2 = instance(); + + ASSERT ( &t1 == &t2, "not a Singleton, got two different instances." ); + + cout << "calling a non-static method on the Singleton-" + << t1.identify() << "\n" + << string (t1) << "\n"; + +///////////////////////////////////////////////////////////////////////////////TODO: find a way to configure NoBug to throw in case of assertion +///////////////////////////////////////////////////////////////////////////////TODO: just for the proc tests. Also find a better way to configure +///////////////////////////////////////////////////////////////////////////////TODO: the non-release check. Then re-enable these checks... +//#ifdef DEBUG +// verify_error_detection (); +//#endif + } + + + + void verify_error_detection () + { + + singleton::UseSubclass more_special_type; + + try + { + SingletonSubclassFactory instance (more_special_type); + cout << "was able to re-configure the SingletonSubclassFactory " + "with another type. This should be detected in debug mode\n"; + } + catch (...) + { + ASSERT (lumiera_error () == error::LUMIERA_ERROR_ASSERTION); + } + + + // Note: the following won't compile, because the "subclass" isn't a subclass... + // + // singleton::UseSubclass yet_another_type; + // SingletonSubclassFactory instance (yet_another_type); + } + }; + + + + /** Register this test class... */ + LAUNCHER (SingletonSubclass_test, "unit common"); + + + +}} // namespace lumiera::test diff --git a/tests/lib/singleton-test.cpp b/tests/lib/singleton-test.cpp new file mode 100644 index 000000000..a5a6fdd3f --- /dev/null +++ b/tests/lib/singleton-test.cpp @@ -0,0 +1,137 @@ +/* + Singleton(Test) - unittest for our Singleton template + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + 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. + +* *****************************************************/ + + +#include "lib/test/run.hpp" +#include "lib/util.hpp" + +#include "testtargetobj.hpp" +#include "lib/singleton.hpp" + +#include +#include +#include +#include + +using std::tr1::function; +using boost::lexical_cast; +using boost::format; +using util::isnil; +using std::string; +using std::cout; + + +namespace lumiera { +namespace test { + + + /** + * Target object to be instantiated as Singleton + * Allocates a variable amount of additional heap memory + * and prints diagnostic messages. + */ + class TargetObj : public TestTargetObj + { + public: + static int cnt; + static void setCountParam (uint c) { TargetObj::cnt = c; } + protected: + TargetObj () : TestTargetObj(cnt) {} + + friend class singleton::StaticCreate; + friend class singleton::HeapCreate; + }; + + int TargetObj::cnt = 0; + + + + + + + + /******************************************************************* + * @test implement a Singleton class using our Singleton Template. + * Expected results: no memory leaks. + * @see lumiera::Singleton + * @see lumiera::singleton::StaticCreate + * @see lumiera::singleton::HeapCreate + */ + class Singleton_test : public Test + { + typedef function InstanceAccessFunc; + InstanceAccessFunc instance; + + virtual void run(Arg arg) + { + uint num= isnil(arg)? 1 : lexical_cast(arg[1]); + + testStaticallyAllocatedSingleton (num++); + testHeapAllocatedSingleton (num++); + } + + + /** @test parametrize the Singleton creation such as to create + * the single TargetObj instance as a static variable. + */ + void testStaticallyAllocatedSingleton (uint num) + { + SingletonFactory single; + instance = single; + useInstance (num, "statically allocated"); + } + + /** @test parametrize the Singleton creation such as to create + * the single TargetObj instance allocated on the Heap + * and deleted automatically at application shutdown. + */ + void testHeapAllocatedSingleton (uint num) + { + SingletonFactory single; + instance = single; + useInstance (num, "heap allocated"); + } + + + + void useInstance (uint num, string kind) + { + cout << format("testing TargetObj(%d) as Singleton(%s)\n") % num % kind; + TargetObj::setCountParam(num); + TargetObj& t1 = instance(); + TargetObj& t2 = instance(); + + ASSERT ( &t1 == &t2, "not a Singleton, got two different instances." ); + + cout << "calling a non-static method on the Singleton instance\n" + << string (t1) << "\n"; + } + }; + + + + /** Register this test class... */ + LAUNCHER (Singleton_test, "unit common"); + + + +}} // namespace lumiera::test diff --git a/tests/lib/singletonsubclasstest.cpp b/tests/lib/singletonsubclasstest.cpp deleted file mode 100644 index 318ed76e1..000000000 --- a/tests/lib/singletonsubclasstest.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - SingletonSubclass(Test) - actually creating a subclass of the Singleton Type - - Copyright (C) Lumiera.org - 2008, Hermann Vosseler - - 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. - -* *****************************************************/ - - -#include "lib/test/run.hpp" -#include "lib/util.hpp" - -#include "testtargetobj.hpp" -#include "lib/singletonsubclass.hpp" - -#include -#include -#include - -using boost::lexical_cast; -using boost::format; -using util::isnil; -using std::string; -using std::cout; - - -namespace lumiera - { - namespace test - { - - - /** - * Target object to be instantiated as Singleton - * Allocates a variable amount of additional heap memory - * and prints diagnostic messages. - */ - class Interface : public TestTargetObj - { - public: - static int cnt; - static void setCountParam (uint c) { Interface::cnt = c; } - - virtual string identify() { return "Interface"; } - - protected: - Interface () : TestTargetObj(cnt) {} - virtual ~Interface() {} - - friend class singleton::StaticCreate; - friend class singleton::HeapCreate; - }; - - int Interface::cnt = 0; - - - class Impl : public Interface - { - public: - virtual string identify() { return "Implementation"; } - }; - - - // for checking the safety..... - class Impl_XXX : public Impl { }; - class Unrelated { }; - - - - - /******************************************************************* - * @test specialised variant of the Singleton Factory, for creating - * subclasses (implementation classes) without coupling the - * caller to the concrete class type. - * Expected results: an instance of the subclass is created. - * @see lumiera::Singleton - * @see lumiera::SingletonSubclassFactory - * @see lumiera::singleton::Adapter - */ - class SingletonSubclass_test : public Test - { - - virtual void run(Arg arg) - { - uint num= isnil(arg)? 1 : lexical_cast(arg[1]); - - cout << format("using the Singleton should create TargetObj(%d)...\n") % num; - - Interface::setCountParam(num); - - // marker to declare the concrete type to be created - singleton::UseSubclass typeinfo; - - // define an instance of the Singleton factory, - // Specialised to create the concrete Type passed in - SingletonSubclassFactory instance (typeinfo); - - // Now use the Singleton factory... - // Note: we get the Base type - Interface& t1 = instance(); - Interface& t2 = instance(); - - ASSERT ( &t1 == &t2, "not a Singleton, got two different instances." ); - - cout << "calling a non-static method on the Singleton-" - << t1.identify() << "\n" - << string (t1) << "\n"; - -///////////////////////////////////////////////////////////////////////////////TODO: find a way to configure NoBug to throw in case of assertion -///////////////////////////////////////////////////////////////////////////////TODO: just for the proc tests. Also find a better way to configure -///////////////////////////////////////////////////////////////////////////////TODO: the non-release check. Then re-enable these checks... -//#ifdef DEBUG -// verify_error_detection (); -//#endif - } - - - - void verify_error_detection () - { - - singleton::UseSubclass more_special_type; - - try - { - SingletonSubclassFactory instance (more_special_type); - cout << "was able to re-configure the SingletonSubclassFactory " - "with another type. This should be detected in debug mode\n"; - } - catch (...) - { - ASSERT (lumiera_error () == error::LUMIERA_ERROR_ASSERTION); - } - - - // Note: the following won't compile, because the "subclass" isn't a subclass... - // - // singleton::UseSubclass yet_another_type; - // SingletonSubclassFactory instance (yet_another_type); - } - }; - - - - /** Register this test class... */ - LAUNCHER (SingletonSubclass_test, "unit common"); - - - - } // namespace test - -} // namespace lumiera diff --git a/tests/lib/singletontest.cpp b/tests/lib/singletontest.cpp deleted file mode 100644 index 88fc923d7..000000000 --- a/tests/lib/singletontest.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - Singleton(Test) - unittest for our Singleton template - - Copyright (C) Lumiera.org - 2008, Hermann Vosseler - - 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. - -* *****************************************************/ - - -#include "lib/test/run.hpp" -#include "lib/util.hpp" - -#include "testtargetobj.hpp" -#include "lib/singleton.hpp" - -#include -#include -#include - -using boost::lexical_cast; -using boost::format; -using util::isnil; -using std::string; -using std::cout; - - -namespace lumiera - { - namespace test - { - - - /** - * Target object to be instantiated as Singleton - * Allocates a variable amount of additional heap memory - * and prints diagnostic messages. - */ - class TargetObj : public TestTargetObj - { - public: - static int cnt; - static void setCountParam (uint c) { TargetObj::cnt = c; } - protected: - TargetObj () : TestTargetObj(cnt) {} - - friend class singleton::StaticCreate; - friend class singleton::HeapCreate; - }; - - int TargetObj::cnt = 0; - - - - - - - - /******************************************************************* - * @test implement a Singleton class using our Singleton Template. - * Expected results: no memory leaks. - * @see lumiera::Singleton - * @see lumiera::singleton::StaticCreate - * @see lumiera::singleton::HeapCreate - */ - class Singleton_test : public Test - { - typedef boost::function InstanceAccessFunc; - InstanceAccessFunc instance; - - virtual void run(Arg arg) - { - uint num= isnil(arg)? 1 : lexical_cast(arg[1]); - - testStaticallyAllocatedSingleton (num++); - testHeapAllocatedSingleton (num++); - } - - - /** @test parametrize the Singleton creation such as to create - * the single TargetObj instance as a static variable. - */ - void testStaticallyAllocatedSingleton (uint num) - { - SingletonFactory single; - instance = single; - useInstance (num, "statically allocated"); - } - - /** @test parametrize the Singleton creation such as to create - * the single TargetObj instance allocated on the Heap - * and deleted automatically at application shutdown. - */ - void testHeapAllocatedSingleton (uint num) - { - SingletonFactory single; - instance = single; - useInstance (num, "heap allocated"); - } - - - - void useInstance (uint num, string kind) - { - cout << format("testing TargetObj(%d) as Singleton(%s)\n") % num % kind; - TargetObj::setCountParam(num); - TargetObj& t1 = instance(); - TargetObj& t2 = instance(); - - ASSERT ( &t1 == &t2, "not a Singleton, got two different instances." ); - - cout << "calling a non-static method on the Singleton instance\n" - << string (t1) << "\n"; - } - }; - - - - /** Register this test class... */ - LAUNCHER (Singleton_test, "unit common"); - - - - } // namespace test - -} // namespace lumiera diff --git a/tests/lib/streamtypelifecycletest.cpp b/tests/lib/streamtypelifecycletest.cpp index af646bf1c..9ef328d3d 100644 --- a/tests/lib/streamtypelifecycletest.cpp +++ b/tests/lib/streamtypelifecycletest.cpp @@ -50,7 +50,7 @@ namespace lumiera { UNIMPLEMENTED ("setup basic dummy-type-info"); } - namespace // enroll this basic setup to be triggered when the type system is reset + namespace // enrol this basic setup to be triggered when the type system is reset { LifecycleHook _schedule_at_reset (ON_STREAMTYPES_RESET, &setup_basicDummyTypeInfo); } diff --git a/tests/lib/visitingtoolconcept.cpp b/tests/lib/visitingtoolconcept.cpp index 8508cdb0d..056a103df 100644 --- a/tests/lib/visitingtoolconcept.cpp +++ b/tests/lib/visitingtoolconcept.cpp @@ -235,7 +235,7 @@ namespace lumiera template inline void - enroll(TOOLImpl* typeref) + enrol(TOOLImpl* typeref) { Tag& index = Tag::get (typeref); if (is_known (index)) @@ -272,7 +272,7 @@ namespace lumiera Applicable () { TOOLImpl* typeref = 0; - Dispatcher::instance().enroll (typeref); + Dispatcher::instance().enrol (typeref); } virtual ~Applicable () {}