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(a)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(a)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