diff --git a/src/lib/functor-util.hpp b/src/lib/functor-util.hpp index 4512d54d5..92ed46633 100644 --- a/src/lib/functor-util.hpp +++ b/src/lib/functor-util.hpp @@ -178,12 +178,12 @@ namespace std { * @note use with caution. Hash is calculated * relying on undocumented boost internals. */ - template - inline lib::HashVal - hash_value (function const& fun) - { - return util::rawHashValue (fun); - } +// template +// inline lib::HashVal +// hash_value (function const& fun) +// { +// return util::rawHashValue (fun); +// } } diff --git a/src/steam/engine/type-handler.hpp b/src/steam/engine/type-handler.hpp index 47359afd7..cf49bcd9e 100644 --- a/src/steam/engine/type-handler.hpp +++ b/src/steam/engine/type-handler.hpp @@ -28,7 +28,7 @@ ** "clean up" after usage. ** ** Within the Lumiera Engine, the BufferProvider default implementation utilises instances - ** of TypeHandler to \em describe specific buffer types capable of managing an attached object, + ** of TypeHandler to _describe specific buffer types_ capable of managing an attached object, ** or requiring some other kind of special treatment of the memory area used for the buffer. ** This BufferDescriptor is embodied into the BufferMetadata::Key and used later on to invoke ** the contained ctor / dtor functors, passing a concrete buffer (memory area). @@ -84,6 +84,16 @@ namespace engine { X* embedded = static_cast (storageBuffer); embedded->~X(); } + + template + inline HashVal + deriveCombinedTypeIdenity() + { + HashVal hash{0}; + boost::hash_combine (hash, typeid(CTOR).hash_code()); + boost::hash_combine (hash, typeid(DTOR).hash_code()); + return hash; + } }//(End)placement-new helpers @@ -97,8 +107,14 @@ namespace engine { * special treatment of a buffer space. When defined, the buffer * will be prepared on locking and cleanup will be invoked * automatically when releasing. - * @warning comparison and hash values rely on internals of the - * std::function implementation and might not be 100% accurate + * @warning comparison and hash values are based merely on the type + * of the Ctor and Dtor functions -- so all type handlers bound + * to the same functor type count as equivalent. This might not + * be what you'd expect, however, there is no sane way to test + * for equivalence of functors anyway. In the typical usage, + * a TypeHandler will be created by TypeHandler::create(), + * and thus will be dedicated to a given type to be placed + * into the storage buffer. */ struct TypeHandler { @@ -106,11 +122,13 @@ namespace engine { DoInBuffer createAttached; DoInBuffer destroyAttached; + HashVal identity; /** build an invalid NIL TypeHandler */ TypeHandler() : createAttached() , destroyAttached() + , identity{0} { } /** build a TypeHandler @@ -124,6 +142,7 @@ namespace engine { TypeHandler(CTOR ctor, DTOR dtor) : createAttached (ctor) , destroyAttached (dtor) + , identity{deriveCombinedTypeIdenity()} { } /** builder function defining a TypeHandler @@ -154,22 +173,14 @@ namespace engine { friend HashVal hash_value (TypeHandler const& handler) { - HashVal hash(0); - if (handler.isValid()) - { - boost::hash_combine(hash, handler.createAttached); - boost::hash_combine(hash, handler.destroyAttached); - } - return hash; + return handler.identity; } friend bool operator== (TypeHandler const& left, TypeHandler const& right) { return (not left.isValid() and not right.isValid()) - || ( util::rawComparison(left.createAttached, right.createAttached) - && util::rawComparison(left.destroyAttached, right.destroyAttached) - ); + || (left.identity == right.identity); } friend bool operator!= (TypeHandler const& left, TypeHandler const& right) diff --git a/tests/library/functor-util-test.cpp b/tests/library/functor-util-test.cpp index da5a29f3c..ad1e11c7b 100644 --- a/tests/library/functor-util-test.cpp +++ b/tests/library/functor-util-test.cpp @@ -67,8 +67,8 @@ namespace test { virtual void run (Arg) { - verifyBruteForceComparison(); - verifyHashThroughBackdoor(); +// verifyBruteForceComparison(); +// verifyHashThroughBackdoor(); } typedef function Fvi; @@ -78,129 +78,129 @@ namespace test { /** @test workaround for the missing functor comparison operator */ - void - verifyBruteForceComparison() - { - Fvi f0; - Fvi f1 (fun1); - Fvi f2 (fun2); - - CHECK (!rawComparison(f0, f1)); - CHECK (!rawComparison(f1, f2)); - CHECK (!rawComparison(f0, f2)); - - Fvi f22 (f2); - CHECK ( rawComparison(f2, f22)); - - f1 = f2; - CHECK ( rawComparison(f1, f2)); - - CHECK (!rawComparison(f0, Fvi())); // note: can't detect they are equivalent - CHECK (!rawComparison(f0, Fiv())); - - f1 = bind (fun2, _1); - CHECK (!rawComparison(f1, f2)); - - Dummy dum1, dum2; - Fvi fm1 = bind (&Dummy::gummi, dum1, _1); - Fvi fm2 = bind (&Dummy::gummi, dum2, _1); - Fvv fm3 = bind (&Dummy::gummi, dum1, 23); - Fvv fm4 = bind (&Dummy::gummi, dum1, 24); - Fvv fm5 = bind (&Dummy::gummi, dum2, 24); - Fvv fm6 = bind (&Dummy::gummi, dum2, 24); - - CHECK (!rawComparison(f1, fm1)); - - CHECK (!rawComparison(fm1, fm2)); - CHECK (!rawComparison(fm1, fm3)); - CHECK (!rawComparison(fm1, fm4)); - CHECK (!rawComparison(fm1, fm5)); - CHECK (!rawComparison(fm1, fm6)); - CHECK (!rawComparison(fm2, fm3)); - CHECK (!rawComparison(fm2, fm4)); - CHECK (!rawComparison(fm2, fm5)); - CHECK (!rawComparison(fm2, fm6)); - CHECK (!rawComparison(fm3, fm4)); - CHECK (!rawComparison(fm3, fm5)); - CHECK (!rawComparison(fm3, fm6)); - CHECK (!rawComparison(fm4, fm5)); // note: same argument but different functor instance - CHECK (!rawComparison(fm4, fm6)); - CHECK (!rawComparison(fm5, fm6)); // again: can't detect they are equivalent - } +// void +// verifyBruteForceComparison() +// { +// Fvi f0; +// Fvi f1 (fun1); +// Fvi f2 (fun2); +// +// CHECK (!rawComparison(f0, f1)); +// CHECK (!rawComparison(f1, f2)); +// CHECK (!rawComparison(f0, f2)); +// +// Fvi f22 (f2); +// CHECK ( rawComparison(f2, f22)); +// +// f1 = f2; +// CHECK ( rawComparison(f1, f2)); +// +// CHECK (!rawComparison(f0, Fvi())); // note: can't detect they are equivalent +// CHECK (!rawComparison(f0, Fiv())); +// +// f1 = bind (fun2, _1); +// CHECK (!rawComparison(f1, f2)); +// +// Dummy dum1, dum2; +// Fvi fm1 = bind (&Dummy::gummi, dum1, _1); +// Fvi fm2 = bind (&Dummy::gummi, dum2, _1); +// Fvv fm3 = bind (&Dummy::gummi, dum1, 23); +// Fvv fm4 = bind (&Dummy::gummi, dum1, 24); +// Fvv fm5 = bind (&Dummy::gummi, dum2, 24); +// Fvv fm6 = bind (&Dummy::gummi, dum2, 24); +// +// CHECK (!rawComparison(f1, fm1)); +// +// CHECK (!rawComparison(fm1, fm2)); +// CHECK (!rawComparison(fm1, fm3)); +// CHECK (!rawComparison(fm1, fm4)); +// CHECK (!rawComparison(fm1, fm5)); +// CHECK (!rawComparison(fm1, fm6)); +// CHECK (!rawComparison(fm2, fm3)); +// CHECK (!rawComparison(fm2, fm4)); +// CHECK (!rawComparison(fm2, fm5)); +// CHECK (!rawComparison(fm2, fm6)); +// CHECK (!rawComparison(fm3, fm4)); +// CHECK (!rawComparison(fm3, fm5)); +// CHECK (!rawComparison(fm3, fm6)); +// CHECK (!rawComparison(fm4, fm5)); // note: same argument but different functor instance +// CHECK (!rawComparison(fm4, fm6)); +// CHECK (!rawComparison(fm5, fm6)); // again: can't detect they are equivalent +// } /** @test workaround for missing standard hash * calculation for functor objects. * Workaround relying on boost * implementation internals */ - void - verifyHashThroughBackdoor() - { - Fvi f0; - Fvi f1 (fun1); - Fvi f2 (fun2); - Fvi f22 (f2); - - hash calculateHash; - CHECK (calculateHash (f0)); - CHECK (calculateHash (f1)); - CHECK (calculateHash (f2)); - CHECK (calculateHash (f22)); - - HashVal h0 = calculateHash (f0); - HashVal h1 = calculateHash (f1); - HashVal h2 = calculateHash (f2); - HashVal h22 = calculateHash (f22); - - CHECK (h0 != h1); - CHECK (h0 != h2); - CHECK (h1 != h2); - - CHECK (h2 == h22); - - f1 = f2; - h1 = calculateHash (f1); - CHECK (h1 == h2); - CHECK (h1 != h0); - - CHECK (h0 != calculateHash (Fvi())); // note: equivalence not detected - - // checking functors based on member function(s) - Dummy dum1, dum2; - Fvi fm1 = bind (&Dummy::gummi, dum1, _1); - Fvi fm2 = bind (&Dummy::gummi, dum2, _1); - Fvv fm3 = bind (&Dummy::gummi, dum1, 23); - Fvv fm4 = bind (&Dummy::gummi, dum1, 24); - Fvv fm5 = bind (&Dummy::gummi, dum2, 24); - Fvv fm6 = bind (&Dummy::gummi, dum2, 24); - - HashVal hm1 = calculateHash (fm1); - HashVal hm2 = calculateHash (fm2); - - hash calculateHashVV; - HashVal hm3 = calculateHashVV (fm3); - HashVal hm4 = calculateHashVV (fm4); - HashVal hm5 = calculateHashVV (fm5); - HashVal hm6 = calculateHashVV (fm6); - - CHECK (h1 != hm1); - - CHECK (hm1 != hm2); - CHECK (hm1 != hm3); - CHECK (hm1 != hm4); - CHECK (hm1 != hm5); - CHECK (hm1 != hm6); - CHECK (hm2 != hm3); - CHECK (hm2 != hm4); - CHECK (hm2 != hm5); - CHECK (hm2 != hm6); - CHECK (hm3 != hm4); - CHECK (hm3 != hm5); - CHECK (hm3 != hm6); - CHECK (hm4 != hm5); - CHECK (hm4 != hm6); - CHECK (hm5 != hm6); // again: unable to detect the equivalence - } +// void +// verifyHashThroughBackdoor() +// { +// Fvi f0; +// Fvi f1 (fun1); +// Fvi f2 (fun2); +// Fvi f22 (f2); +// +// hash calculateHash; +// CHECK (calculateHash (f0)); +// CHECK (calculateHash (f1)); +// CHECK (calculateHash (f2)); +// CHECK (calculateHash (f22)); +// +// HashVal h0 = calculateHash (f0); +// HashVal h1 = calculateHash (f1); +// HashVal h2 = calculateHash (f2); +// HashVal h22 = calculateHash (f22); +// +// CHECK (h0 != h1); +// CHECK (h0 != h2); +// CHECK (h1 != h2); +// +// CHECK (h2 == h22); +// +// f1 = f2; +// h1 = calculateHash (f1); +// CHECK (h1 == h2); +// CHECK (h1 != h0); +// +// CHECK (h0 != calculateHash (Fvi())); // note: equivalence not detected +// +// // checking functors based on member function(s) +// Dummy dum1, dum2; +// Fvi fm1 = bind (&Dummy::gummi, dum1, _1); +// Fvi fm2 = bind (&Dummy::gummi, dum2, _1); +// Fvv fm3 = bind (&Dummy::gummi, dum1, 23); +// Fvv fm4 = bind (&Dummy::gummi, dum1, 24); +// Fvv fm5 = bind (&Dummy::gummi, dum2, 24); +// Fvv fm6 = bind (&Dummy::gummi, dum2, 24); +// +// HashVal hm1 = calculateHash (fm1); +// HashVal hm2 = calculateHash (fm2); +// +// hash calculateHashVV; +// HashVal hm3 = calculateHashVV (fm3); +// HashVal hm4 = calculateHashVV (fm4); +// HashVal hm5 = calculateHashVV (fm5); +// HashVal hm6 = calculateHashVV (fm6); +// +// CHECK (h1 != hm1); +// +// CHECK (hm1 != hm2); +// CHECK (hm1 != hm3); +// CHECK (hm1 != hm4); +// CHECK (hm1 != hm5); +// CHECK (hm1 != hm6); +// CHECK (hm2 != hm3); +// CHECK (hm2 != hm4); +// CHECK (hm2 != hm5); +// CHECK (hm2 != hm6); +// CHECK (hm3 != hm4); +// CHECK (hm3 != hm5); +// CHECK (hm3 != hm6); +// CHECK (hm4 != hm5); +// CHECK (hm4 != hm6); +// CHECK (hm5 != hm6); // again: unable to detect the equivalence +// } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a1aeb3065..cdba0726f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -46127,6 +46127,42 @@ + + + + + + + + + + + +

+ d.h. wir brauchen keine Äquivalenz? +

+ + +
+
+ + + + + + + + + + + + + + + + + +