https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)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