
2006-11-14 Thierry GERAUD <theo@tegucigalpa.lrde.epita.fr> Simplify scoop facilities. * stc/scoop.hh: Rename as... * stc/was.scoop.hh: ...this new file. * stc/scoop.hh: New version. Index: stc/scoop.hh =================================================================== --- stc/scoop.hh (revision 705) +++ stc/scoop.hh (working copy) @@ -43,51 +43,19 @@ # include <mlc/abort.hh> # include <mlc/bool.hh> -# include <mlc/int.hh> # include <mlc/cmp.hh> # include <mlc/if.hh> # include <mlc/is_a.hh> -# include <mlc/comma.hh> -# include <mlc/valist.hh> -# include <stc/valist_aggregator.hh> -# include <stc/exact.hh> -# include <stc/internal/extract_vtype_from_list.hh> - - -/*-----------------. -| Error messages. | -`-----------------*/ - namespace stc { + /// Error messages raised by static assertions/abortions. namespace ERROR { - /// Errors from internal::get_super_types_helper. - /// \{ - struct PARAMETER_OF_get_super_types_helper_IS_NOT_A_VALID_VALIST; - /// \} - - /// Errors from internal rec_get_vtype. - /// \{ - struct FIRST_PARAMETER_OF_rec_get_vtype_IS_NOT_A_TAG; - - struct FIRST_PARAMETER_OF_rec_get_vtype_from_list_IS_NOT_A_TAG; - struct THIRD_PARAMETER_OF_rec_get_vtype_from_list_IS_NOT_A_LIST; - /// \} - - /// Errors from internal::select_typedef. - /// \{ - struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_SINGLE; - struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_EXTERNAL; - struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_SINGLE_AND_EXTERNAL; - struct VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_SINGLE_AND_EXTERNAL; - /// \} - /// Errors from check_type_of_ and check_exact_type_of_. /// \{ struct VIRTUAL_TYPE_NOT_FOUND; @@ -99,933 +67,259 @@ -/*------------. -| Equipment. | -`------------*/ - -/// Internal macros, not to be used by the client. -/// \{ - -// Note: TypedefName *must* be of the form `typedef_::foo'. # define stc_internal_get_typedef(Type, TypedefName) \ typename TypedefName::template from_< Type >::ret -# define stc_internal_maybe_get_nth_super_type(Type, Nth) \ - typename internal::maybe_get_super_type< Type, Nth >::ret -# define stc_internal_rec_get_vtype(Type) \ - typename rec_get_vtype< method, category, Type, typedef_type >::ret +# define stc_internal_get_super(Type) \ + typename typedef_::super_type::template from_< Type >::ret -/// \} -// FIXME: Complete support for hierarchies with several super classes. -// FIXME: Could we extract some classes from this gigantic macro? -# define stc_scoop_equipment_for_namespace(SCOOPED_NAMESPACE) \ - \ -namespace SCOOPED_NAMESPACE \ -{ \ - \ - /* ----------------------- */ \ - /* Typedefs declarations. */ \ - /* ----------------------- */ \ - \ - /* Declare the ``uplink'' typedef (access to a pseudosuper class). */ \ - mlc_decl_typedef(pseudosuper_type); \ - \ - \ - /* ------------- */ \ - /* Inheritance. */ \ - /* ------------- */ \ - \ - /* Set super classes. */ \ - \ - template<typename type, unsigned N = 1> \ - struct set_super_type : public mlc::undefined \ - { \ - typedef mlc::none ret; \ - }; \ - \ - \ - /* Get supers list. */ \ - \ - namespace internal \ - { \ - template <typename type, unsigned N> \ - struct maybe_get_super_type \ - { \ - typedef typename \ - mlc::if_< mlc_is_a( mlc_comma_1( set_super_type<type, N> ), \ - mlc::undefined ), \ - mlc::internal::valist_none, \ - mlc_ret(mlc_comma_1(set_super_type< type, N >)) >::ret \ - ret; \ - }; \ - } /* end of namespace SCOOPED_NAMESPACE ::internal */ \ - \ - template <typename type> \ - struct get_supers_list \ - { \ - /* FIXME: Factor with a loop macro? */ \ - typedef stc_internal_maybe_get_nth_super_type(type, 1) s1; \ - typedef stc_internal_maybe_get_nth_super_type(type, 2) s2; \ - typedef stc_internal_maybe_get_nth_super_type(type, 3) s3; \ - typedef stc_internal_maybe_get_nth_super_type(type, 4) s4; \ - typedef stc_internal_maybe_get_nth_super_type(type, 5) s5; \ - typedef stc_internal_maybe_get_nth_super_type(type, 6) s6; \ - typedef stc_internal_maybe_get_nth_super_type(type, 7) s7; \ - typedef stc_internal_maybe_get_nth_super_type(type, 8) s8; \ - typedef stc_internal_maybe_get_nth_super_type(type, 9) s9; \ - \ - typedef mlc::valist_<s1, s2, s3, s4, s5, s6, s7, s8, s9> ret; \ - }; \ - \ - \ - /* Get super classes. */ \ - \ - namespace internal \ - { \ - \ - /** Accessor helper. */ \ - template<typename type> \ - struct get_super_types_helper; \ - \ - /** Accessor helper: specialization for the case of a single */ \ - /** super class. */ \ - template<typename super> \ - struct get_super_types_helper< mlc::valist_ <super> > \ - { \ - /** Return the super class directly. */ \ - typedef super ret; \ - }; \ - \ - /** Accessor helper: specializations for the case of two super */ \ - /** classes or more. */ \ - /* FIXME: Currently works only for 2 and 3 super types. */ \ - template <typename super1, typename super2, typename super3> \ - struct get_super_types_helper< mlc::valist_ <super1, super2, super3> > \ - { \ - /** Return an aggregate of the super classes. */ \ - typedef stc::valist_aggregator< mlc::valist_ <super1, super2, super3> > \ - ret; \ - }; \ - \ - /** Accessor helper: default case (abort). */ \ - template<typename type> \ - struct get_super_types_helper : \ - public mlc::abort_< \ - type, \ - stc::ERROR::PARAMETER_OF_get_super_types_helper_IS_NOT_A_VALID_VALIST \ - > \ - { \ - }; \ - \ - } /* end of namespace SCOOPED_NAMESPACE ::internal */ \ - \ - \ - template<typename type> \ - struct get_super_types \ - { \ - typedef typename get_supers_list<type>::ret supers_list; \ - typedef typename internal::get_super_types_helper<supers_list>::ret ret; \ - }; \ - \ - \ - /* ------------------------ */ \ - /* ``Pseudo'' inheritance. */ \ - /* ------------------------ */ \ - \ - template <typename type> \ - struct set_pseudosuper_type \ - { \ - typedef mlc::none ret; \ - }; \ - \ - \ - /* --------------- */ \ - /* Virtual types. */ \ - /* --------------- */ \ - \ - /** \brief Definition of virtual types. */ \ - /** */ \ - /** There a three kinds of structures for virtual types: */ \ - /** - internal vtypes (\a vtypes); */ \ - /** - single vtypes (\a single_vtype); */ \ - /** - extended vtypes (\a ext_vtype); */ \ - /** */ \ - /** A \a vtype structure can store one or several internal vtypes, */ \ - /** whereas a \a single_vtype or an \a ext_vtype structure can hold */ \ - /** one and only one vtype. */ \ - /** */ \ - /** See tests/tour.cc and tests/vtypes.cc for examples of use. */ \ - /** */ \ - /** A virtual type definition within a \a vtype structure cannot use */ \ - /** the form `stc_type_of(Exact, ...)', which would cause endless */ \ - /** recursions in the class hierarchy. Instead, such definitions */ \ - /** should be placed in \a single_vtype or \a ext_vtype structure. */ \ - /** */ \ - /** Definitions of single vtypes can be ``announced'' in the */ \ - /** corresponding internal vtypes structure, using the \a */ \ - /** mlc::undefined tag (i.e., a vtype defined as \a mlc::undefined in */ \ - /** \a vtypes can be re-defined in a \a single_vtype). */ \ - /** */ \ - /** Apart from this exception, a vtype shall be defined at most by */ \ - /** one of the three structures explained above. */ \ - /** */ \ - /** To put in a nushell, internal vtypes are the default way to define */ \ - /** the vtypes of a class (except those of the form */ \ - /** `stc_type_of(Exact, ...)'); single vtypes are used to transcend */ \ - /** this limitation; and extended vtypes are used to add new vtypes to */ \ - /** a class besides its initial vtypes. */ \ - \ - \ - /* Internal vtypes. */ \ - /* \{ */ \ - \ - /** \brief Internal virtual types associated to \a from_type. */ \ - /** */ \ - /** Specialize this class for the desired \a from_type. */ \ - template <typename category, typename from_type> \ - struct vtypes_in_category \ - { \ - }; \ - \ - /** \brief Internal virtual types associated to \a from_type */ \ - /** having no category. */ \ - /** */ \ - /** Specialize this class for the desired \a from_type. */ \ - template <typename from_type> \ - struct vtypes \ - { \ - }; \ - \ - /** Specialization of vtypes for types without category. */ \ - template <typename from_type> \ - struct vtypes_in_category<void, from_type> : public vtypes<from_type> \ - { \ - }; \ - \ - /** End of the recursive construction of any vtypes hierarchy. */ \ - template <typename category> \ - struct vtypes_in_category<category, mlc::none> \ - { \ - }; \ - \ - /* \} */ \ - \ - \ - /* Single vtype. */ \ - /* \{ */ \ - \ - /** \brief A single virtual type associated to \a from_type. */ \ - /** */ \ - /** Specialize this class for the desired \a from_type. */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct single_vtype_in_category \ - { \ - }; \ - \ - /** \brief A single virtual type associated to \a from_type. */ \ - /** Version for types without category. */ \ - /** */ \ - /** Specialize this class for the desired \a from_type. */ \ - template <typename from_type, typename typedef_type> \ - struct single_vtype \ - { \ - }; \ - \ - /** Specialization of single_vtype for types without category. */ \ - template <typename from_type, typename typedef_type> \ - struct single_vtype_in_category<void, from_type, typedef_type> \ - : public single_vtype<from_type, typedef_type> \ - { \ - }; \ - \ - /** End of the recursive construction of any single_vtype<> */ \ - /** hierarchy. */ \ - template <typename category, typename typedef_type> \ - struct single_vtype_in_category<category, mlc::none, typedef_type> \ - { \ - }; \ - \ - /* \} */ \ - \ - \ - /* Extended vtype. */ \ - /* \{ */ \ - \ - /** \brief An extended virtual type associated to \a from_type. */ \ - /** */ \ - /** Specialize this class for the desired \a from_type. */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct ext_vtype_in_category \ - { \ - }; \ - \ - /** \brief An extended virtual type associated to \a from_type. */ \ - /** Version for types without category. */ \ - /** */ \ - /** Specialize this class for the desired \a from_type. */ \ - template <typename from_type, typename typedef_type> \ - struct ext_vtype \ - { \ - }; \ - \ - /** Specialization of ext_vtype for types without category. */ \ - template <typename from_type, typename typedef_type> \ - struct ext_vtype_in_category<void, from_type, typedef_type> \ - : public ext_vtype<from_type, typedef_type> \ - { \ - }; \ - \ - /** End of the recursive construction of any ext_vtype<> */ \ - /** hierarchy. */ \ - template <typename category, typename typedef_type> \ - struct ext_vtype_in_category<category, mlc::none, typedef_type> \ - { \ - }; \ - \ - /* \} */ \ - \ - \ - /* -------------------- */ \ - /* Internal machinery. */ \ - /* -------------------- */ \ - \ - /** The classes enclosed in this namespace must not be specialized */ \ - /** by the user (they are part of the automatic associated types */ \ - /** retrieval mechanism). */ \ - namespace internal \ - { \ - /* ------------------------------------------ */ \ - /* Recursive retrieval of an internal vtype. */ \ - /* ------------------------------------------ */ \ - \ - /** Tags for retrieval methods. */ \ - namespace tag \ - { \ - \ - /** Abstraction for method tags. */ \ - struct method {}; \ - \ - /** Tag for retrieval within internal vtypes. */ \ - struct internal : public method {}; \ - /** Tag for retrieval within single vtypes. */ \ - struct single : public method {}; \ - /** Tag for retrieval within extended vtypes. */ \ - struct extended : public method {}; \ - \ - } /* end of namespace SCOOPED_NAMESPACE ::internal::tag */ \ - \ - /** 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_helper \ - { \ - /* Nothing (no method selected). */ \ - }; \ - \ - /** Specialization of get_vtypes for retrievals within */ \ - /** internal vtypes. */ \ - template <typename category, \ - typename from_type, typename typedef_type> \ - struct get_vtype_helper<tag::internal, category, \ - from_type, typedef_type> \ - { \ - /** Set of vtypes associated with FROM_TYPE. */ \ - typedef vtypes_in_category<category, from_type> types; \ - /** Typedef in the current vtypes (may be mlc::not_found). */ \ - typedef stc_internal_get_typedef(types, typedef_type) ret; \ - }; \ - \ - /** Specialization of get_vtypes for retrievals within */ \ - /** single vtypes. */ \ - template <typename category, \ - typename from_type, typename typedef_type> \ - struct get_vtype_helper<tag::single, category, \ - from_type, typedef_type> \ - { \ - /** Set of vtypes associated with FROM_TYPE. */ \ - typedef single_vtype_in_category<category, from_type, typedef_type> \ - single_type; \ - /** Typedef in the current single_vtype (may be mlc::not_found). */ \ - typedef mlc_ret(single_type) ret; \ - }; \ - \ - /** Specialization of get_vtypes for retrievals within */ \ - /** extended vtypes. */ \ - template <typename category, \ - typename from_type, typename typedef_type> \ - struct get_vtype_helper<tag::extended, category, \ - from_type, typedef_type> \ - { \ - /** Set of vtypes associated with FROM_TYPE. */ \ - typedef ext_vtype_in_category<category, from_type, typedef_type> \ - ext_type; \ - /** Typedef in the current ext_vtype (may be mlc::not_found). */ \ - typedef mlc_ret(ext_type) ret; \ - }; \ - \ - \ - /* FIXME: Do a basic scheme of the algorithm in pseudo-code. */ \ - \ - /* Forward declaration. */ \ - template <typename method, typename category, \ - typename from_list, typename typedef_type> \ - struct rec_get_vtype_from_list; \ - \ - /** Recursive retrieval of the virtual type \a typedef_type inside */ \ - /** the class \a from_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_IS_NOT_A_TAG > \ - { \ - /** Get potential vtype \a typedef_type from the current class */ \ - /** (\a from_type). */ \ - typedef typename \ - get_vtype_helper< method, category, from_type, typedef_type>::ret \ - type; \ - \ - /** Implicit parents (i.e. supers), if any. */ \ - typedef typename get_supers_list<from_type>::ret supers_list; \ - /** Vtype deduced from the vtypes of the base class(es) of */ \ - /** \a from_type, if any. */ \ - typedef typename \ - rec_get_vtype_from_list< method, category, \ - supers_list, typedef_type >::ret \ - vtype_from_supers; \ - \ - /** Pseudosuper class, if any. */ \ - typedef stc_get_pseudosuper(from_type) pseudosuper; \ - /** Vtype deduced from the vtype of the pseudo super class of */ \ - /** \a from_type, if any. */ \ - typedef typename \ - rec_get_vtype< method, category, pseudosuper, typedef_type >::ret \ - vtype_from_pseudo_super; \ - \ - /* Core of the search algorithm. */ \ - 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 vtypes of the `supers' of FROM_TYPE */ \ - /* has the typedef */ \ - typename \ - mlc::if_< mlc::neq_< vtype_from_supers, mlc::not_found >, \ - /* then */ \ - /* return it */ \ - vtype_from_supers, \ - /* else */ \ - /* check if the FROM_TYPE has a pseudo super */ \ - /* and try to retrieve the typedef from it. */ \ - vtype_from_pseudo_super >::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 method, typename category, typename typedef_type> \ - struct rec_get_vtype<method, category, mlc::none, typedef_type> : \ - private mlc::assert_< mlc_is_a(method, tag::method), \ - stc::ERROR::FIRST_PARAMETER_OF_rec_get_vtype_IS_NOT_A_TAG > \ - { \ - typedef mlc::not_found ret; \ - }; \ - /** Case where \a from_type = mlc::not_found (end of a recursive */ \ - /** retrieval following `super' types). */ \ - template <typename method, typename category, typename typedef_type> \ - struct rec_get_vtype<method, category, mlc::not_found, typedef_type> : \ - private mlc::assert_< mlc_is_a(method, tag::method), \ - stc::ERROR::FIRST_PARAMETER_OF_rec_get_vtype_IS_NOT_A_TAG > \ - { \ - typedef mlc::not_found ret; \ - }; \ - /** \} */ \ - \ - \ - /** Recursive retrieval of vtype \a typedef_type inside */ \ - /** \a from_list. */ \ - /** \{ */ \ - \ - /* Default case: \a from_type is not a mlc::valist_, abort. */ \ - template <typename method, typename category, \ - typename from_list, typename typedef_type> \ - struct rec_get_vtype_from_list : \ - private mlc::abort_< from_list, \ - stc::ERROR::THIRD_PARAMETER_OF_rec_get_vtype_from_list_IS_NOT_A_LIST > \ - { \ - }; \ - \ - /** Case where the list is empty. Suprisingly, the general */ \ - /** specialization for mlc::valist<e1, ..., e9> is not enough: */ \ - /** this specialization is needed too. */ \ - template <typename method, typename category, typename typedef_type> \ - struct rec_get_vtype_from_list< \ - method, category, mlc::valist_<>, typedef_type> \ - { \ - typedef mlc::not_found ret; \ - }; \ - \ - /* Case where \a from_list is a genuine list. */ \ - template <typename method, typename category, \ - typename e1, typename e2, typename e3, \ - typename e4, typename e5, typename e6, \ - typename e7, typename e8, typename e9, \ - typename typedef_type> \ - struct rec_get_vtype_from_list< \ - method, category, \ - mlc::valist_<e1, e2, e3, e4, e5, e6, e7, e8, e9>, typedef_type \ - > : \ - private mlc::assert_< mlc_is_a(method, tag::method), \ - stc::ERROR::FIRST_PARAMETER_OF_rec_get_vtype_from_list_IS_NOT_A_TAG > \ - { \ - /* For each item of the list \a from_list, perform a */ \ - /* rec_get_vtype search. */ \ - /* FIXME: Factor with a loop macro? */ \ - typedef stc_internal_rec_get_vtype(e1) res1; \ - typedef stc_internal_rec_get_vtype(e2) res2; \ - typedef stc_internal_rec_get_vtype(e3) res3; \ - typedef stc_internal_rec_get_vtype(e4) res4; \ - typedef stc_internal_rec_get_vtype(e5) res5; \ - typedef stc_internal_rec_get_vtype(e6) res6; \ - typedef stc_internal_rec_get_vtype(e7) res7; \ - typedef stc_internal_rec_get_vtype(e8) res8; \ - typedef stc_internal_rec_get_vtype(e9) res9; \ - \ - /* Then, create a list from the results. */ \ - typedef \ - mlc::valist_<res1, res2, res3, res4, res5, res6, res7, res8, res9> \ - res_list; \ - \ - /* Finally, match this list against a set of valid patterns. */ \ - /* If the match fails, return mlc::not_found. */ \ - typedef typename \ - stc::internal::extract_vtype_from_list<res_list>::ret ret; \ - }; \ - \ - \ - /* -------------------------------------------- */ \ - /* Internal/single/extended typedef selection. */ \ - /* -------------------------------------------- */ \ - \ - /** \brief Typedef selector. */ \ - /** */ \ - /** A virtual type is considered valid if and only if it has been */ \ - /** found as an internal vtype or (exclusive) as an extended vtype. */ \ - /** Other cases (no definition or a double definition) are invalid. */ \ - /** */ \ - /** \{ */ \ - /** Fwd decl. */ \ - template \ - < typename internal_vtype_candidate, bool found_as_internal_vtype, \ - typename single_vtype_candidate, bool found_as_single_vtype, \ - typename extended_vtype_candidate, bool found_as_extended_vtype > \ - struct select_typedef; \ - \ - /** The typedef is defined as an internal vtype only: good. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, true, \ - single_vtype_candidate, false, \ - extended_vtype_candidate, false> \ - { \ - typedef internal_vtype_candidate ret; \ - }; \ - \ - /** The typedef is defined as a single vtype only: good. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, false, \ - single_vtype_candidate, true, \ - extended_vtype_candidate, false> \ - { \ - typedef single_vtype_candidate ret; \ - }; \ - \ - /** The typedef is defined as an extended vtype only: good. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, false, \ - single_vtype_candidate, false, \ - extended_vtype_candidate, true> \ - { \ - typedef extended_vtype_candidate ret; \ - }; \ - \ - /** Special case: The typedef is <b>declared</b> as mlc::undefined */ \ - /** in internal vtypes, and <b>defined</b> as a single vtype: good. */ \ - template <typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<mlc::undefined, true, \ - single_vtype_candidate, true, \ - extended_vtype_candidate, false> \ - { \ - typedef single_vtype_candidate ret; \ - }; \ - \ - \ - /* Erroneous cases. */ \ - /* ---------------- */ \ - \ - /* In the following cases, mlc::abort_ ``statements'' take a dummy */ \ - /* typedef as first parameter, to prevent an immediate evaluation. */ \ - /* of mlc_abort_<>. */ \ - /* The choice was made to choose the first unbound parameter, but it */ \ - /* <i>it has no meaning in itself!</i>. This is just a part of the */ \ - /* static abortion mechanism. */ \ - \ - /** The typedef is <b>defined</b> both as internal and single (and */ \ - /** the internal flavour is <b>not</b> mlc::undefined): bad. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, true, \ - single_vtype_candidate, true, \ - extended_vtype_candidate, false> : \ - mlc::abort_ < \ - internal_vtype_candidate /* dummy */ , \ - stc::ERROR::VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_SINGLE \ - > \ - { \ - /* Error, no valid typedef found. */ \ - typedef mlc::not_found ret; \ - }; \ - \ - /** The typedef is <b>defined</b> both as internal and external: bad. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, true, \ - single_vtype_candidate, false, \ - extended_vtype_candidate, true> : \ - mlc::abort_ < \ - internal_vtype_candidate /* dummy */ , \ - stc::ERROR::VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_EXTERNAL \ - > \ - { \ - /* Error, no valid typedef found. */ \ - typedef mlc::not_found ret; \ - }; \ - \ - /** The typedef is <b>defined</b> both as single and external: bad. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, false, \ - single_vtype_candidate, true, \ - extended_vtype_candidate, true> : \ - mlc::abort_ < \ - internal_vtype_candidate /* dummy */ , \ - stc::ERROR::VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_SINGLE_AND_EXTERNAL \ - > \ - { \ - /* Error, no valid typedef found. */ \ - typedef mlc::not_found ret; \ - }; \ - \ - /** The typedef is <b>defined</b> as internal, single, and */ \ - /** external: bad. */ \ - template <typename internal_vtype_candidate, \ - typename single_vtype_candidate, \ - typename extended_vtype_candidate> \ - struct select_typedef<internal_vtype_candidate, true, \ - single_vtype_candidate, true, \ - extended_vtype_candidate, true> : \ - mlc::abort_ < \ - internal_vtype_candidate /* dummy */ , \ - stc::ERROR:: \ - VIRTUAL_TYPE_MULTIPLY_DEFINED_AS_INTERNAL_AND_SINGLE_AND_EXTERNAL \ - > \ - { \ - /* Error, no valid typedef found. */ \ - typedef mlc::not_found ret; \ - }; \ - \ - /** All other cases: \a mlc::not_found is returned, but no static. */ \ - /** error is raised. */ \ - template \ - < typename internal_vtype_candidate, bool found_as_internal_vtype, \ - typename single_vtype_candidate, bool found_as_single_vtype, \ - typename extended_vtype_candidate, bool found_as_extended_vtype > \ - struct select_typedef \ - { \ - typedef mlc::not_found ret; \ - }; \ - /** \} */ \ - \ - } /* End of namespace SCOOPED_NAMESPACE ::internal */ \ - \ - \ - /* Entry points. */ \ - /* ------------- */ \ - \ - /** Entry point of the vtype retrieval algorithm. */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct direct_type_of_ \ - { \ - /* Look for the typedef in internal vtypes. */ \ - typedef typename \ - internal::rec_get_vtype<internal::tag::internal, category, \ - from_type, typedef_type>::ret \ - internal_vtype_candidate; \ - /* Look for the typedef as a single vtype definition. */ \ - typedef typename \ - internal::rec_get_vtype<internal::tag::single, category, \ - from_type, typedef_type>::ret \ - single_vtype_candidate; \ - /* Look for the typedef as an extended vtype. */ \ - typedef typename \ - internal::rec_get_vtype<internal::tag::extended, category, \ - from_type, typedef_type>::ret \ - extended_vtype_candidate; \ - \ - /* Did we found the virtual type in any of the vtypes structures? */ \ - static const bool found_as_internal_vtype = \ - mlc_bool(mlc::is_found_<internal_vtype_candidate>); \ - static const bool found_as_single_vtype = \ - mlc_bool(mlc::is_found_<single_vtype_candidate>); \ - static const bool found_as_extended_vtype = \ - mlc_bool(mlc::is_found_<extended_vtype_candidate>); \ - \ - /* Find an eligible typedef. */ \ - typedef typename \ - internal::select_typedef< \ - internal_vtype_candidate, found_as_internal_vtype, \ - single_vtype_candidate, found_as_single_vtype, \ - extended_vtype_candidate, found_as_extended_vtype \ - >::ret ret; \ - }; \ - \ - /** Entry point of the vtype retrieval algorithm (working on the */ \ - /** exact version of \a from_type). */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct type_of_ \ - { \ - /* Get the exact type of \a from_type. */ \ - typedef stc_to_exact(from_type) from_exact_type; \ - /* ``Run'' type_of_. */ \ - typedef typename \ - direct_type_of_<category, from_exact_type, typedef_type>::ret ret; \ - }; \ - \ - \ - /** Like direct_type_of_, but ensure that the result is different */ \ - /** from mlc::not_found. */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct check_direct_type_of_ \ - { \ - /* Candidate type. */ \ - typedef typename \ - direct_type_of_<category, from_type, typedef_type>::ret candidate; \ - /* Check that CANDIDATE is found. */ \ - typedef typename \ - mlc::assert_and_return_< \ - mlc_neq(candidate, mlc::not_found), \ - candidate, \ - stc::ERROR::VIRTUAL_TYPE_NOT_FOUND \ - >::ret ret; \ - }; \ - \ - /** Like type_of_, but ensure that the result is different from */ \ - /** mlc::not_found. */ \ - template <typename category, typename from_type, typename typedef_type> \ - struct check_type_of_ \ - { \ - /* Candidate type. */ \ - typedef typename \ - type_of_<category, from_type, typedef_type>::ret candidate; \ - /* Check that CANDIDATE is found. */ \ - typedef typename \ - mlc::assert_and_return_< \ - mlc_neq(candidate, mlc::not_found), \ - candidate, \ - stc::ERROR::VIRTUAL_TYPE_NOT_FOUND \ - >::ret ret; \ - }; \ - \ -} /* end of namespace SCOOPED_NAMESPACE */ \ - \ + +# define stc_scoop_equipment_for_namespace(SCOOPED_NAMESPACE) \ + \ +namespace SCOOPED_NAMESPACE \ +{ \ + \ + template <typename from_type> \ + struct set_super_type \ + { \ + typedef mlc::none ret; \ + }; \ + \ + template <typename type> \ + struct set_pseudosuper_type \ + { \ + typedef mlc::not_found ret; \ + }; \ + \ + template <typename from_type> \ + struct vtypes \ + { \ + }; \ + \ + template <typename from_type, typename type> \ + struct single_vtype \ + { \ + typedef mlc::not_found ret; \ + }; \ + \ + \ + namespace internal \ + { \ + \ + /* retrieve_from_single_vtype */ \ + \ + template <typename from_type, typename type> \ + struct retrieve_from_single_vtype; \ + \ + template <typename res, typename super, typename type> \ + struct helper_retrieve_from_single_vtype \ + { \ + typedef res ret; \ + }; \ + \ + template <typename super, typename type> \ + struct helper_retrieve_from_single_vtype < mlc::not_found, super, type > \ + { \ + typedef typename retrieve_from_single_vtype<super, type>::ret ret; \ + }; \ + \ + template <typename type> \ + struct helper_retrieve_from_single_vtype < mlc::not_found, mlc::none, type > \ + { \ + typedef mlc::not_found ret; \ + }; \ + \ + template <typename type> \ + struct helper_retrieve_from_single_vtype < mlc::not_found, mlc::not_found, type > \ + { \ + }; \ + \ + template <typename from_type, typename type> \ + struct retrieve_from_single_vtype \ + { \ + typedef SCOOPED_NAMESPACE::single_vtype<from_type, type> decl; \ + typedef typename decl::ret res; \ + typedef typename set_super_type<from_type>::ret super; \ + typedef typename helper_retrieve_from_single_vtype< res, super, type >::ret ret; \ + }; \ + \ + /* vtypes */ \ + \ + template <typename from_type, typename type> \ + struct retrieve_from_vtypes; \ + \ + template <typename res, typename super, typename type> \ + struct helper_retrieve_from_vtypes \ + { \ + typedef res ret; \ + }; \ + \ + template <typename super, typename type> \ + struct helper_retrieve_from_vtypes < mlc::not_found, super, type > \ + { \ + typedef typename retrieve_from_vtypes<super, type>::ret ret; \ + }; \ + \ + template <typename type> \ + struct helper_retrieve_from_vtypes < mlc::not_found, mlc::none, type > \ + { \ + typedef mlc::not_found ret; \ + }; \ + \ + template <typename type> \ + struct helper_retrieve_from_vtypes < mlc::not_found, mlc::not_found, type > \ + { \ + }; \ + \ + template <typename from_type, typename type> \ + struct retrieve_from_vtypes \ + { \ + typedef SCOOPED_NAMESPACE::vtypes<from_type> decl; \ + typedef stc_internal_get_typedef(decl, type) res; \ + typedef typename set_super_type<from_type>::ret super; \ + typedef typename helper_retrieve_from_vtypes< res, super, type >::ret ret; \ + }; \ + \ + /* pseudo super */ \ + \ + template <typename from_type> \ + struct retrieve_pseudosuper; \ + \ + template <typename res, typename super> \ + struct helper_retrieve_pseudosuper \ + { \ + typedef res ret; \ + }; \ + \ + template <typename super> \ + struct helper_retrieve_pseudosuper < mlc::not_found, super > \ + { \ + typedef typename retrieve_pseudosuper<super>::ret ret; \ + }; \ + \ + template <> \ + struct helper_retrieve_pseudosuper < mlc::not_found, mlc::none > \ + { \ + typedef mlc::not_found ret; \ + }; \ + \ + template <> \ + struct helper_retrieve_pseudosuper < mlc::not_found, mlc::not_found > \ + { \ + }; \ + \ + template <typename from_type> \ + struct retrieve_pseudosuper \ + { \ + typedef typename set_pseudosuper_type<from_type>::ret res; \ + typedef typename set_super_type<from_type>::ret super; \ + typedef typename helper_retrieve_pseudosuper< res, super >::ret ret; \ + }; \ + \ + /* scoop_vtype_of */ \ + \ + template <typename from_type, typename type> \ + struct step_from_vtypes; /* fwd decl of main entry */ \ + \ + /* step 3 <=> delegation */ \ + \ + template <typename from_type, typename type> \ + struct helper_step_from_delegation \ + { \ + /* REC */ \ + typedef typename step_from_vtypes<from_type, type>::ret ret; \ + }; \ + \ + template <typename type> \ + struct helper_step_from_delegation < mlc::not_found, type > \ + { \ + typedef mlc::not_found ret; \ + }; \ + \ + template <typename from_type, typename type> \ + struct step_from_delegation /* step 3 entry */ \ + { \ + typedef typename retrieve_pseudosuper<from_type>::ret pseudo_type; \ + typedef typename helper_step_from_delegation<pseudo_type, type>::ret ret; \ + }; \ + \ + /* step 2 <=> single_vtype */ \ + \ + template <typename res, typename from_type, typename type> \ + struct helper_step_from_single_vtype \ + { \ + typedef res ret; /* found! */ \ + }; \ + \ + template <typename from_type, typename type> \ + struct helper_step_from_single_vtype <mlc::not_found, /* => step 3 */ \ + from_type, type> \ + { \ + typedef typename step_from_delegation<from_type, type>::ret ret; \ + }; \ + \ + template <typename from_type, typename type> \ + struct helper_step_from_single_vtype <mlc::undefined, /* => step 3 */ \ + from_type, type> \ + { \ + typedef typename step_from_delegation<from_type, type>::ret ret; \ + }; \ + \ + template <typename from_type, typename type> \ + struct step_from_single_vtype /* step 2 entry */ \ + { \ + typedef typename retrieve_from_single_vtype<from_type, type>::ret res; \ + typedef typename helper_step_from_single_vtype< res, from_type, type>::ret ret; \ + }; \ + \ + /* step 1 <=> vtypes */ \ + \ + template <typename res, typename from_type, typename type> \ + struct helper_step_from_vtypes \ + { \ + typedef res ret; /* found! */ \ + }; \ + \ + template <typename from_type, typename type> \ + struct helper_step_from_vtypes <mlc::not_found, /* => step 2 */ \ + from_type, type> \ + { \ + typedef typename step_from_single_vtype<from_type, type>::ret ret; \ + }; \ + \ + template <typename from_type, typename type> \ + struct helper_step_from_vtypes <mlc::undefined, /* => step 2 */ \ + from_type, type> \ + { \ + typedef typename step_from_single_vtype<from_type, type>::ret ret; \ + }; \ + \ + template <typename from_type, typename type> \ + struct step_from_vtypes /* main entry (so step 1 entry) */ \ + { \ + typedef typename retrieve_from_vtypes<from_type, type>::ret res; \ + typedef typename helper_step_from_vtypes< res, from_type, type>::ret ret; \ + }; \ + \ + } /* end of namespace SCOOPED_NAMESPACE ::internal */ \ + \ + \ + template <typename from_type, typename type> \ + struct direct_type_of_ \ + { \ + typedef typename internal::step_from_vtypes<from_type, type>::ret ret; \ + }; \ + \ + \ +} /* end of namespace SCOOPED_NAMESPACE */ \ + \ struct e_n_d__w_i_t_h___s_e_m_i_c_o_l_o_n -/*---------. -| Macros. | -`---------*/ - -// ------------- // -// Inheritance. // -// ------------- // - -// Set. - -/* FIXME: I don't know whether these macros will be really usable; what - if Type is a template class? We would have to provide additional - versions of these macros, with support for one parameter, two - parameters, etc. */ -/// \def Declare the immediate base class \a Super of \a Type. -#define stc_set_nth_super(Type, N, Super) \ - template<> \ - struct set_super_type< Type, N > \ - { \ - typedef Super ret; \ - }; \ - \ - struct e_n_d__w_i_t_h___s_e_m_i_c_o_l_o_n - -// Shortcut. -#define stc_set_super(Type, Super) \ - stc_set_nth_super(Type, 1, Super) - - -// Get. - -// FIXME: The error message given by the compiler is not explicit -// when trying to use stc_get_supers on a class which has no -// (declared) super class. Improve this. - -/** \a stc_get_supers(Type) returns a class which inerits from all the - classes declared as super types of \a Type. - - However, there is an exception when Type as single super: - stc_get_supers returns this super class directly, not a class - ineriting from it, to avoid a useless indirection. */ -#define stc_get_supers(Type) \ - get_super_types< Type >::ret - -/// \def Get the Nth immediate base class(es) of Type (version to be -/// used inside a template). -# define stc_get_nth_super(Type, Nth) \ - typename stc_get_nth_super_(Type, Nth) - -/// \def Get the Nth immediate base class(es) of Type (version to be -/// used outside a template). -# define stc_get_nth_super_(Type, Nth) \ - set_super_type< Type, Nth >::ret - -/// \def Get the fisrt immediate base class of Type (version to be -/// used inside a template). -# define stc_get_super(Type) \ - typename stc_get_super_(Type) - -/// \def Get the first immediate base class of Type (version to be -/// used outside a template). -# define stc_get_super_(Type) \ - stc_get_nth_super_(Type, 1) - - -// -------------------- // -// Pseudo inheritance. // -// -------------------- // - -/* FIXME: I don't know whether this macro will be really usable; what - if Type is a template class? We would have to provide additional - versions of this macro, with support for one parameter, two - parameters, etc. */ -/// \def Declare the pseudosuper class \a PseudoSuper of \a Type. -# define stc_set_pseudosuper(Type, PseudoSuper) \ - template<> \ - struct set_pseudosuper_type<Type> \ - { \ - typedef PseudoSuper ret; \ - }; \ - \ - struct e_n_d__w_i_t_h___s_e_m_i_c_o_l_o_n - - -/// \def Get the pseudosuper class of Type (version to be used inside a -/// template). -# define stc_get_pseudosuper(Type) \ - typename stc_get_pseudosuper_(Type) - -/// \def Get the pseudosuper class of Type (version to be used outside a -/// template). -# define stc_get_pseudosuper_(Type) \ - set_pseudosuper_type< Type >::ret - - -// --------------------- // -// Virtual type access. // -// --------------------- // - -/// Get the vtype \a Typedef, declared in \a Namespace, from the -/// exact type of \a FromType (version to be used inside a template). -#define stc_type_of(Namespace, Category, FromType, Typedef) \ - typename stc_type_of_(Namespace, Category, FromType, Typedef) - -/// Get the vtype \a Typedef, declared in \a Namespace, from the -/// exact type of \a FromType (version to be used outside a template). -#define stc_type_of_(Namespace, Category, FromType, Typedef) \ - Namespace::type_of_< Category, FromType, \ - Namespace::typedef_:: Typedef##_type >::ret - - -/// Get the vtype \a Typedef, declared in \a Namespace, from \a -/// FromType directly. (version to be used inside a template). -#define stc_direct_type_of(Namespace, Category, FromType, Typedef) \ - typename stc_direct_type_of_(Namespace, Category, FromType, Typedef) - -/// Get the vtype \a Typedef, declared in \a Namespace, from \a -/// FromType directly (version to be used outside a template). -#define stc_direct_type_of_(Namespace, Category, FromType, Typedef) \ - Namespace::direct_type_of_< Category, FromType, \ - Namespace::typedef_:: Typedef##_type >::ret - - -// ------------------------------- // -// Virtual type check and access. // -// ------------------------------- // - -/* These macros are the same as the previous ones, but they use - check_type_of_ (resp. check_direct_type_of_) instead of type_of_ - (resp. direct_type_of_). */ - -/// Get the vtype \a Typedef, declared in \a Namespace, from the -/// exact type of \a FromType (version to be used inside a template). -/// If the virtual type is not found, raise a static error. -#define stc_check_type_of(Namespace, Category, FromType, Typedef) \ - typename stc_check_type_of_(Namespace, Category, FromType, Typedef) - -/// Get the vtype \a Typedef, declared in \a Namespace, from the -/// exact type of \a FromType (version to be used outside a template). -/// If the virtual type is not found, raise a static error. -#define stc_check_type_of_(Namespace, Category, FromType, Typedef) \ - Namespace::check_type_of_< Category, FromType, \ - Namespace::typedef_:: Typedef##_type >::ret - - -/// Get the vtype \a Typedef, declared in \a Namespace, from \a -/// FromType directly. (version to be used inside a template). -/// If the virtual type is not found, raise a static error. -#define stc_check_direct_type_of(Namespace, Category, FromType, Typedef) \ - typename stc_check_direct_type_of_(Namespace, Category, FromType, Typedef) - -/// Get the vtype \a Typedef, declared in \a Namespace, from \a -/// FromType directly (version to be used outside a template). -/// If the virtual type is not found, raise a static error. -#define stc_check_direct_type_of_(Namespace, Category, FromType, Typedef) \ - Namespace::check_direct_type_of_< \ - Category, \ - FromType, \ - Namespace::typedef_:: Typedef##_type \ - >::ret - - #endif // ! STC_SCOOP_HH