https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog from Roland Levillain roland@lrde.epita.fr
Factor the recursive retrieval in internal and external vtypes.
* stc/vtypes.hh (stc::ERROR::FIRST_PARAMETER_OF_rec_get_vtype_SHOULD_BE_A_TAG): New. (tag::method, tag::internal, tag::external): New. (get_vtype): New. (rec_get_vtype): Handle both internal and external vtypes. (rec_ext_vtype): Remove.
vtypes.hh | 162 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 81 insertions(+), 81 deletions(-)
Index: stc/vtypes.hh --- stc/vtypes.hh (revision 489) +++ stc/vtypes.hh (working copy) @@ -40,6 +40,22 @@ # include <mlc/cmp.hh> # include <mlc/if.hh> # include <mlc/is_a.hh> +# include <mlc/assert.hh> + + +/*-----------------. +| Error messages. | +`-----------------*/ + +namespace stc +{ + /// Error messages raised by static assertions. + namespace ERROR + { + struct FIRST_PARAMETER_OF_rec_get_vtype_SHOULD_BE_A_TAG; + } // end of namespace stc::ERROR +} // end of namespace stc +
/*------------. @@ -137,88 +153,66 @@ /* Recursive retrieval of an internal vtype. */ \ /* ------------------------------------------ */ \ \ - /* FIXME: Do a basic scheme of the algorithm in pseudo-code. */ \ + /** Tags for retrieval methods. */ \ + namespace tag \ + { \ \ - /* FIXME: Check for mlc::undefined? */ \ + /** Abstraction for method tags. */ \ + struct method {}; \ \ - /* FIXME: The presence of `vtypes' is the only thing that makes */ \ - /* this code different from the retrieval within an external */ \ - /* vtype. How can we factor this? */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct rec_get_vtype \ - { \ - /** Set of vtypes associated with FROM_TYPE. */ \ - typedef vtypes<category, from_type> types; \ - /** Typedef in the current vtypes (may be mlc::not_found). */ \ - typedef stc_internal_get_typedef(types, typedef_type) type; \ + /** Tag for retrieval within internal vtypes. */ \ + struct internal : public method {}; \ + /** Tag for retrieval within external vtypes. */ \ + struct external : public method {}; \ \ - /** Implicit parent (i.e. super), if any. */ \ - typedef stc_super(from_type) super; \ - /** Pseudosuper class, if any. */ \ - typedef stc_pseudosuper(from_type) pseudosuper; \ + } /** end of stc::internal::tag */ \ \ - typedef typename \ - mlc::if_< \ - mlc::neq_< type, mlc::not_found >, \ - /* then */ \ - /* return it */ \ - /* (the typedef has been found in the vtypes */ \ - /* associated to FROM_TYPE) */ \ - type, \ - /* else */ \ - /* check if the vtype of the `super' of FROM_TYPE */ \ - /* has the typedef */ \ - typename \ - mlc::if_< mlc::neq_< typename rec_get_vtype< category, \ - super, \ - typedef_type >::ret, \ - mlc::not_found >, \ - /* then */ \ - /* return it */ \ - typename rec_get_vtype< category, \ - super, \ - typedef_type >::ret, \ - /* else */ \ - /* check if the FROM_TYPE has a decl_parent */ \ - /* and try to retrieve the typedef from it. */ \ - typename rec_get_vtype< category, \ - pseudosuper, \ - typedef_type >::ret >::ret >::ret \ - ret; \ - }; \ \ - /** Ends of the recursive retrieval (mlc::none is at the end of the */ \ - /** transitive closure of every `super' relation). */ \ - /** { */ \ - /** Case where \a from_type = mlc::none (end of a recursive */ \ - /** retrieval following `super' types). */ \ - template <typename category, typename typedef_type> \ - struct rec_get_vtype<category, mlc::none, typedef_type> \ + /** Try to get \a typedef_type from \a from_type. In case this */ \ + /** typedef is mlc::not_found, don't perform a recursive */ \ + /** retrieval, simply return mlc::not_found. */ \ + template <typename method, typename category, \ + typename from_type, typename typedef_type> \ + struct get_vtype \ { \ - typedef mlc::not_found ret; \ + /* Nothing (no method selected). */ \ }; \ - /** Case where \a from_type = mlc::not_found (end of a recursive */ \ - /** retrieval following `super' types). */ \ - template <typename category, typename typedef_type> \ - struct rec_get_vtype<category, mlc::not_found, typedef_type> \ + \ + /** Specialization of get_vtypes for retrievals within */ \ + /** internal vtypes. */ \ + template <typename category, typename from_type, typename typedef_type> \ + struct get_vtype<tag::internal, category, from_type, typedef_type> \ { \ - typedef mlc::not_found ret; \ + /** Set of vtypes associated with FROM_TYPE. */ \ + typedef vtypes<category, from_type> types; \ + /** Typedef in the current vtypes (may be mlc::not_found). */ \ + typedef stc_internal_get_typedef(types, typedef_type) ret; \ }; \ - /** } */ \ - \ - /* ------------------------------------------ */ \ - /* Recursive retrieval of an external vtype. */ \ - /* ------------------------------------------ */ \ - \ - /* FIXME: Merge this with rec_get_vtype. */ \ \ + /** Specialization of get_vtypes for retrievals within */ \ + /** external vtypes. */ \ template <typename category, typename from_type, typename typedef_type> \ - struct rec_get_ext_vtype \ + struct get_vtype<tag::external, category, from_type, typedef_type> \ { \ /** Set of vtypes associated with FROM_TYPE. */ \ typedef ext_vtype<category, from_type, typedef_type> ext_type; \ /** Typedef in the current vtypes (may be mlc::not_found). */ \ - typedef mlc_ret(ext_type) type; \ + typedef mlc_ret(ext_type) ret; \ + }; \ + \ + \ + /* FIXME: Do a basic scheme of the algorithm in pseudo-code. */ \ + /* FIXME: Check for mlc::undefined? */ \ + \ + /** Recursive retrieval of a virtual type. */ \ + template <typename method, typename category, \ + typename from_type, typename typedef_type> \ + struct rec_get_vtype : \ + private mlc::assert_< mlc_is_a(method, tag::method), \ + stc::ERROR::FIRST_PARAMETER_OF_rec_get_vtype_SHOULD_BE_A_TAG > \ + { \ + typedef typename \ + get_vtype<method, category, from_type, typedef_type>::ret type; \ \ /** Implicit parent (i.e. super), if any. */ \ typedef stc_super(from_type) super; \ @@ -237,19 +231,22 @@ /* check if the vtype of the `super' of FROM_TYPE */ \ /* has the typedef */ \ typename \ - mlc::if_< mlc::neq_< typename rec_get_ext_vtype< category, \ + mlc::if_< mlc::neq_< typename rec_get_vtype< method, \ + category, \ super, \ typedef_type >::ret, \ mlc::not_found >, \ /* then */ \ /* return it */ \ - typename rec_get_ext_vtype< category, \ + typename rec_get_vtype< method, \ + category, \ super, \ typedef_type >::ret, \ /* else */ \ /* check if the FROM_TYPE has a decl_parent */ \ /* and try to retrieve the typedef from it. */ \ - typename rec_get_ext_vtype< category, \ + typename rec_get_vtype< method, \ + category, \ pseudosuper, \ typedef_type >::ret>::ret>::ret \ ret; \ @@ -260,20 +257,21 @@ /** { */ \ /** Case where \a from_type = mlc::none (end of a recursive */ \ /** retrieval following `super' types). */ \ - template <typename category, typename typedef_type> \ - struct rec_get_ext_vtype<category, mlc::none, typedef_type> \ + template <typename method, typename category, typename typedef_type> \ + struct rec_get_vtype<method, category, mlc::none, typedef_type> \ { \ typedef mlc::not_found ret; \ }; \ /** Case where \a from_type = mlc::not_found (end of a recursive */ \ /** retrieval following `super' types). */ \ - template <typename category, typename typedef_type> \ - struct rec_get_ext_vtype<category, mlc::not_found, typedef_type> \ + template <typename method, typename category, typename typedef_type> \ + struct rec_get_vtype<method, category, mlc::not_found, typedef_type> \ { \ typedef mlc::not_found ret; \ }; \ /** } */ \ \ + \ /* ------------------------------------- */ \ /* External/internal typedef selection. */ \ /* ------------------------------------- */ \ @@ -329,20 +327,22 @@ template <typename category, typename from_type, typename typedef_type> \ struct type_of_ \ { \ - /* Look for the typedef as an external type. */ \ - typedef typename \ - internal::rec_get_ext_vtype<category, from_type, typedef_type>::ret \ - external_typedef; \ /* Look for the typedef in internal types. */ \ typedef typename \ - internal::rec_get_vtype<category, from_type, typedef_type>::ret \ + internal::rec_get_vtype<internal::tag::internal, category, \ + from_type, typedef_type>::ret \ internal_typedef; \ + /* Look for the typedef as an external type. */ \ + typedef typename \ + internal::rec_get_vtype<internal::tag::external, category, \ + from_type, typedef_type>::ret \ + external_typedef; \ \ /* Did we found the virtual type? */ \ - static const bool found_external_p = \ - mlc_bool(mlc::is_found_<external_typedef>); \ static const bool found_internal_p = \ mlc_bool(mlc::is_found_<internal_typedef>); \ + static const bool found_external_p = \ + mlc_bool(mlc::is_found_<external_typedef>); \ \ typedef typename \ internal::select_typedef<found_external_p, found_internal_p, \