
https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Roland Levillain <roland@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; };