
https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Get rid of the explicit instantiations of oln::bbox<>. * oln/core/gen/topo_lbbox.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_lbbox_<point>::bbox_t): Use oln_type_of to define it (more of an aesthetic change than a functional change). * oln/core/1d/bbox1d.hh, oln/core/2d/bbox2d.hh, * oln/core/3d/bbox3d.hh: Remove. * oln/basics1d.hh, oln/basics2d.hh, oln/basics3d.hh, * oln/core/1d/image1d.hh, oln/core/2d/image2d.hh, * oln/core/3d/image3d.hh: Remove their inclusions. basics1d.hh | 1 basics2d.hh | 1 basics3d.hh | 1 core/1d/image1d.hh | 1 core/2d/image2d.hh | 1 core/3d/image3d.hh | 1 core/gen/topo_lbbox.hh | 57 +++++++++++++++++++++++++++++++++++++++++++++++-- 7 files changed, 55 insertions(+), 8 deletions(-) Index: oln/basics1d.hh --- oln/basics1d.hh (revision 640) +++ oln/basics1d.hh (working copy) @@ -39,7 +39,6 @@ # include <oln/core/gen/bbox.hh> # include <oln/core/gen/topo_lbbox.hh> -# include <oln/core/1d/bbox1d.hh> # include <oln/core/gen/fwd_piter_bbox.hh> # include <oln/core/gen/bkd_piter_bbox.hh> Index: oln/core/1d/image1d.hh --- oln/core/1d/image1d.hh (revision 640) +++ oln/core/1d/image1d.hh (working copy) @@ -35,7 +35,6 @@ # include <oln/core/internal/tracked_ptr.hh> # include <oln/core/1d/array1d.hh> # include <oln/core/1d/point1d.hh> -# include <oln/core/1d/bbox1d.hh> // For topo1d. # include <oln/core/1d/aliases.hh> // For fwd_piter and bkd_piter virtual types. Index: oln/core/2d/image2d.hh --- oln/core/2d/image2d.hh (revision 640) +++ oln/core/2d/image2d.hh (working copy) @@ -35,7 +35,6 @@ # include <oln/core/internal/tracked_ptr.hh> # include <oln/core/2d/array2d.hh> # include <oln/core/2d/point2d.hh> -# include <oln/core/2d/bbox2d.hh> // For topo2d. # include <oln/core/2d/aliases.hh> // For fwd_piter and bkd_piter virtual types. Index: oln/core/3d/image3d.hh --- oln/core/3d/image3d.hh (revision 640) +++ oln/core/3d/image3d.hh (working copy) @@ -35,7 +35,6 @@ # include <oln/core/internal/tracked_ptr.hh> # include <oln/core/3d/array3d.hh> # include <oln/core/3d/point3d.hh> -# include <oln/core/3d/bbox3d.hh> // For topo3d. # include <oln/core/3d/aliases.hh> // For fwd_piter and bkd_piter virtual types. Index: oln/core/gen/topo_lbbox.hh --- oln/core/gen/topo_lbbox.hh (revision 640) +++ oln/core/gen/topo_lbbox.hh (working copy) @@ -54,7 +54,59 @@ template <typename point> struct vtypes< topo_lbbox_<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_lbbox_<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_lbbox_<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,8 @@ public topology_entry< topo_lbbox_<point> >, private mlc::assert_< mlc_is_a(point, abstract::point) > { - typedef bbox_<point> bbox_t; + typedef topo_lbbox_<point> self_t; + typedef oln_type_of(self_t, bbox) bbox_t; public: Index: oln/basics2d.hh --- oln/basics2d.hh (revision 640) +++ oln/basics2d.hh (working copy) @@ -39,7 +39,6 @@ # include <oln/core/gen/bbox.hh> # include <oln/core/gen/topo_lbbox.hh> -# include <oln/core/2d/bbox2d.hh> # include <oln/core/gen/fwd_piter_bbox.hh> # include <oln/core/gen/bkd_piter_bbox.hh> Index: oln/basics3d.hh --- oln/basics3d.hh (revision 640) +++ oln/basics3d.hh (working copy) @@ -39,7 +39,6 @@ # include <oln/core/gen/bbox.hh> # include <oln/core/gen/topo_lbbox.hh> -# include <oln/core/3d/bbox3d.hh> # include <oln/core/gen/fwd_piter_bbox.hh> # include <oln/core/gen/bkd_piter_bbox.hh>