https://svn.lrde.epita.fr/svn/oln/trunk/static
This is currently a workaround inside Static, but it would be better
to let Metalic deal with this instead.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Allow the use of Metalic values as virtual types.
* stc/properties.hh (mlc::eqv, mlc::neqv): New (workaround)
classes.
(mlc_eqv, mlc_neqv): New macros.
(rec_get_vtype, rec_get_ext_vtype): Use them, to allow the use of
Metalic values as virtual types.
* tests/properties.cc: Ensure Metalic values can be valid
virtual types.
stc/properties.hh | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----
tests/properties.cc | 18 +++++++++++++--
2 files changed, 70 insertions(+), 7 deletions(-)
Index: tests/properties.cc
--- tests/properties.cc (revision 468)
+++ tests/properties.cc (working copy)
@@ -28,6 +28,7 @@
#include <stc/properties.hh>
#include <mlc/cmp.hh>
#include <mlc/assert.hh>
+#include <mlc/int.hh>
// This test focuses on the virtual types system, so the exact type of
// classes is not propagated here (stc::any is not used).
@@ -82,8 +83,13 @@
template<>
struct vtypes<category::my_cat, my::A>
{
+ // A native type.
typedef int foo_type;
- typedef float bar_type;
+ // A Metalic value, used here is to ensure that
+ // mlc::abstract::values are accepted as virtual types, as well as
+ // any other type).
+ typedef mlc::int_<42> bar_type;
+ // An undefined type.
typedef mlc::undefined baz_type;
};
@@ -212,10 +218,16 @@
{
// Check types associated to A.
mlc::assert_<mlc_eq(my::A::foo_type, int)>::check();
- mlc::assert_<mlc_eq(my::A::bar_type, float)>::check();
+ /* FIXME: Note that we use mlc_eqv, not mlc_eq, since the latter
+ doesn't accept Metalic values. Try to get rid of this
+ limitation. */
+ mlc::assert_<mlc_eqv(my::A::bar_type, mlc::int_<42>)>::check();
// Check types associated to B.
- mlc::assert_<mlc_neq(my::B::bar_type, my::A::bar_type)>::check();
+ /* FIXME: Note that we use mlc_neqv, not mlc_neq, since the latter
+ doesn't accept Metalic values. Try to get rid of this
+ limitation. */
+ mlc::assert_<mlc_neqv(my::B::bar_type, my::A::bar_type)>::check();
mlc::assert_<mlc_eq(my::B::baz_type, char)>::check();
mlc::assert_<mlc_eq(my::B::quux_type, long)>::check();
mlc::assert_<mlc_eq(my::B::yin_type, unsigned long)>::check();
Index: stc/properties.hh
--- stc/properties.hh (revision 468)
+++ stc/properties.hh (working copy)
@@ -42,6 +42,55 @@
# include <mlc/is_a.hh>
+/*----------------------.
+| Metalic workarounds. |
+`----------------------*/
+
+/// Shortcuts.
+/// \{
+# define mlc_eqv( T1, T2) mlc::eqv_ <T1, T2>
+# define mlc_neqv(T1, T2) mlc::neqv_<T1, T2>
+/// \}
+
+namespace mlc
+{
+ /* FIXME: This really is a work around Metalic's limitations
+ regarding the operands of its logic operators than cannot be
+ subtypes of mlc::abstract::value. This limitations breaks Static
+ when a virtual type *is* a Metalic value! Hence the introduction
+ of this more laxist version of mlc_neq. */
+
+ /// Equality test between a couple of types, also accepting Metalic
+ /// values (i.e., subtypes of mlc::abstract::value).
+ /// \{
+ template <typename T1, typename T2>
+ struct eqv_ : public bexpr_<false>
+ {
+ };
+
+ template <typename T>
+ struct eqv_ <T, T> : public bexpr_<true>
+ {
+ };
+ /// \}
+
+ /// Inequality test between a couple of types, also accepting Metalic
+ /// values (i.e., subtypes of mlc::abstract::value).
+ /// \{
+ template <typename T1, typename T2>
+ struct neqv_ : public bexpr_<true>
+ {
+ };
+
+ template <typename T>
+ struct neqv_ <T, T> : public bexpr_<false>
+ {
+ };
+ /// \}
+
+}
+
+
/*------------.
| Equipment. |
`------------*/
@@ -159,7 +208,7 @@
\
typedef typename \
mlc::if_< \
- mlc::neq_< type, mlc::not_found >, \
+ mlc::neqv_< type, mlc::not_found >, \
/* then */ \
/* return it */ \
/* (the typedef has been found in the vtypes */ \
@@ -169,7 +218,7 @@
/* check if the vtype of the `super' of FROM_TYPE */ \
/* has the typedef */ \
typename \
- mlc::if_< mlc::neq_< typename rec_get_vtype< category, \
+ mlc::if_< mlc::neqv_< typename rec_get_vtype<category, \
super, \
typedef_type >::ret, \
mlc::not_found >, \
@@ -227,7 +276,7 @@
\
typedef typename \
mlc::if_< \
- mlc::neq_< type, mlc::not_found >, \
+ mlc::neqv_< type, mlc::not_found >, \
/* then */ \
/* return it */ \
/* (the typedef has been found in the vtypes */ \
@@ -237,7 +286,7 @@
/* check if the vtype of the `super' of FROM_TYPE */ \
/* has the typedef */ \
typename \
- mlc::if_< mlc::neq_< typename rec_get_ext_vtype< category, \
+ mlc::if_< mlc::neqv_< typename rec_get_ext_vtype<category, \
super, \
typedef_type >::ret, \
mlc::not_found >, \
@@ -420,6 +469,8 @@
# define stc_pseudosuper_(T) \
set_pseudosuper_type<T>::ret
+// FIXME: s/stc_typeof/stc_type_of/.
+
/// Get the property \a Typedef from \a FromType (version to be used
/// inside a template).
#define stc_typeof(Category, FromType, Typedef) \