
J'ai rajouté vite fait qq explications là : http://www.lrde.epita.fr/cgi-bin/twiki/view/Know/StaticDiamondHierarchies Index: metalic/ChangeLog from Nicolas Burrus <burrus_n@lrde.epita.fr> * mlc/type.hh (any_with_diamond): Use a static offset instead of an pointer member to find the exact type instance. (mlc_init_static_hierarchy): Adjust consequently. Index: olena/ChangeLog from Nicolas Burrus <burrus_n@lrde.epita.fr> * oln/core/abstract/image.hh: Uncomment copy constructor. Index: metalic/mlc/type.hh --- metalic/mlc/type.hh Thu, 07 Aug 2003 10:08:50 +0200 burrus_n (oln/c/21_type.hh 1.25 640) +++ metalic/mlc/type.hh Mon, 01 Sep 2003 20:06:36 +0200 burrus_n (oln/c/21_type.hh 1.25 640) @@ -51,29 +51,42 @@ public: typedef E exact_type; - E& exact() { assert(exact_this != 0); return *exact_this; } - const E& exact() const { assert(exact_this != 0); return *exact_this; } - - static std::string name() + E& exact() { - return std::string("any_with_diamond<") + E::name() + ">"; + assert(offset_assigned); + return *(E*)((char*)this - exact_offset); + } + const E& exact() const + { + assert(offset_assigned); + return *(const E*)((const char*)this - exact_offset); } - protected: - any_with_diamond() + static std::string name() { - exact_this = 0; + return std::string("any_with_diamond<") + E::name() + ">"; } - protected: - // This stores the actual value of the exact type pointer. This - // enables diamond hierarchies, as static_cast cannot perform it - // and reinterpret_cast or (Exact*)(void*) cast are unsafe and - // compiler dependent. This member should be initialized by every - // concrete classes, using the mlc_init_static_hierarchy macro. - E* exact_this; + public: + // This stores the actual value of the offset between the this + // pointer and the this pointer of the exact type. This enables + // diamond hierarchies, as static_cast cannot perform it and + // reinterpret_cast or (Exact*)(void*) cast are unsafe and + // compiler dependent. These members should be initialized by + // every concrete classes, using the mlc_init_static_hierarchy + // macro. + static int exact_offset; + // This Boolean determines if the exact_offset value has already + // been affected. + static bool offset_assigned; }; + template <class E> + int any_with_diamond<E>::exact_offset = 0; + + template <class E> + bool any_with_diamond<E>::offset_assigned = false; + // Warning, this class does not allow diamond hierarchies, consider // any_with_diamond if you really need it. @@ -134,20 +147,27 @@ // mlc_init_static_hierarchy. template <class Exact, class Final> - struct assign_exact_this + struct assign_exact_offset { - template <class V> - static void doit(V*, Exact**) + template <class E> + static void doit(const E&) {} }; template <> - struct assign_exact_this<mlc::final, mlc::final> + struct assign_exact_offset<mlc::final, mlc::final> + { + template <class E> + static void doit(const E* t) { - template <class U> - static void doit(U* src, U** dest) + if (!mlc_hierarchy::any_with_diamond<E>::offset_assigned) { - *dest = src; + mlc_hierarchy::any_with_diamond<E>::exact_offset = + (const char*) + static_cast<const mlc_hierarchy::any_with_diamond<E>*>(t) + - (const char*) t; + mlc_hierarchy::any_with_diamond<E>::offset_assigned = true; + } } }; @@ -265,6 +285,6 @@ `--------------------------*/ # define mlc_init_static_hierarchy(Exact) \ -mlc::assign_exact_this<Exact, mlc::final>::doit(this, &(this->exact_this)) +mlc::assign_exact_offset<Exact, mlc::final>::doit(this) #endif // ! METALIC_TYPE_HH Index: olena/oln/core/abstract/image.hh --- olena/oln/core/abstract/image.hh Mon, 25 Aug 2003 11:47:33 +0200 burrus_n (oln/t/25_image.hh 1.18 640) +++ olena/oln/core/abstract/image.hh Mon, 01 Sep 2003 19:52:32 +0200 burrus_n (oln/t/25_image.hh 1.18 640) @@ -185,11 +185,11 @@ } protected: - image() {} - //image(self_type& rhs) {} + image(self_type& rhs) + {}; }; } // end of namespace abstract
participants (1)
-
Nicolas Burrus