diff --git a/src/lib/hash-indexed.hpp b/src/lib/hash-indexed.hpp index f1ee66aee..bc6d8e25d 100644 --- a/src/lib/hash-indexed.hpp +++ b/src/lib/hash-indexed.hpp @@ -1,5 +1,5 @@ /* - HA-ID.hpp - generic hash based and hierarchically typed ID + HASH-INDEXED.hpp - generic hash based and typed ID Copyright (C) Lumiera.org 2009, Hermann Vosseler @@ -21,7 +21,7 @@ */ -/** @file ha-id.hpp +/** @file hash-indexed.hpp ** A template for generating hash based ID tags carrying compile-time type info. ** While the actual storage is assumed to be based on a POD, the type info is crucial ** to circumvent the problems with an "object" base class. Frequently, the need to @@ -37,9 +37,9 @@ ** - based on a configurable storage/implementation of the actual hash or index code. ** - tied to a specific hierarchy of objects (template parameter "BA") ** - providing an additional template parameter to pass the desired type info - ** - establishing an type hierarchy relation between ID template instances, such that - ** the IDs typed to the derived/specialised objects can stand-in for the generic - ** ID typed to the base class. + ** - establishing an type hierarchy relation between ID related to the base class + ** and the IDs denoting specific subclasses, such that the latter can stand-in + ** for the generic ID. ** - providing a Mixin, which allows any hierarchy to use this facility without ** much code duplication. ** @@ -50,8 +50,8 @@ -#ifndef LIB_HA_ID_H -#define LIB_HA_ID_H +#ifndef LIB_HASH_INDEXED_H +#define LIB_HASH_INDEXED_H //#include "lib/util.hpp" @@ -73,22 +73,29 @@ namespace lib { }; - template + /************************************************************ + * A Mixin to add a private ID type to the target class, + * together with storage to hold an instance of this ID, + * getter and setter, and a templated version of the ID type + * which can be used to pass on specific subclass type info. + */ + template struct HashIndexed { - /** - * Generic hash based and hierarchically typed ID - * @todo WIP maybe also usable for assets? + + /** + * generic hash based ID, corresponding to the base class BA */ - template - struct Id; - - struct ID : LuidH + struct ID : IMP { - ID () : LuidH () {} - ID (BA const& ref) : LuidH (ref.getID()) {} + ID () : IMP () {} + ID (BA const& ref) : IMP (ref.getID()) {} + ID (IMP const& ir) : IMP (ir) {} }; + /** + * Hash based ID, typed to a specific subclass of BA + */ template struct Id : ID { @@ -96,18 +103,21 @@ namespace lib { Id (T const& ref) : ID (ref) {} }; - ID const& getID() const + ID const& + getID () const { return id_; } - void resetID(HashIndexed const& ref) + + void + assignID (HashIndexed const& ref) { this->id_ = ref.getID(); } - void resetID(ID const& ref) ///< @todo this mutator should be removed in the final version to keep the actual hash opaque - { - this->id_.dummy_ = ref.dummy_; - } + + protected: + HashIndexed () : id_() {} + HashIndexed (IMP const& iref) : id_(iref) {} private: ID id_; diff --git a/tests/40components.tests b/tests/40components.tests index bad8b8be3..afa9451e2 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -215,7 +215,7 @@ out: dtor ~TargetObj(12) successful END -PLANNED "HaID_test" HaID_test < @@ -23,12 +23,12 @@ #include "lib/test/run.hpp" -#include "lib/ha-id.hpp" +#include "lib/hash-indexed.hpp" -#include +//#include #include -using boost::format; +//using boost::format; //using std::string; using std::cout; @@ -40,49 +40,56 @@ namespace test{ struct Base { - int ii_; + long ii_; }; - struct TestA : Base, HashIndexed + struct TestB : Base, HashIndexed { + TestB () {} + TestB (ID const& refID) : HashIndexed(refID) {} }; - struct TestBA : TestA {}; - struct TestBB : TestA {}; + struct TestDA : TestB {}; + struct TestDB : TestB {}; /*************************************************************************** * @test proof-of-concept test for a generic hash based and typed ID struct. - * @see lib::HaID + * @see lib::HashIndexed::Id */ - class HaID_test : public Test + class HashIndexed_test : public Test { virtual void run (Arg) { - format fmt ("sizeof( %s ) = %d\n"); + TestB::Id idDA; - /////////////////////////////////TODO - TestA::Id idBB1; + TestB bb (idDA); - TestBA bab; - bab.resetID (idBB1); + TestB::Id idDB1 ; + TestB::Id idDB2 (idDB1); - TestA::Id idBA1 (bab); + ASSERT (sizeof (idDB1) == sizeof (idDA) ); + ASSERT (sizeof (TestB::ID) == sizeof (LuidH)); + ASSERT (sizeof (TestDA) == sizeof (LuidH) + sizeof (Base)); - cout << fmt % "TestBA" % sizeof(bab); - cout << fmt % "Id" % sizeof(idBA1); - cout << fmt % "Id" % sizeof(idBB1); + ASSERT (idDA.dummy_ == bb.getID().dummy_); + ASSERT (idDB1.dummy_ == idDB2.dummy_); - ASSERT (idBA1.dummy_ == idBB1.dummy_); + TestDA d1; + TestDA d2; + ASSERT (d1.getID().dummy_ != d2.getID().dummy_); + + d2 = d1; + ASSERT (d1.getID().dummy_ == d2.getID().dummy_); } }; /** Register this test class... */ - LAUNCHER (HaID_test, "unit common"); + LAUNCHER (HashIndexed_test, "unit common"); }} // namespace lib::test