Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
February 2006
- 4 participants
- 32 discussions
Re: [Olena-patches] 414: Revamp the virtual types (aka properties) system.
by Thierry GERAUD 28 Feb '06
by Thierry GERAUD 28 Feb '06
28 Feb '06
Roland Levillain wrote:
> There are still things to be improved, but at least we have (almost)
> all the desired functionality. The missing features that I can see
> ...
> +# define mlc_super_(T) \
> + set_super_type<T>::ret
do we really need to distinguish between set_super and get_super?
2
3
There are still things to be improved, but at least we have (almost)
all the desired functionality. The missing features that I can see
are:
- handling multiple inheritance (both declaration of super classes and
recursive retrieval of vtypes);
- using exact() in typeof_ to fetch vtypes from the exact static type
(needs mlc::any).
I'll try to factor this code (some incriminated sections have been
tagged as such).
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Revamp the virtual types (aka properties) system.
No longer use the C++'s inheritance mechanism to ``pack'' the
internal vtypes of a class. Rely on a metacode algorithm to
recursively look for vtypes in internal and external vtypes
instead, using both the super link and a ``pseudosuper'' link to
visit the upper classes. The set/get classes have been replaced
by a single class (in fact, by two classes, one for internal
vtypes, the other for external vtypes). The pseudosuper link is
used to inherit (or fetch) the vtypes from a given class, without
needing to inherit from this class.
* metalic/mlc/properties.hh (mlc_equip_namespace_with_properties):
Rewrite this macro.
(set_types, set_ext_types): Rename as...
(vtypes, ext_vtypes): ...this.
(get_types, get_ext_type): Remove.
* metalic/tests/properties.cc: Update the test.
Check for new cases (external vtype, pseudo inheritance of
vtypes).
(rec_get_vtype, rec_get_ext_vtype): New.
This class holds the algorithm for the recursive retrieval of
internal/external vtypes.
(typeof_): Adjust.
mlc/properties.hh | 281 +++++++++++++++++++++++++++++++++++-----------------
tests/properties.cc | 95 ++++++++++++-----
2 files changed, 261 insertions(+), 115 deletions(-)
Index: metalic/tests/properties.cc
--- metalic/tests/properties.cc (revision 413)
+++ metalic/tests/properties.cc (working copy)
@@ -14,22 +14,23 @@
namespace my
{
- /*----------------------.
- | Namespace equipment. |
- `----------------------*/
-
- mlc_equip_namespace_with_properties();
-
-
/*-----------.
| Typedefs. |
`-----------*/
- mlc_decl_typedef(ptr_type);
mlc_decl_typedef(foo_type);
mlc_decl_typedef(bar_type);
mlc_decl_typedef(baz_type);
mlc_decl_typedef(quux_type);
+ mlc_decl_typedef(yin_type);
+ mlc_decl_typedef(zorg_type);
+
+
+ /*----------------------.
+ | Namespace equipment. |
+ `----------------------*/
+
+ mlc_equip_namespace_with_properties();
/*-----------.
@@ -43,7 +44,6 @@
}
-
/*----.
| A. |
`----*/
@@ -51,10 +51,9 @@
// Forward declaration.
struct A;
- // FIXME: Rename as set_types<> when mlc/properties.hh is updated.
- // Associated types.
+ /// Types associated to my::A.
template<>
- struct set_types<category::my_cat, my::A>
+ struct vtypes<category::my_cat, my::A>
{
typedef int foo_type;
typedef float bar_type;
@@ -80,47 +79,93 @@
// 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).
+ /// Types associated to my::B.
template<>
- struct redefine_types<category::my_cat, B> :
- mlc_super_types_(category::my_cat, B)
+ struct vtypes<category::my_cat, B>
{
+ // (foo is left untouched.)
+
// A type redefined here.
typedef double bar_type;
// A type defined here (but declared abstract in the super class).
typedef char baz_type;
+ // A type defined only here (and not in the super class).
+ typedef long quux_type;
};
- /// \brief New types associated to \a B.
+ /// An external type associated to my::B.
template<>
- struct set_types<category::my_cat, B>
+ struct ext_vtype<category::my_cat, B, typedef_::yin_type>
{
- // A type defined only here (and not in the super class).
- typedef long quux_type;
+ typedef unsigned long ret;
};
- struct B : public mlc_super(B)
+ struct B : public mlc_super_(B)
{
// Aliases.
typedef my_type_of_(B, foo) foo_type;
typedef my_type_of_(B, bar) bar_type;
typedef my_type_of_(B, baz) baz_type;
typedef my_type_of_(B, quux) quux_type;
+ typedef my_type_of_(B, yin) yin_type;
};
+
+
+ /*---.
+ | C. |
+ `---*/
+
+ // Forward declaration.
+ struct C;
+
+ // C do not derive from B, but we want its vtypes to ``inherit''
+ // from B's vtypes (see the specilization
+ // vtypes<category::my_cat, C>.
+
+ /// Types associated to my::C.
+ template<>
+ struct vtypes<category::my_cat, C>
+ {
+ // FIXME: Having this link here is not elegant when you consider
+ // ext_vtype<>: this means that even if you have only a vtype
+ // declared as ext_vtype, you'll still have to define a
+ // corresponding vtypes<>, at least to define the pseudosuper
+ // class. What about externalizing this information, maybe with
+ // set_pseudosuper_type<>, and a macro set_pseudosuper() as sugar?
+
+ /// Link to B (``pseudo'' inheritance).
+ typedef B pseudosuper_type;
+
+ // A type defined only here (and not in the super class).
+ typedef double zorg_type;
+ };
+
+ struct C // no inheritance
+ {
+ // Aliases.
+ typedef my_type_of_(C, foo) foo_type;
+ typedef my_type_of_(C, quux) quux_type;
+ typedef my_type_of_(C, zorg) zorg_type;
+ };
+
}
+
int
main()
{
- // Check associated types.
+ // Check types associated to A.
mlc_eq(my::A::foo_type, int)::ensure ();
mlc_eq(my::A::bar_type, float)::ensure ();
- // Check associated types.
+ // Check types associated to B.
mlc_neq(my::B::bar_type, my::A::bar_type)::ensure ();
mlc_eq(my::B::baz_type, char)::ensure ();
mlc_eq(my::B::quux_type, long)::ensure ();
+ mlc_eq(my::B::yin_type, unsigned long)::ensure ();
+
+ // Check types associated to C.
+ mlc_eq(my::C::foo_type, int)::ensure ();
+ mlc_eq(my::C::quux_type, long)::ensure ();
+ mlc_eq(my::C::zorg_type, double)::ensure ();
}
Index: metalic/mlc/properties.hh
--- metalic/mlc/properties.hh (revision 413)
+++ metalic/mlc/properties.hh (working copy)
@@ -52,9 +52,21 @@
// FIXME: Add support for hierarchies with several super classes.
# define mlc_equip_namespace_with_properties() \
\
- /* ------------------------- */ \
- /* Inheritance declaration. */ \
- /* ------------------------- */ \
+ /* ----------------------- */ \
+ /* Typedefs declarations. */ \
+ /* ----------------------- */ \
+ \
+ /* FIXME: Should we use the `ret' typdef defined in the global */ \
+ /* namespace instead ? (see at the end mlc/typedef.hh). */ \
+ mlc_decl_typedef(ret); \
+ \
+ /* Declare the ``uplink'' typedef (access to a pseudosuper class). */ \
+ mlc_decl_typedef(pseudosuper_type); \
+ \
+ \
+ /* ------------- */ \
+ /* Inheritance. */ \
+ /* ------------- */ \
\
template <typename type> \
struct set_super_type \
@@ -63,58 +75,36 @@
}; \
\
\
- /* ---------------------------------------- */ \
- /* ``Internal'' associated types facility. */ \
- /* ---------------------------------------- */ \
+ /* --------------- */ \
+ /* Virtual types. */ \
+ /* --------------- */ \
\
- /** Fwd decl. */ \
- namespace internal { \
- template <typename category, typename from_type> struct get_types; \
- } \
- \
- /** Specialize this class to set ``internal'' associated types. */ \
+ /** \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 set_types \
+ struct vtypes \
{ \
}; \
\
- /** \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) \
+ /** End of the recursive construction of any vtypes hierarchy. */ \
+ template <typename category> \
+ struct vtypes<category, mlc::none> \
{ \
}; \
\
- \
- /* ----------------------------------------- */ \
- /* ``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. */ \
+ /** \brief An external 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 set_ext_type \
+ struct ext_vtype \
{ \
}; \
\
- /** \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 redefine_ext_type : \
- public mlc_super_ext_type(category, from_type, typedef_type) \
+ /** End of the recursive construction of any ext_vtype<> */ \
+ /** hierarchy. */ \
+ template <typename category, typename typedef_type> \
+ struct ext_vtype<category, mlc::none, typedef_type> \
{ \
}; \
\
@@ -128,34 +118,162 @@
/** 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> \
+ /* ------------------------------------------ */ \
+ /* Recursive retrieval of an internal vtype. */ \
+ /* ------------------------------------------ */ \
+ \
+ /* FIXME: Do a basic scheme of the algorithm in pseudo-code. */ \
+ \
+ /* FIXME: Check for mlc::undefined? */ \
+ \
+ /* 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 (maybe mlc::not_found). */ \
+ typedef mlc_internal_get_typedef(types, typedef_type) type; \
+ \
+ /** Implicit parent (i.e. super), if any. */ \
+ typedef mlc_super(from_type) super; \
+ /** Pseudosuper class, if any. */ \
+ typedef mlc_internal_get_typedef(types, typedef_::pseudosuper_type) \
+ pseudosuper; \
+ \
+ 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; \
}; \
\
- /** End of the recursive construction of any get_types<> hierarchy. */ \
- template <typename category> \
- struct get_types<category, mlc::none> \
+ /** 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> \
+ { \
+ 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_vtype<category, mlc::not_found, typedef_type> \
{ \
+ typedef mlc::not_found ret; \
}; \
+ /** \} */ \
+ \
+ /* ------------------------------------------ */ \
+ /* Recursive retrieval of an external vtype. */ \
+ /* ------------------------------------------ */ \
+ \
+ /* FIXME: Merge this with rec_get_vtype. */ \
\
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> \
+ struct rec_get_ext_vtype \
{ \
+ /** Set of vtypes associated with FROM_TYPE. */ \
+ typedef ext_vtype<category, from_type, typedef_type> ext_type; \
+ /** Typedef in the current vtypes (maybe mlc::not_found). */ \
+ typedef mlc_internal_get_typedef(ext_type, typedef_::ret) type; \
+ \
+ /** Implicit parent (i.e. super), if any. */ \
+ typedef mlc_super(from_type) super; \
+ /** Pseudosuper class, if any. */ \
+ /* FIXME: Looking for this information is not elegant. Have a */ \
+ /* look at metalic/tests/properties.cc for a better suggestion. */ \
+ typedef vtypes<category, from_type> types; \
+ typedef mlc_internal_get_typedef(types, typedef_::pseudosuper_type) \
+ pseudosuper; \
+ \
+ 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_ext_vtype< category, \
+ super, \
+ typedef_type >::ret, \
+ mlc::not_found >, \
+ /* then */ \
+ /* return it */ \
+ typename rec_get_ext_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_ext_vtype< category, \
+ pseudosuper, \
+ typedef_type >::ret>::ret>::ret \
+ ret; \
}; \
\
- /** End of the recursive construction of any get_ext_type<> */ \
- /** hierarchy. */ \
+ /** 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_ext_vtype<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 get_ext_type<category, mlc::none, typedef_type> \
+ struct rec_get_ext_vtype<category, mlc::not_found, typedef_type> \
{ \
+ typedef mlc::not_found ret; \
}; \
+ /** \} */ \
+ \
+ /* ------------------------------------- */ \
+ /* External/internal typedef selection. */ \
+ /* ------------------------------------- */ \
\
- /** Typedef selector. */ \
+ /** \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 external vtype. */ \
+ /** Other cases (no definition or a double definition) are invalid. */ \
+ /** */ \
/** \{ */ \
/** Fwd decl. */ \
template <bool external_typedef_p, bool internal_typedef_p, \
@@ -196,26 +314,21 @@
} /** End of namespace internal. */ \
\
\
- /** FIXME: Don't query from_type directly, but */ \
- /** exact_type(from_type) instead */ \
+ /* FIXME: Don't query from_type directly, but exact_type(from_type) */ \
+ /* instead. We need mlc::any for this. */ \
template <typename category, typename from_type, typename typedef_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 \
- 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 \
- mlc_internal_get_typedef(ext_type, typedef_::ret) external_typedef; \
- /** Look for the typedef in internal types. */ \
- typedef \
- mlc_internal_get_typedef(types, typedef_type) internal_typedef; \
+ /* 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_typedef; \
\
+ /* Did we found the virtual type? */ \
static const bool found_external_p = \
mlc::is_found<external_typedef>::value; \
static const bool found_internal_p = \
@@ -243,25 +356,13 @@
typedef Super ret; \
}
-/// \def Get the immediate base class of T
+/// \def Get the immediate base class of T (version with typename).
# define mlc_super(T) \
- set_super_type<T>::ret
+ typename 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>
+/// \def Get the immediate base class of T (version without typename).
+# define mlc_super_(T) \
+ set_super_type<T>::ret
/// Get the property \a Typedef from \a FromType (version with typename).
#define mlc_typeof(Category, FromType, Typedef) \
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Enhance error handling in mlc::switch_.
* tests/switch.cc: New file.
* mlc/switch.hh (case_true, case_false): New classes.
(case_type): New typedef in classes.
(case_, switch_): Modify error handling.
mlc/switch.hh | 107 +++++++++++++++++++++++++++++++++++++++++++++++---------
tests/switch.cc | 78 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 168 insertions(+), 17 deletions(-)
Index: tests/switch.cc
--- tests/switch.cc (revision 0)
+++ tests/switch.cc (revision 0)
@@ -0,0 +1,78 @@
+#include <mlc/is_a.hh>
+#include <mlc/switch.hh>
+
+
+struct test;
+
+
+namespace mlc
+{
+
+ template <class T>
+ struct case_ <test, T, 1> : public where_< mlc_is_a(T, short) >
+ {
+ typedef float ret;
+ };
+
+ template <class T>
+ struct case_ <test, T, 2> : public where_< mlc_is_a(T, int) >
+ {
+ typedef double ret;
+ };
+
+
+// // ok
+
+// template <class T>
+// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// {
+// typedef int ret;
+// };
+
+
+// // ko
+
+// template <class T>
+// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// {
+// typedef not_found ret;
+// };
+
+// template <class T>
+// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// {
+// };
+
+// template <class T>
+// struct case_ <test, T, 3>
+// {
+// typedef int ret;
+// };
+
+// template <class T>
+// struct default_case_ <test, T> : public where_< mlc::true_ >
+// {
+// typedef int ret;
+// };
+
+// template <class T>
+// struct default_case_ <test, T>
+// {
+// };
+
+
+} // end of namespace mlc
+
+
+template <class T>
+void print()
+{
+ int tmp;
+}
+
+
+
+int main()
+{
+ print< mlc::switch_<test, char>::ret >();
+}
Index: mlc/switch.hh
--- mlc/switch.hh (revision 412)
+++ mlc/switch.hh (working copy)
@@ -34,6 +34,7 @@
# include <mlc/implies.hh>
# include <mlc/comma.hh>
# include <mlc/cmp.hh>
+# include <mlc/if.hh>
namespace mlc
@@ -41,11 +42,36 @@
// FIXME: doc
+ namespace internal
+ {
+ struct case_true {};
+ struct case_false {};
+
+ } // end of namespace mlc::internal
+
+
template <typename bexpr>
- struct where_ : public bexpr::eval
+ struct where_ : public mlc_if_( typename bexpr::eval,
+ internal::case_true,
+ internal::case_false )
{
};
+// template <typename bexpr>
+// struct where_ : public where_<typename bexpr::eval>
+// {
+// };
+
+// template <>
+// struct where_<true_>
+// {
+// };
+
+// template <>
+// struct where_<false_>
+// {
+// };
+
// FIXME: doc
@@ -57,6 +83,7 @@
{
};
+
template <typename context,
typename data>
struct case_ <context, data, 0>;
@@ -73,7 +100,9 @@
{
struct A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_;
struct A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_;
- struct RESULT_NOT_FOUND;
+ struct SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA;
+ struct RESULT_IS_NOT_FOUND_IN_default_case_;
+ template <unsigned i> struct RESULT_IS_NOT_FOUND_IN_case_;
} // end of namespace mlc::ERROR
@@ -87,81 +116,124 @@
struct handle_case_;
+
// impossible situation
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
1, 1>;
+
+
+ // default case
+
template <typename context, typename data>
struct handle_default_case_
+
: private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
undefined),
mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
where_) >,
- ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >
+ ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >,
+
+ private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
+ undefined),
+ neq_<mlc_ret(mlc_comma_1(default_case_<context, data>)),
+ not_found> >,
+ ERROR::RESULT_IS_NOT_FOUND_IN_default_case_ >
+
{
- typedef mlc_ret( mlc_comma_1(default_case_<context, data>) ) ret;
+ typedef default_case_<context, data> current_t;
+ typedef typename mlc::if_<mlc_is_a(current_t, undefined),
+ none,
+ current_t>::ret case_type;
+ typedef mlc_ret(current_t) ret;
};
+
+
// there is no more user-defined cases
- // so go to the default case
+ // so go to the default case (the last case handled here)
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
0, 0>
+
: private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
undefined),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_) >,
ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+
{
- typedef mlc_ret( mlc_comma_1(handle_default_case_<context, data>) ) ret;
+ typedef handle_default_case_<context, data> last_t;
+ typedef typename last_t::case_type case_type;
+ typedef typename last_t::ret ret;
};
// current case is the one
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
1, 0>
+
: private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
undefined) >,
- ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >,
+
+ private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
+ undefined),
+ neq_<mlc_ret(mlc_comma_2(case_<context, data, i>)),
+ not_found> >,
+ ERROR::RESULT_IS_NOT_FOUND_IN_case_<i> >
+
{
- typedef mlc_ret( mlc_comma_2(case_<context, data, i>) ) ret;
+ typedef case_<context, data, i> case_type;
+ typedef mlc_ret(case_type) ret;
};
+
// current case is not the one
// so go to the next case
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
0, 1>
+
: private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
undefined) >,
ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+
{
typedef handle_case_ < context, data, i+1,
mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
- true_)::value,
+ internal::case_true)::value,
mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
- false_)::value > next_t;
+ internal::case_false)::value > next_t;
+ typedef typename next_t::case_type case_type;
typedef typename next_t::ret ret;
};
+
// switch_
+
template <typename context, typename data>
struct switch_
{
- typedef typename internal::handle_case_ < context, data, 1,
+ typedef internal::handle_case_ < context, data, 1,
mlc_is_a(mlc_comma_2(case_<context, data, 1>),
- true_)::value,
+ internal::case_true)::value,
mlc_is_a(mlc_comma_2(case_<context, data, 1>),
- false_)::value
- >::ret ret;
+ internal::case_false)::value > handle_t;
+ typedef typename handle_t::case_type case_type;
+ typedef typename handle_t::ret ret;
};
@@ -173,10 +245,11 @@
template <typename context, typename data>
struct switch_
- : private assert_< neq_<typename internal::switch_<context, data>::ret,
- not_found>,
- ERROR::RESULT_NOT_FOUND >
+ : private assert_< neq_< mlc_comma_1(typename internal::switch_<context, data>::case_type),
+ none >,
+ ERROR::SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA >
{
+ typedef typename internal::switch_<context, data>::case_type case_type;
typedef typename internal::switch_<context, data>::ret ret;
};
1
0
17 Feb '06
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Modify mlc::assert_ to handle explicit error messages; also.
* mlc/elt.hh: Fix bug.
* mlc/pair.hh: Add explicit error messages.
* mlc/valist.hh: Likewise.
* mlc/bool.hh (ASSERTION_FAILED_, AN_ASSERTION_FAILED_): Remove
so that error messages are more concise.
(iff_, mlc_iff): Rename as...
(type_iff_, mlc_type_iff): ...these.
(assert_): Update.
* mlc/switch.hh: New.
* mlc/is_a.hh (internal::is_a): Move and rename as...
(is_a_): ...this so error messages are shortern.
* mlc/cmp.hh: Pretty print.
bool.hh | 85 ++++++++++------------------
cmp.hh | 0
elt.hh | 4 -
is_a.hh | 67 ++++++++++++----------
pair.hh | 12 +++
switch.hh | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
valist.hh | 16 ++++-
7 files changed, 281 insertions(+), 90 deletions(-)
Index: mlc/elt.hh
--- mlc/elt.hh (revision 411)
+++ mlc/elt.hh (working copy)
@@ -29,9 +29,9 @@
# define METALIC_ELT_HH
-# define mlc_elt(Type, Ith) typename Type::template elt<I>::ret
+# define mlc_elt(Type, Index) typename Type::template elt<Index>::ret
-# define mlc_elt_(Type, Ith) Type::template elt<I>::ret
+# define mlc_elt_(Type, Index) Type::template elt<Index>::ret
Index: mlc/pair.hh
--- mlc/pair.hh (revision 411)
+++ mlc/pair.hh (working copy)
@@ -46,6 +46,15 @@
} // end of namespace mlc::internal
+
+ namespace ERROR
+ {
+ struct PAIR_ELT_INDEX_SHOULD_BE_1_OR_2;
+
+ } // end of namespace mlc::ERROR
+
+
+
/*! \class mlc::pair_<E1, E2>
**
** This class is FIXME */
@@ -60,7 +69,8 @@
template <unsigned i>
struct elt : private assert_< or_< uint_equal_<i, 1>,
- uint_equal_<i, 2> > >,
+ uint_equal_<i, 2> >,
+ ERROR::PAIR_ELT_INDEX_SHOULD_BE_1_OR_2 >,
public internal::pair_elt_<E1, E2, i>
{
};
Index: mlc/bool.hh
--- mlc/bool.hh (revision 411)
+++ mlc/bool.hh (working copy)
@@ -42,12 +42,12 @@
-/*! \def mlc_iff(Type, BExpr)
+/*! \def mlc_type_iff(Type, BExpr)
**
** FIXME: doc
*/
-# define mlc_iff(Type, BExpr) typename mlc::iff_<Type, BExpr>::ret
-# define mlc_iff_(Type, BExpr) mlc::iff_<Type, BExpr>::ret
+# define mlc_type_iff(Type, BExpr) typename mlc::type_iff_<Type, BExpr>::ret
+# define mlc_type_iff_(Type, BExpr) mlc::type_iff_<Type, BExpr>::ret
@@ -196,41 +196,6 @@
{
};
-
- // FIXME: doc
-
- template <typename bexpr, typename err>
- struct ASSERTION_FAILED_ :
- private virtual check_<bexpr, typename bexpr::is_true>
- {
- };
-
-
- // FIXME: doc
-
- template <typename bexpr1,
- typename bexpr2,
- typename bexpr3,
- typename bexpr4,
- typename bexpr5,
- typename bexpr6,
- typename bexpr7,
- typename bexpr8,
- typename bexpr9>
- struct AN_ASSERTION_FAILED_ :
- private virtual check_item_<1, bexpr1, typename bexpr1::is_true>,
- private virtual check_item_<2, bexpr2, typename bexpr2::is_true>,
- private virtual check_item_<3, bexpr3, typename bexpr3::is_true>,
- private virtual check_item_<4, bexpr4, typename bexpr4::is_true>,
- private virtual check_item_<5, bexpr5, typename bexpr5::is_true>,
- private virtual check_item_<6, bexpr6, typename bexpr6::is_true>,
- private virtual check_item_<7, bexpr7, typename bexpr7::is_true>,
- private virtual check_item_<8, bexpr8, typename bexpr8::is_true>,
- private virtual check_item_<9, bexpr9, typename bexpr9::is_true>
- {
- };
-
-
} // end of namespace mlc::internal
@@ -310,27 +275,40 @@
*/
template <typename bexpr, typename err = no_error_message>
- struct assert_ : public internal::ASSERTION_FAILED_<bexpr, err>
+ struct assert_ :
+ private virtual internal::check_<bexpr, typename bexpr::is_true>
{
- static void run() {}
+ typedef dummy is_true;
protected:
assert_() {}
};
- /*! \class mlc::iff_<T, bexpr>
+ /*! \class mlc::type_iff_<T, bexpr>
**
** FIXME: doc
- ** T iff bexpr
+ ** returns type T iff bexpr
*/
template <typename T, typename bexpr>
- struct iff_ :
+ struct type_iff_ :
private assert_<bexpr>
{
typedef T ret;
};
+ /*! \class mlc::literal_<T>
+ **
+ ** FIXME: doc
+ */
+
+ template <typename T>
+ struct literal_
+ {
+ typedef T ret;
+ };
+
+
/*! \class mlc::multiple_assert_<bexpr1..>
**
** FIXME: this doc is partially obsolete!
@@ -373,23 +351,22 @@
typename bexpr7 = no_bexpr,
typename bexpr8 = no_bexpr,
typename bexpr9 = no_bexpr>
- struct multiple_assert_ : public internal::AN_ASSERTION_FAILED_<bexpr1,
- bexpr2,
- bexpr3,
- bexpr4,
- bexpr5,
- bexpr6,
- bexpr7,
- bexpr8,
- bexpr9>
+ struct multiple_assert_ :
+ private virtual internal::check_item_<1, bexpr1, typename bexpr1::is_true>,
+ private virtual internal::check_item_<2, bexpr2, typename bexpr2::is_true>,
+ private virtual internal::check_item_<3, bexpr3, typename bexpr3::is_true>,
+ private virtual internal::check_item_<4, bexpr4, typename bexpr4::is_true>,
+ private virtual internal::check_item_<5, bexpr5, typename bexpr5::is_true>,
+ private virtual internal::check_item_<6, bexpr6, typename bexpr6::is_true>,
+ private virtual internal::check_item_<7, bexpr7, typename bexpr7::is_true>,
+ private virtual internal::check_item_<8, bexpr8, typename bexpr8::is_true>,
+ private virtual internal::check_item_<9, bexpr9, typename bexpr9::is_true>
{
- static void run() {}
protected:
multiple_assert_() {}
};
-
/*! \class mlc::bool_<true>
**
** Specialization of mlc::bool_<b> for b set to true. This type
Index: mlc/switch.hh
--- mlc/switch.hh (revision 0)
+++ mlc/switch.hh (revision 0)
@@ -0,0 +1,187 @@
+// Copyright (C) 2005, 2006 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef METALIC_SWITCH_HH
+# define METALIC_SWITCH_HH
+
+# include <mlc/bool.hh>
+# include <mlc/typedef.hh>
+# include <mlc/is_a.hh>
+# include <mlc/implies.hh>
+# include <mlc/comma.hh>
+# include <mlc/cmp.hh>
+
+
+namespace mlc
+{
+
+ // FIXME: doc
+
+ template <typename bexpr>
+ struct where_ : public bexpr::eval
+ {
+ };
+
+
+
+ // FIXME: doc
+
+ template <typename context,
+ typename data,
+ unsigned i>
+ struct case_ : public undefined
+ {
+ };
+
+ template <typename context,
+ typename data>
+ struct case_ <context, data, 0>;
+
+
+ template <typename context,
+ typename data>
+ struct default_case_ : public undefined
+ {
+ };
+
+
+ namespace ERROR
+ {
+ struct A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_;
+ struct A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_;
+ struct RESULT_NOT_FOUND;
+
+ } // end of namespace mlc::ERROR
+
+
+ namespace internal
+ {
+
+ template <typename context, typename data, unsigned i,
+ bool the_ith_case_derives_from_true,
+ bool the_ith_case_derives_from_false>
+ struct handle_case_;
+
+
+ // impossible situation
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 1, 1>;
+
+ template <typename context, typename data>
+ struct handle_default_case_
+ : private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
+ undefined),
+ mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
+ where_) >,
+ ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >
+ {
+ typedef mlc_ret( mlc_comma_1(default_case_<context, data>) ) ret;
+ };
+
+ // there is no more user-defined cases
+ // so go to the default case
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 0, 0>
+ : private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
+ undefined),
+ mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ where_) >,
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ {
+ typedef mlc_ret( mlc_comma_1(handle_default_case_<context, data>) ) ret;
+ };
+
+
+ // current case is the one
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 1, 0>
+ : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ where_),
+ mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ undefined) >,
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ {
+ typedef mlc_ret( mlc_comma_2(case_<context, data, i>) ) ret;
+ };
+
+
+ // current case is not the one
+ // so go to the next case
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 0, 1>
+ : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ where_),
+ mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ undefined) >,
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ {
+ typedef handle_case_ < context, data, i+1,
+ mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
+ true_)::value,
+ mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
+ false_)::value > next_t;
+ typedef typename next_t::ret ret;
+ };
+
+
+ // switch_
+ template <typename context, typename data>
+ struct switch_
+ {
+ typedef typename internal::handle_case_ < context, data, 1,
+ mlc_is_a(mlc_comma_2(case_<context, data, 1>),
+ true_)::value,
+ mlc_is_a(mlc_comma_2(case_<context, data, 1>),
+ false_)::value
+ >::ret ret;
+ };
+
+
+ } // end of namespace mlc::internal
+
+
+
+ // FIXME: doc
+
+ template <typename context, typename data>
+ struct switch_
+ : private assert_< neq_<typename internal::switch_<context, data>::ret,
+ not_found>,
+ ERROR::RESULT_NOT_FOUND >
+ {
+ typedef typename internal::switch_<context, data>::ret ret;
+ };
+
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_SWITCH_HH
Index: mlc/valist.hh
--- mlc/valist.hh (revision 411)
+++ mlc/valist.hh (working copy)
@@ -46,7 +46,6 @@
# define mlc_internal_valist_elt_spe(I) \
template < mlc_internal_valist_decl_params_ > \
struct valist_elt_ < mlc_internal_valist_params_, I > \
- : private assert_< neq_<E##I, internal::valist_none> > \
{ \
typedef E##I ret; \
}
@@ -74,6 +73,15 @@
**
** This class is FIXME */
+
+ namespace ERROR
+ {
+ struct VALIST_ELT_INDEX_SHOULD_BE_1_OR_GREATER;
+ struct VALIST_ELT_INDEX_IS_GREATER_THAN_LIST_SIZE;
+
+ } // end of namespace mlc::ERROR
+
+
template < typename E1 = internal::valist_none,
typename E2 = internal::valist_none,
typename E3 = internal::valist_none,
@@ -89,8 +97,10 @@
valist_<mlc_internal_valist_params_> >::value;
template <unsigned i>
- struct elt : private multiple_assert_< uint_greater_or_equal_<i, 1>,
- uint_less_or_equal_<i, size_value> >,
+ struct elt : private assert_< uint_greater_or_equal_<i, 1>,
+ ERROR::VALIST_ELT_INDEX_SHOULD_BE_1_OR_GREATER >,
+ private assert_< uint_less_or_equal_<i, size_value>,
+ ERROR::VALIST_ELT_INDEX_IS_GREATER_THAN_LIST_SIZE >,
public internal::valist_elt_<mlc_internal_valist_params_, i>
{
};
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 411)
+++ mlc/is_a.hh (working copy)
@@ -34,7 +34,7 @@
// private macro so do _not_ use it
# define mlc_internal_is_a_result_ \
-sizeof(helper<T,U>::select((T*)helper<T,U>::makeT())) == sizeof(yes_)
+sizeof(helper<T,U>::select((T*)helper<T,U>::makeT())) == sizeof(internal::yes_)
namespace mlc
@@ -81,25 +81,27 @@
typedef char yes_;
struct no_ { char dummy[2]; };
+ } // end of namespace mlc::internal
+
- // dev note : below, is_a<T,id> is a better factorization
+ // dev note : below, is_a_<T,id> is a better factorization
// but g++ 2.95.4 has some trouble with it
template<unsigned id>
- struct is_a;
+ struct is_a_;
// class_
template<>
- struct is_a< form::class_ >
+ struct is_a_< form::class_ >
{
- typedef is_a< form::class_ > self;
+ typedef is_a_< form::class_ > self;
template<class T, class U>
struct helper
{
- static yes_ select(U*);
- static no_ select(...);
+ static internal::yes_ select(U*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -113,16 +115,16 @@
// template_l_class_r_class_
template<>
- struct is_a< form::template_l_class_r_class_ >
+ struct is_a_< form::template_l_class_r_class_ >
{
- typedef is_a< form::template_l_class_r_class_ > self;
+ typedef is_a_< form::template_l_class_r_class_ > self;
template<class T, template < class > class U>
struct helper
{
template<class V>
- static yes_ select(U<V>*);
- static no_ select(...);
+ static internal::yes_ select(U<V>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -136,16 +138,16 @@
// template_l_class_class_r_class_
template<>
- struct is_a< form::template_l_class_class_r_class_ >
+ struct is_a_< form::template_l_class_class_r_class_ >
{
- typedef is_a< form::template_l_class_class_r_class_ > self;
+ typedef is_a_< form::template_l_class_class_r_class_ > self;
template<class T, template < class,class > class U>
struct helper
{
template<class V, class W>
- static yes_ select(U<V,W>*);
- static no_ select(...);
+ static internal::yes_ select(U<V,W>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -158,16 +160,16 @@
// template_l_template_l_class_r_class_r_class_
template<>
- struct is_a< form::template_l_template_l_class_r_class_r_class_ >
+ struct is_a_< form::template_l_template_l_class_r_class_r_class_ >
{
- typedef is_a< form::template_l_template_l_class_r_class_r_class_ > self;
+ typedef is_a_< form::template_l_template_l_class_r_class_r_class_ > self;
template<class T, template < template < class > class > class U>
struct helper
{
template<template<class> class V>
- static yes_ select(U<V>*);
- static no_ select(...);
+ static internal::yes_ select(U<V>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -180,16 +182,16 @@
// template_l_template_l_class_class_r_class_r_class_
template<>
- struct is_a< form::template_l_template_l_class_class_r_class_r_class_ >
+ struct is_a_< form::template_l_template_l_class_class_r_class_r_class_ >
{
- typedef is_a< form::template_l_template_l_class_class_r_class_r_class_ > self;
+ typedef is_a_< form::template_l_template_l_class_class_r_class_r_class_ > self;
template<class T, template < template < class,class > class > class U>
struct helper
{
template<template<class,class> class V>
- static yes_ select(U<V>*);
- static no_ select(...);
+ static internal::yes_ select(U<V>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -199,7 +201,6 @@
{};
};
- } // end of namespace mlc::internal
} // end of namespace mlc
@@ -237,19 +238,25 @@
*/
# define mlc_is_a(T, U) \
-mlc::wrap_<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > >
+mlc::wrap_< typename mlc::is_a_<sizeof(mlc::form::of<U >())>::ret<T,U > >
+# define mlc_is_a_(T, U) \
+mlc::is_a_< sizeof(mlc::form::of<U >())>::ret<T,U >
-/*! \def mlc_is_a_(T, U)
+
+/*! \def mlc_is_not_a(T, U)
**
-** Macro equivalent as mlc_is_a(T, U) for use in a non templated
-** context. The result is a Boolean expression type.
+** Macro equivalent as "not mlc_is_a(T, U)". The result is a Boolean
+** expression type.
**
** \see mlc_is_a(T, U)
*/
-# define mlc_is_a_(T, U) \
-mlc::wrap_<mlc::internal::is_a< sizeof(mlc::form::of<U >())>::ret<T,U > >
+# define mlc_is_not_a(T, U) \
+mlc::not_< typename mlc::is_a_<sizeof(mlc::form::of<U >())>::ret<T,U > >
+
+# define mlc_is_not_a_(T, U) \
+mlc::not_< mlc::is_a_< sizeof(mlc::form::of<U >())>::ret<T,U > >
#endif // ! METALIC_IS_A_HH
Index: mlc/cmp.hh
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
Sorry for the ugly diff (damn macros !). Reading the new
mlc/properties.hh is probably easier.
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
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
This is just for testing purpose (namely, to see if the new typedef
facility works with the old properties). I'm currently working on the
new implementation of mlc/properties.hh, described in Théo's
presentation from January 2006.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add the old properties system.
* tests/properties.cc, mlc/to_string.hh: New files.
* mlc/properties.hh: New test.
mlc/properties.hh | 53 +++++++----------
tests/properties.cc | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 184 insertions(+), 29 deletions(-)
Index: tests/properties.cc
--- tests/properties.cc (revision 0)
+++ tests/properties.cc (revision 0)
@@ -0,0 +1,160 @@
+#include <ostream>
+
+#include <mlc/properties.hh>
+#include <mlc/to_string.hh>
+#include <mlc/cmp.hh>
+
+
+// FIXME: Split this test into several smaller tests? For instance,
+// we have to test inheritance, properties/associated types,
+// ``external properties'', etc. The best approach is probably to
+// browse mlc/properties.hh so as to make a list of the features to be
+// checked.
+
+
+namespace my
+{
+ /*----------------------.
+ | Namespace equipment. |
+ `----------------------*/
+
+ mlc_equip_namespace_with_properties();
+
+
+ /*-----------.
+ | Typedefs. |
+ `-----------*/
+
+ mlc_decl_typedef(ptr_type);
+ mlc_decl_typedef(foo_type);
+ mlc_decl_typedef(bar_type);
+ mlc_decl_typedef(baz_type);
+ mlc_decl_typedef(quux_type);
+
+
+ /*-----------.
+ | Category. |
+ `-----------*/
+
+ // We only use one category here.
+ namespace category
+ {
+ 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. |
+ `----*/
+
+ // Forward declaration.
+ struct A;
+
+ // FIXME: Rename as set_types<> when mlc/properties.hh is updated.
+ // Associated types.
+ template<>
+ struct set_props<category::my_cat, my::A>
+ {
+ typedef int foo_type;
+ typedef float bar_type;
+ typedef mlc::undefined baz_type;
+ };
+
+ class A
+ {
+ // Aliases.
+ typedef my_type_of_(A, foo) foo_type;
+ typedef my_type_of_(A, bar) bar_type;
+ typedef my_type_of_(A, baz) baz_type;
+ };
+
+
+ /*------------.
+ | B ---|> A. |
+ `------------*/
+
+ // Forward declaration.
+ struct B;
+
+ // FIXME: Is there any `set_super_type(T)'' sugar available?
+ template<>
+ struct set_super_type<my::B>
+ {
+ typedef A ret;
+ };
+
+ template<>
+ struct set_props<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;
+ // 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?
+ class B : public internal::get_super_type<B>
+ {
+ // Aliases.
+ typedef my_type_of_(B, foo) foo_type;
+ typedef my_type_of_(B, bar) bar_type;
+ typedef my_type_of_(B, baz) baz_type;
+ typedef my_type_of_(B, quux) quux_type;
+ };
+}
+
+int
+main()
+{
+ // Check associated types.
+ mlc_eq(my::A::foo_type, int)::ensure ();
+ mlc_eq(my::A::bar_type, float)::ensure ();
+
+ // Check associated types.
+ mlc_neq(my::B::bar_type, my::A::bar_type)::ensure ();
+ mlc_eq(my::B::baz_type, char)::ensure ();
+ mlc_eq(my::B::quux_type, long)::ensure ();
+}
Index: mlc/properties.hh
--- mlc/properties.hh (revision 0)
+++ mlc/properties.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2005 EPITA Research and Development Laboratory
+// Copyright (C) 2005, 2006 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,26 +28,21 @@
#ifndef METALIC_PROPERTIES_HH
# define METALIC_PROPERTIES_HH
-# include <mlc/types.hh>
+# include <mlc/flags.hh>
# include <mlc/typedef.hh>
# include <mlc/bool.hh>
-# include <mlc/implies.hh>
# include <mlc/cmp.hh>
# include <mlc/if.hh>
# include <mlc/is_a.hh>
+# include <mlc/implies.hh>
-
-// this is an internal macro
-# define mlc_internal_get_typedef_(FromType, TypedefType) \
- typename internal::get_typedef <FromType, TypedefType> ::ret
-
+// Note: TypedefName must be of the form `typedef_::foo'.
+# define mlc_internal_get_typedef_(Type, TypedefName) \
+ typename TypedefName::template from_< Type >::ret
# define mlc_equip_namespace_with_properties() \
\
- mlc_equip_namespace_with_typedef(); \
- mlc_decl_typedef(ret); \
- \
template <template <typename> class abstraction> \
struct is_a \
{ \
@@ -61,13 +56,13 @@
template <typename type, unsigned i = 0> \
struct set_super_type \
{ \
- typedef mlc::no_type ret; \
+ typedef mlc::none ret; \
}; \
\
template <typename type, unsigned i = 0> \
struct set_category \
{ \
- typedef mlc::no_type ret; \
+ typedef mlc::none ret; \
}; \
\
template <typename category> \
@@ -122,10 +117,10 @@
typedef mlc_internal_get_typedef_(get_default_props<category>, \
typedef_type) prop_type; \
\
- mlc::implies< mlc::neq< mlc_typedef_of(super_type, ret), \
- mlc::internal::not_found >, \
- mlc::eq< prop_type, \
- mlc::internal::not_found > >::ensure(); \
+ mlc::implies_< mlc::neq_< mlc_ret(super_type), \
+ mlc::not_found >, \
+ mlc::eq_< prop_type, \
+ mlc::not_found > >::ensure(); \
} \
}; \
\
@@ -137,7 +132,7 @@
typedef mlc_internal_get_typedef_(props, typedef_type) prop; \
\
typedef typename \
- mlc::if_< mlc::neq< prop, mlc::internal::not_found >, \
+ mlc::if_< mlc::neq_< prop, mlc::not_found >, \
prop, \
typename f_rec_get_prop< category, \
typename get_super_type<from_type, 0>::ret, \
@@ -146,14 +141,14 @@
}; \
\
template <typename category, typename typedef_type> \
- struct f_rec_get_prop <category, mlc::no_type, 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() \
{ \
- mlc::and_< mlc::neq< ret, mlc::internal::not_found >, \
- mlc::neq< ret, mlc::undefined_type > >::ensure(); \
+ mlc::and_< mlc::neq_< ret, mlc::not_found >, \
+ mlc::neq_< ret, mlc::undefined > >::ensure(); \
} \
}; \
\
@@ -162,10 +157,10 @@
struct f_rec_get_type \
{ \
typedef get_type<category, from_type, typedef_type> client_type; \
- typedef mlc_typedef_of(client_type, ret) type; \
+ typedef mlc_ret(client_type) type; \
\
typedef typename \
- mlc::if_< mlc::neq< type, mlc::internal::not_found >, \
+ mlc::if_< mlc::neq_< type, mlc::not_found >, \
type, \
typename f_rec_get_type< category, \
typename get_super_type<from_type, 0>::ret, \
@@ -174,9 +169,9 @@
}; \
\
template <typename category, typename typedef_type> \
- struct f_rec_get_type <category, mlc::no_type, typedef_type> \
+ struct f_rec_get_type <category, mlc::none, typedef_type> \
{ \
- typedef mlc::internal::not_found ret; \
+ typedef mlc::not_found ret; \
}; \
\
template <typename category, typename from_type, typename typedef_type> \
@@ -196,7 +191,7 @@
\
~f_get_type() \
{ \
- mlc::implies< mlc::is_found<default_prop>, \
+ mlc::implies_< mlc::is_found<default_prop>, \
mlc::is_not_found<type> >::ensure(); \
mlc::xor_< mlc::is_found<prop>, \
mlc::is_found<type> >::ensure(); \
@@ -206,7 +201,7 @@
prop, \
typename mlc::if_< mlc::is_ok<type>, \
type, \
- mlc::internal::not_ok \
+ mlc::not_ok \
> ::ret \
> ::ret ret; \
}; \
@@ -220,12 +215,12 @@
# define mlc_type_of_(Namespace, Category, FromType, Alias) \
Namespace::internal::f_get_type<Category, \
FromType, \
- Namespace::internal::typedef_::Alias##_type>::ret
+ Namespace::typedef_::Alias##_type>::ret
# define mlc_type_2_of_(Namespace, Category, FromType,_2, Alias) \
Namespace::internal::f_get_type<Category, \
FromType,_2, \
- Namespace::internal::typedef_::Alias##_type>::ret
+ Namespace::typedef_::Alias##_type>::ret
# define mlc_type_of(Namespace, Category, FromType, Alias) \
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix mlc::is_ok definition.
* mlc/cmp.hh (mlc::is_ok): Add missing template declarator.
cmp.hh | 1 +
1 file changed, 1 insertion(+)
Index: mlc/cmp.hh
--- mlc/cmp.hh (revision 401)
+++ mlc/cmp.hh (working copy)
@@ -106,6 +106,7 @@
/// Check whether a type is a sound (supposedly before using it).
+ template <typename T>
struct is_ok : public ands_< neq_<T, not_found>,
neq_<T, not_ok>,
neq_<T, undefined > >
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add tests for mlc_is_a, mlc_if and mlc_typedef.
* tests/is_a.cc, tests/if.cc, tests/typedef.cc: New tests.
if.cc | 17 +++++++++++++++++
is_a.cc | 14 ++++++++++++++
typedef.cc | 17 +++++++++++++++++
3 files changed, 48 insertions(+)
Index: tests/is_a.cc
--- tests/is_a.cc (revision 0)
+++ tests/is_a.cc (revision 0)
@@ -0,0 +1,14 @@
+#include <mlc/is_a.hh>
+
+struct A {};
+struct B : public A {};
+
+template <class T> struct C {};
+template <class T> struct D : public C<T> {};
+
+int
+main ()
+{
+ mlc_is_a_(B, A)::ensure();
+ mlc_is_a_(D<int>, C<int>)::ensure();
+}
Index: tests/if.cc
--- tests/if.cc (revision 0)
+++ tests/if.cc (revision 0)
@@ -0,0 +1,17 @@
+#include <mlc/if.hh>
+#include <mlc/cmp.hh>
+
+struct alpha;
+struct beta;
+struct gamma;
+struct delta;
+
+int
+main()
+{
+ typedef mlc_if_(mlc::true_, alpha, beta) x;
+ mlc_eq(x, alpha)::ensure();
+
+ typedef mlc_if_(mlc::false_, gamma, delta) y;
+ mlc_eq(y, delta)::ensure();
+}
Index: tests/typedef.cc
--- tests/typedef.cc (revision 0)
+++ tests/typedef.cc (revision 0)
@@ -0,0 +1,17 @@
+#include <mlc/typedef.hh>
+#include <mlc/cmp.hh>
+
+struct foo
+{
+ typedef int good_type;
+};
+
+mlc_decl_typedef(good_type);
+mlc_decl_typedef(bad_type);
+
+int
+main ()
+{
+ mlc_eq(mlc_typedef_(foo, good_type), foo::good_type)::ensure();
+ mlc_eq(mlc_typedef_(foo, bad_type), mlc::not_found)::ensure();
+}
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add TODO.
* TODO: New.
TODO | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
Index: TODO
--- TODO (revision 0)
+++ TODO (revision 0)
@@ -0,0 +1,27 @@
+See also the TODO in oln-proto-1.0 and oln-proto-stl-style
+
+* Metalic
+
+** Modules
+Split Metalic into several modules:
+
+ mlc : core Metalic tools
+ stc : static inheritance
+ xtd : meta-functions and operator traits (for built-in types)
+ dyn : static-dynamic bridge (work of Damien Thivolle and Nicolas
+ Pouillard)
+
+** Static inheritance
+
+*** mlc/properties -- Roland
+
+
+* Olena
+
+
+* Integre
+
+
+Local Variables:
+mode: outline
+End:
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add some documentation and types to Metalic.
* mlc/cmp.hh: More documentation.
(is_found, is_not_found, is_ok): New.
* mlc/implies.hh, mlc/is_a.hh: Fix Doxygen comment.
* mlc/flags.hh: More documentation.
(dummy, locked): New.
From Thierry Géraud.
* mlc/value.hh: Remove dead code.
cmp.hh | 35 ++++++++++++--
flags.hh | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++----------
implies.hh | 4 -
is_a.hh | 4 -
value.hh | 19 -------
5 files changed, 162 insertions(+), 49 deletions(-)
Index: mlc/implies.hh
--- mlc/implies.hh (revision 398)
+++ mlc/implies.hh (working copy)
@@ -31,9 +31,9 @@
# include <mlc/bool.hh>
-/*! \macro mlc_implies(Left_BExpr, Right_BExpr)
+/*! \def mlc_implies(Left_BExpr, Right_BExpr)
**
-** Macro correponding to mlc::implies_<L, R>, for use in a template
+** Macro corresponding to mlc::implies_<L, R>, for use in a template
** context.
**
** \see mlc::implies_<L, R>
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 398)
+++ mlc/is_a.hh (working copy)
@@ -205,7 +205,7 @@
-/*! \macro mlc_is_a(T, U)
+/*! \def mlc_is_a(T, U)
**
** Macro that answers if T is an U. T should be a type and U can have
** different forms: class, template class, etc. The result is a
@@ -240,7 +240,7 @@
mlc::wrap_<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > >
-/*! \macro mlc_is_a_(T, U)
+/*! \def mlc_is_a_(T, U)
**
** Macro equivalent as mlc_is_a(T, U) for use in a non templated
** context. The result is a Boolean expression type.
Index: mlc/flags.hh
--- mlc/flags.hh (revision 398)
+++ mlc/flags.hh (working copy)
@@ -38,9 +38,15 @@
/*! \class mlc::abstract::flag
**
- ** Abstract base class for types that are only flags.
+ ** Abstract base class for types that are flags. A flag type
+ ** expresses a particular property translated by the name of the
+ ** type. For instance, mlc::undefined is a flag type which
+ ** means "declared but not defined".
**
- ** Example: mlc::undefined is a mlc::abstract::flag.
+ ** Flag types have no interface; they only serve as types.
+ **
+ ** The flags provided in mlc are: dummy, locked, none, not_found,
+ ** undefined, and unknown.
*/
struct flag : public type {};
@@ -48,37 +54,91 @@
} // end of namespace mlc::abstract
- /*! \class mlc::undefined
+ /*! \class mlc::dummy
**
- ** Flag class to state that a type is undefined, that is, declared
- ** but not defined.
+ ** Flag class to value a type when one knows that this value does
+ ** not matter and will not be used.
**
- ** Sample use: you want to define a trait to get the signed version
- ** of a type T. For that, you write:
+ ** The dummy type appears typically in some part of meta-program
+ ** that are ignored. In mlc_typedef_onlyif, for instance, dummy is
+ ** returned when the guard value is false. When defining a
+ ** pattern matching meta-program, if a clause is not a match, the
+ ** returned type for this clause is evaluated into dummy.
+ */
+ struct dummy : public abstract::flag {};
+
+
+ /*! \class mlc::locked
+ **
+ ** Flag class whose purpose is to state and ensure that a type
+ ** should not be re-defined (or specialized) by the client.
+ **
+ ** Let us consider a type that should not be re-defined or
+ ** specialized by the client. Such a type is defined having
+ ** mlc::locked as base class. Inserting the static check
+ ** mlc_is_a(type, locked) then ensures that this type is untouched.
+ **
+ ** Sample use: First a type (set_foo) is declared for the user to
+ ** specialize it:
+ **
+ ** template <typename T> struct set_foo;
+ **
+ ** and the access to this specialization (handled by the type
+ ** get_foo), for use in a meta-program, is written once for all.
+ ** The access code should not be re-defined by the client so it is
+ ** tagged as locked:
**
** template <typename T>
- ** struct signed_type_of
- ** {
- ** typedef mlc::undefined ret;
+ ** struct get_foo : public mlc::locked,
+ ** public set_foo<T> {
+ ** using set_foo<T>::ret;
** };
**
- ** which means that the return type (ret) is not defined by default.
- ** Put differently, this trait is just declared. So far, the
- ** type "signed_type_of<unsigned short>::ret" is "mlc::undefined".
- **
- ** Other flags are mlc::unknown, mlc::none, and mlc::not_found.
+ ** The meta-program that reads the value of get_foo<T>::ret also
+ ** checks that get_foo<T> derives from mlc::locked. That thus
+ ** ensures that the client has not confuse set_foo with get_foo.
*/
- struct undefined : public abstract::flag {};
+ struct locked : public abstract::flag {};
- struct unknown : public abstract::flag {};
+ /*! \class mlc::none
+ **
+ ** Flag class to state that there is no type corresponding to a
+ ** request.
+ **
+ ** Sample use 1: In the context of a variadic parameter list, none
+ ** is the default value for every parameter after the first one.
+ **
+ ** With:
+ ** template <typename P1,
+ ** typename P2 = none,
+ ** typename P3 = none>
+ ** struct foo {
+ ** typedef P1 param1;
+ ** typedef P2 param2;
+ ** typedef P3 param3;
+ ** };
+ **
+ ** instantiated into foo<int, float>, we thus have param3 set to
+ ** none.
+ **
+ ** Sample use 2: The type none can be used as a trait value. For
+ ** instance:
+ **
+ ** template<>
+ ** struct super_type_of <int> {
+ ** typedef none ret;
+ ** };
+ */
struct none : public abstract::flag {};
/*! \class mlc::not_found
**
- ** Flag class to state that a type is not found (for use in the
- ** context of trying to retrieve a type).
+ ** Flag class to state that a type is not found. This class is for
+ ** use in the context of trying to retrieve a type. More precisely,
+ ** this flag type should only appear as a return of a piece of
+ ** meta-program.
**
** Design issue: this flag is used in some meta-code to handle the
** case of an "absent" typedef. For instance it is used in the
@@ -86,14 +146,59 @@
** mlc_typedef(std::vector<int>, value_type) is int, whereas
** mlc_typedef(std::vector<int>, walue_type) is mlc::not_found.
**
- ** Other flags are mlc::undefined, mlc::unknown, and mlc::none.
- **
** \see mlc_typedef
*/
struct not_found : public abstract::flag {};
- // FIXME: add corresponding is_* types
+ /*! \class mlc::undefined
+ **
+ ** Flag class to state that a type is undefined, that is, declared
+ ** but not defined.
+ **
+ ** Sample use: When you want to define a trait to get the signed
+ ** version of a type T, you write:
+ **
+ ** template <typename T>
+ ** struct signed_type_of
+ ** {
+ ** typedef mlc::undefined ret;
+ ** };
+ **
+ ** meaning that the return type (ret) is not defined by default.
+ ** Put differently, this trait is just declared. So far, the trait
+ ** value signed_type_of<unsigned short>::ret is mlc::undefined. If
+ ** it happens that this trait value is not specialized in some
+ ** following code, this value thus remains mlc::undefined, which
+ ** clearly denotes an error.
+ **
+ ** \see mlc::abstract::flag.
+ */
+ struct undefined : public abstract::flag {};
+
+
+ /*! \class mlc::unknown
+ **
+ ** Flag class to state that a result is yet unknown.
+ **
+ ** Sample use: This flag can be used in a meta-program to express
+ ** that a sub-program fails to give the expected result. For
+ ** instance in:
+ **
+ ** template <class T>
+ ** struct foo {
+ ** typedef sub_program_1 ret1;
+ ** typedef sub_program_2 ret2;
+ ** typedef typename if_< neq_<ret1, unknown>,
+ ** ret1,
+ ** ret2 >::ret ret;
+ ** };
+ */
+ struct unknown : public abstract::flag {};
+
+
+ // FIXME: Doc.
+ struct not_ok : public abstract::flag {};
} // end of namespace mlc
Index: mlc/value.hh
--- mlc/value.hh (revision 398)
+++ mlc/value.hh (working copy)
@@ -164,23 +164,4 @@
# include <mlc/bool.hh>
-// FIXME: the following code causes inclusion recursion...
-
-// # include <mlc/is_a.hh>
-
-// namespace mlc {
-
-// template <typename T>
-// struct is_value : public mlc_is_a(T, mlc::abstract::value)
-// {
-// };
-
-// template <typename T>
-// struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)>
-// {
-// };
-
-// } // end of namespace mlc
-
-
#endif // ! METALIC_VALUE_HH
Index: mlc/cmp.hh
--- mlc/cmp.hh (revision 398)
+++ mlc/cmp.hh (working copy)
@@ -39,13 +39,14 @@
namespace mlc
{
- // FIXME: code moved from the end of value.hh
+ /// Check whether \a T is a mlc::abstract::value.
template <typename T>
struct is_value : public mlc_is_a(T, mlc::abstract::value)
{
};
+ /// Check whether \a T is not a mlc::abstract::value.
template <typename T>
struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)>
{
@@ -54,7 +55,7 @@
/// Equality test between a couple of types.
-
+ /// \{
template <typename T1, typename T2>
struct eq_ : private ensure_list_< is_not_value<T1>,
is_not_value<T2> >,
@@ -67,10 +68,10 @@
public true_
{
};
-
+ /// \}
/// Inequality test between a couple of types.
-
+ /// \{
template <typename T1, typename T2>
struct neq_ : private ensure_list_< is_not_value<T1>,
is_not_value<T2> >,
@@ -83,7 +84,33 @@
public false_
{
};
+ /// \}
+
+
+ /*--------------------------------------.
+ | Syntactic sugar for flag comparison. |
+ `--------------------------------------*/
+
+ /// Shortcuts for comparison with mlc::not_found.
+ /// \{
+ template <typename T>
+ struct is_found : public neq_<T, not_found>
+ {
+ };
+
+ template <typename T>
+ struct is_not_found : public neq_<T, not_found>
+ {
+ };
+ /// \}
+
+ /// Check whether a type is a sound (supposedly before using it).
+ struct is_ok : public ands_< neq_<T, not_found>,
+ neq_<T, not_ok>,
+ neq_<T, undefined > >
+ {
+ };
} // end of namespace mlc
1
0