410: Switch to the new properties system.

https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Switch to the new properties system. * mlc/properties.hh: Switch to the new properties system. * tests/properties.cc: Adjust test. mlc/properties.hh | 307 ++++++++++++++++++++++++++++------------------------ tests/properties.cc | 72 +++--------- 2 files changed, 189 insertions(+), 190 deletions(-) Index: tests/properties.cc --- tests/properties.cc (revision 409) +++ tests/properties.cc (working copy) @@ -1,7 +1,4 @@ -#include <ostream> - #include <mlc/properties.hh> -#include <mlc/to_string.hh> #include <mlc/cmp.hh> @@ -11,6 +8,9 @@ // browse mlc/properties.hh so as to make a list of the features to be // checked. +// Helper macro. +#define my_type_of_(FromType, Typedef) \ + mlc_typeof_(my::category::my_cat, FromType, Typedef) namespace my { @@ -42,46 +42,8 @@ struct my_cat; } - template <> - struct set_default_props < category::my_cat > - { - typedef mlc::undefined ptr_type; - }; - - /* FIXME: In the current version of SCOOP 2, this ``packing'' is no - longer done at this stage, but thanks to the `get_types' - mechanism. */ - /// Retrieval of any image type properties (FIXME: say 'packing'). - template <typename T> - struct get_props < category::my_cat, T > - { - typedef char ptr_type; - - // FIXME: Same remark as in the above FIXME: this echo() method - // should be place lower in the prop/type hierarchy. - static void echo(std::ostream& ostr) - { - ostr << "props_of( oln::category::point, " - << mlc_to_string(T) << " ) =" << std::endl - << "{" << std::endl - << "\t ptr_type = " << mlc_to_string(ptr_type) << std::endl - << "}" << std::endl; - } - - static void ensure() - { - mlc::is_ok< ptr_type >::ensure(); - } - }; - -} -// Helper macro. -#define my_type_of_(FromType, Alias) \ - mlc_type_of_(my, my::category::my_cat, FromType, Alias) -namespace my -{ /*----. | A. | `----*/ @@ -92,7 +54,7 @@ // FIXME: Rename as set_types<> when mlc/properties.hh is updated. // Associated types. template<> - struct set_props<category::my_cat, my::A> + struct set_types<category::my_cat, my::A> { typedef int foo_type; typedef float bar_type; @@ -115,28 +77,32 @@ // Forward declaration. struct B; - // FIXME: Is there any `set_super_type(T)'' sugar available? - template<> - struct set_super_type<my::B> - { - typedef A ret; - }; + // Warning, this sugar might me remove from properties.hh. + mlc_set_super(B, A); + /// \brief Redefined types associated to \a B. + /// + /// Keeping the inheritance is absolutely capital here (i.e., when + /// you redefine an associated type with redefine_types). template<> - struct set_props<category::my_cat, B> + struct redefine_types<category::my_cat, B> : + mlc_super_types_(category::my_cat, B) { - // Note: foo_type is untouched here. - // A type redefined here. typedef double bar_type; // A type defined here (but declared abstract in the super class). typedef char baz_type; + }; + + /// \brief New types associated to \a B. + template<> + struct set_types<category::my_cat, B> + { // A type defined only here (and not in the super class). typedef long quux_type; }; - // FIXME: Is there any `set_super_type(T)'' sugar available? - struct B : public internal::get_super_type<B> + struct B : public mlc_super(B) { // Aliases. typedef my_type_of_(B, foo) foo_type; Index: mlc/properties.hh --- mlc/properties.hh (revision 409) +++ mlc/properties.hh (working copy) @@ -25,6 +25,11 @@ // reasons why the executable file might be covered by the GNU General // Public License. +// \file mlc/properties.hh +// \brief Property mechanism. +// +// From Theo's presentation (olena-06-jan.pdf). + #ifndef METALIC_PROPERTIES_HH # define METALIC_PROPERTIES_HH @@ -34,209 +39,237 @@ # include <mlc/cmp.hh> # include <mlc/if.hh> # include <mlc/is_a.hh> -# include <mlc/implies.hh> -// Note: TypedefName must be of the form `typedef_::foo'. -# define mlc_internal_get_typedef_(Type, TypedefName) \ - typename TypedefName::template from_< Type >::ret +/*------------. +| Equipment. | +`------------*/ + +// Note: TypedefName *must* be of the form `typedef_::foo'. +# define mlc_internal_get_typedef(Type, TypedefName) \ + typename TypedefName::template from_< Type >::ret +// FIXME: Add support for hierarchies with several super classes. # define mlc_equip_namespace_with_properties() \ \ - template <template <typename> class abstraction> \ - struct is_a \ - { \ - template <typename E> \ - struct instantiated_with \ - { \ - typedef abstraction<E> ret; \ - }; \ - }; \ + /* ------------------------- */ \ + /* Inheritance declaration. */ \ + /* ------------------------- */ \ \ - template <typename type, unsigned i = 0> \ + template <typename type> \ struct set_super_type \ { \ typedef mlc::none ret; \ }; \ \ - template <typename type, unsigned i = 0> \ - struct set_category \ - { \ - typedef mlc::none ret; \ - }; \ \ - template <typename category> \ - struct set_default_props \ + /* ---------------------------------------- */ \ + /* ``Internal'' associated types facility. */ \ + /* ---------------------------------------- */ \ + \ + /** Fwd decl. */ \ + namespace internal { \ + template <typename category, typename from_type> struct get_types; \ + } \ + \ + /** Specialize this class to set ``internal'' associated types. */ \ + template <typename category, typename from_type> \ + struct set_types \ { \ }; \ \ - template <typename category, typename type> \ - struct set_props \ + /** \brief Specialize this class to redefine ``internal'' */ \ + /** associated types. */ \ + /** */ \ + /** Notice the inheritance relation, which enable the automatic */ \ + /** retrieval of the types associated to the super class of \a */ \ + /** from_type. */ \ + template <typename category, typename from_type> \ + struct redefine_types : public mlc_super_types(category, from_type) \ { \ }; \ \ - template <typename category, typename type> \ - struct get_props \ + \ + /* ----------------------------------------- */ \ + /* ``External'' associated types machinery. */ \ + /* ----------------------------------------- */ \ + \ + /** Fwd decl. */ \ + namespace internal { \ + template <typename category, typename from_type, typename typedef_type> \ + struct get_ext_type; \ + } \ + \ + /** Specialize this class to set an ``external'' associated type. */ \ + template <typename category, typename from_type, typename typedef_type> \ + struct set_ext_type \ { \ }; \ \ + /** \brief Specialize this class to redefine an ``external'' */ \ + /** associated type. */ \ + /** */ \ + /** Notice the inheritance relation, which enable the automatic */ \ + /** retrieval of the types associated to the super class of \a */ \ + /** from_type. */ \ template <typename category, typename from_type, typename typedef_type> \ - struct set_type \ + struct redefine_ext_type : \ + public mlc_super_ext_type(category, from_type, typedef_type) \ { \ }; \ \ - namespace internal \ - { \ \ - template <typename type, unsigned i = 0> \ - struct get_super_type : public set_super_type <type, i> \ - { \ - }; \ + /* -------------------- */ \ + /* Internal machinery. */ \ + /* -------------------- */ \ \ - template <typename type, unsigned i = 0> \ - struct get_category : public set_category <type, i> \ + /** 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 \ + { \ + template <typename category, typename from_type> \ + struct get_types : \ + public set_types<category, from_type>, \ + public redefine_types<category, from_type> \ { \ }; \ \ + /** End of the recursive construction of any get_types<> hierarchy. */ \ template <typename category> \ - struct get_default_props : public set_default_props <category> \ + struct get_types<category, mlc::none> \ { \ }; \ \ - template <typename category, typename type> \ - struct get_props : public set_props <category, type> \ + template <typename category, typename from_type, typename typedef_type> \ + struct get_ext_type : \ + public set_ext_type<category, from_type, typedef_type>, \ + public redefine_ext_type<category, from_type, typedef_type> \ { \ }; \ \ - template <typename category, typename from_type, typename typedef_type> \ - struct get_type : public set_type <category, from_type, typedef_type> \ - { \ - ~get_type() \ + /** End of the recursive construction of any get_ext_type<> */ \ + /** hierarchy. */ \ + template <typename category, typename typedef_type> \ + struct get_ext_type<category, mlc::none, typedef_type> \ { \ - typedef set_type <category, from_type, typedef_type> super_type; \ - typedef mlc_internal_get_typedef_(get_default_props<category>, \ - typedef_type) prop_type; \ - \ - mlc::implies_< mlc::neq_< mlc_ret(super_type), \ - mlc::not_found >, \ - mlc::eq_< prop_type, \ - mlc::not_found > >::ensure(); \ - } \ }; \ \ + /** Typedef selector. */ \ + /** \{ */ \ + /** Fwd decl. */ \ + template <bool external_typedef_p, bool internal_typedef_p, \ + typename external_typedef, typename internal_typedef> \ + struct select_typedef; \ \ - template <typename category, typename from_type, typename typedef_type> \ - struct f_rec_get_prop \ + /** The typedef is found in both an external and an internal */ \ + /** type definitions: error. */ \ + template <typename external_typedef, typename internal_typedef> \ + struct select_typedef<true, true, external_typedef, internal_typedef> \ { \ - typedef get_props<category, from_type> props; \ - typedef mlc_internal_get_typedef_(props, typedef_type) prop; \ - \ - typedef typename \ - mlc::if_< mlc::neq_< prop, mlc::not_found >, \ - prop, \ - typename f_rec_get_prop< category, \ - typename get_super_type<from_type, 0>::ret, \ - typedef_type >::ret \ - >::ret ret; \ + /* No ret member. */ \ }; \ \ - template <typename category, typename typedef_type> \ - struct f_rec_get_prop <category, mlc::none, typedef_type> \ - { \ - typedef mlc_internal_get_typedef_(get_default_props<category>, \ - typedef_type) ret; \ - ~f_rec_get_prop() \ + /** The typedef is found neither in an external nor in an */ \ + /** internal type definition: error. */ \ + template <typename external_typedef, typename internal_typedef> \ + struct select_typedef<false, false, external_typedef, internal_typedef> \ { \ - mlc::and_< mlc::neq_< ret, mlc::not_found >, \ - mlc::neq_< ret, mlc::undefined > >::ensure(); \ - } \ + /* No ret member. */ \ }; \ \ - \ - template <typename category, typename from_type, typename typedef_type> \ - struct f_rec_get_type \ + /** The typedef is found in an extternal definition only: good. */ \ + template <typename external_typedef, typename internal_typedef> \ + struct select_typedef<true, false, external_typedef, internal_typedef> \ { \ - typedef get_type<category, from_type, typedef_type> client_type; \ - typedef mlc_ret(client_type) type; \ - \ - typedef typename \ - mlc::if_< mlc::neq_< type, mlc::not_found >, \ - type, \ - typename f_rec_get_type< category, \ - typename get_super_type<from_type, 0>::ret, \ - typedef_type >::ret \ - >::ret ret; \ + typedef external_typedef ret; \ }; \ \ - template <typename category, typename typedef_type> \ - struct f_rec_get_type <category, mlc::none, typedef_type> \ + /** The typedef is found in an internal definition only: good. */ \ + template <typename external_typedef, typename internal_typedef> \ + struct select_typedef<false, true, external_typedef, internal_typedef> \ { \ - typedef mlc::not_found ret; \ + typedef internal_typedef ret; \ }; \ + /** \} */ \ \ + } /** End of namespace internal. */ \ + \ + \ + /** FIXME: Don't query from_type directly, but */ \ + /** exact_type(from_type) instead */ \ template <typename category, typename from_type, typename typedef_type> \ - struct f_get_type \ + struct typeof_ \ { \ + typedef internal::get_types<category, from_type> types; \ + /* FIXME: Add a check in typeof_ to ensure that get_ext_type */ \ + /* derives from get_ext_type<none> */ \ typedef \ - mlc_internal_get_typedef_(get_default_props<category>, typedef_type) \ - default_prop; \ + internal::get_ext_type<category, from_type, typedef_type> ext_type; \ + /* FIXME: Add a check in typeof_ to ensure that get_ext_type */ \ + /* derives from get_ext_type<none> */ \ \ + /** Look for the typedef as an external type. */ \ typedef \ - typename f_rec_get_prop<category, from_type, typedef_type>::ret \ - prop; \ - \ + mlc_internal_get_typedef(ext_type, typedef_::ret) external_typedef; \ + /** Look for the typedef in internal types. */ \ typedef \ - typename f_rec_get_type<category, from_type, typedef_type>::ret \ - type; \ + mlc_internal_get_typedef(types, typedef_type) internal_typedef; \ \ - ~f_get_type() \ - { \ - mlc::implies_< mlc::is_found<default_prop>, \ - mlc::is_not_found<type> >::ensure(); \ - mlc::xor_< mlc::is_found<prop>, \ - mlc::is_found<type> >::ensure(); \ - } \ + static const bool found_external_p = \ + mlc::is_found<external_typedef>::value; \ + static const bool found_internal_p = \ + mlc::is_found<internal_typedef>::value; \ \ - typedef typename mlc::if_< mlc::is_ok<prop>, \ - prop, \ - typename mlc::if_< mlc::is_ok<type>, \ - type, \ - mlc::not_ok \ - > ::ret \ - > ::ret ret; \ + typedef typename \ + internal::select_typedef<found_external_p, found_internal_p, \ + external_typedef, internal_typedef>::ret ret; \ }; \ \ - } \ - \ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n - -# define mlc_type_of_(Namespace, Category, FromType, Alias) \ - Namespace::internal::f_get_type<Category, \ - FromType, \ - Namespace::typedef_::Alias##_type>::ret - -# define mlc_type_2_of_(Namespace, Category, FromType,_2, Alias) \ - Namespace::internal::f_get_type<Category, \ - FromType,_2, \ - Namespace::typedef_::Alias##_type>::ret - - -# define mlc_type_of(Namespace, Category, FromType, Alias) \ - typename mlc_type_of_(Namespace, Category, FromType, Alias) - -# define mlc_type_2_of(Namespace, Category, FromType,_2, Alias) \ - typename mlc_type_2_of_(Namespace, Category, FromType,_2, Alias) - - - -// FIXME: TODO-list -// -// f_get_type lance d'une part f_rec_get_prop et d'autre part f_rec_get_type -// fusion des r�sultats: si 2 not_found err, si 1 ok + 1 not_found -> ok -// -// f_rec_get_prop et f_rec_get_type examine plusieurs super (i=0,1,2) +/*---------. +| Macros. | +`---------*/ + +/* FIXME: I don't know this macro will be really usable; what if T is + a template class? */ +// mlc_set_super_type(T, S) to declare the immediate base class S of T +# define mlc_set_super(Type, Super) \ + template <> \ + struct set_super_type<Type> \ + { \ + typedef Super ret; \ + } + +/// \def Get the immediate base class of T +# define mlc_super(T) \ + set_super_type<T>::ret + +// FIXME: Doc. +# define mlc_super_types(Category, FromType) \ + internal::get_types<Category, typename mlc_super(FromType)> + +// FIXME: Doc. +# define mlc_super_types_(Category, FromType) \ + internal::get_types<Category, mlc_super(FromType)> + +// FIXME: Doc. +# define mlc_super_ext_type(Category, FromType, Typedef) \ + internal::get_ext_type<Category, typename mlc_super(FromType), Typedef> + +// FIXME: Doc. +# define mlc_super_ext_type_(Category, FromType, Typedef) \ + internal::get_ext_type<Category, mlc_super(FromType), Typedef> + +/// Get the property \a Typedef from \a FromType (version with typename). +#define mlc_typeof(Category, FromType, Typedef) \ + typename typeof_<Category, FromType, typedef_:: Typedef##_type >::ret + +/// Get the property \a Typedef from \a FromType (version without typename). +#define mlc_typeof_(Category, FromType, Typedef) \ + typeof_<Category, FromType, typedef_:: Typedef##_type >::ret #endif // ! METALIC_PROPERTIES_HH
participants (1)
-
Roland Levillain