https://svn.lrde.epita.fr/svn/oln/trunk/olena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Polish the accesses to bbox_<point> as a virtual type.
* oln/core/gen/bbox.hh (oln::bbox_::self_t): Rename as...
(oln::bbox_::self_type): ...this.
Make it public.
(oln::bbox_::super_t): Adjust.
* oln/core/gen/topo_lbbox.hh
(vtypes< topo_lbbox_<point> >::bbox_type): Adjust.
* oln/core/gen/topo_bbox.hh (oln::vtypes< topo_lbbox_<point> >):
Define this virtul type using `bbox_<point>::self_t' instead of
just `bbox_<point>' to force the instiantiation of
oln::bbox_<point> at this point.
(oln::topo_bbox_<point>::bbox_t): Use oln_type_of to define it.
bbox.hh | 9 +++++++--
topo_bbox.hh | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
topo_lbbox.hh | 2 +-
3 files changed, 62 insertions(+), 5 deletions(-)
Index: oln/core/gen/bbox.hh
--- oln/core/gen/bbox.hh (revision 647)
+++ oln/core/gen/bbox.hh (working copy)
@@ -72,8 +72,13 @@
class bbox_ : public point_set_entry< bbox_<point_t> >,
private mlc::assert_< mlc_is_a(point_t, abstract::point) >
{
- typedef bbox_<point_t> self_t;
- typedef point_set_entry<self_t> super_t;
+ // Make self_type public so that is can be used to define a
+ // virtual type of oln::topo_bbox_ and oln::topo_lbbox_.
+ public:
+ typedef bbox_<point_t> self_type;
+
+ private:
+ typedef point_set_entry<self_type> super_t;
typedef oln_type_of(point_t, coord) coord_t;
Index: oln/core/gen/topo_bbox.hh
--- oln/core/gen/topo_bbox.hh (revision 647)
+++ oln/core/gen/topo_bbox.hh (working copy)
@@ -52,7 +52,59 @@
template <typename point>
struct vtypes< topo_bbox_<point> >
{
- typedef bbox_<point> bbox_type;
+ /* Trick to force the instantiation of bbox_<point>.
+
+ As bbox_<point> is a template type used to define the `bbox'
+ virtual type of topo_bbox_<point>, it requires some attention
+ regarding its instantiation.
+
+
+ Metalic's mlc_is_a is used by the static hierarchy mechanism of
+ Static. mlc_is_a performs a static typedef introspection,
+ taking advantage of the SFINAE rule. However, there two
+ phenomena seem to happen here (probably due to the very nature
+ of SFINAE):
+
+ 1. the statement `mlc_is_a(B, A)' requires the knowledge of the
+ entire declaration of the inspected class to answer
+ positively if a `B' actually *is a* `A'. If B is a template
+ class, this implies that B must have been instantiated for
+ mlc_is_a to be able to inspect it;
+
+ 2. mlc_is_a does *not* trigger the instantiation of the
+ inspected type (probably to prevent any error, in accordance
+ to the SFINAE rule).
+
+ When a template type is used to define a virtual type, it
+ *must* have been instantiated, because it might be used during
+ the construction of the base classes of the class it belongs
+ to. That is the case of bbox_<point> here.
+
+ So, how one can trigger such an instantiation? We used to
+ address this problem by using explicit template instantiations
+ placed before the definition of the class holding the template
+ type used a virtual type :
+
+ template class bbox_<point1d>;
+ template class bbox_<point2d>;
+ template class bbox_<point3d>;
+
+ And so on. But this is not good w.r.t. software engineering:
+ one must take care of the correct explicit instantiations at
+ the right place, which is error-prone --and the C++ compiler
+ won't produces easily understandable messages!-- and requires a
+ manual addition for each instantiation of the template type
+ potentially used as a definition of a virtual type.
+
+ A better solution is to force the compiler to instantiate the
+ type at the definition site of the virtual type (here, as for
+ bbox_<point>). Such an instantiation can be triggered by
+ requesting the use of a typedef contained within this type. As
+ many template types define a typedef `self_t' to refer to
+ themselves, we use this typename to both trigger the
+ instantiation of bbox_<point>, and to define
+ `vtypes< topo_bbox_<point> >::bbox_type'. */
+ typedef typename bbox_<point>::self_t bbox_type;
typedef point point_type;
typedef mlc::true_ is_random_accessible_type;
};
@@ -66,7 +118,7 @@
{
typedef topo_bbox_<point> self_t;
typedef topology_entry<self_t> super_t;
- typedef bbox_<point> bbox_t;
+ typedef oln_type_of(self_t, bbox) bbox_t;
public:
Index: oln/core/gen/topo_lbbox.hh
--- oln/core/gen/topo_lbbox.hh (revision 647)
+++ oln/core/gen/topo_lbbox.hh (working copy)
@@ -106,7 +106,7 @@
themselves, we use this typename to both trigger the
instantiation of bbox_<point>, and to define
`vtypes< topo_lbbox_<point> >::bbox_type'. */
- typedef typename bbox_<point>::self_t bbox_type;
+ typedef typename bbox_<point>::self_type bbox_type;
typedef point point_type;
typedef mlc::true_ is_random_accessible_type;
};