Commit 119255ef authored by Roland Levillain's avatar Roland Levillain
Browse files

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.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@414 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 0982e4e7
2006-02-20 Roland Levillain <roland@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.
2006-02-16 Roland Levillain <roland@lrde.epita.fr> 2006-02-16 Roland Levillain <roland@lrde.epita.fr>
Autoconfiscate the project and automate the tests. Autoconfiscate the project and automate the tests.
......
This diff is collapsed.
...@@ -14,22 +14,23 @@ ...@@ -14,22 +14,23 @@
namespace my namespace my
{ {
/*----------------------.
| Namespace equipment. |
`----------------------*/
mlc_equip_namespace_with_properties();
/*-----------. /*-----------.
| Typedefs. | | Typedefs. |
`-----------*/ `-----------*/
mlc_decl_typedef(ptr_type);
mlc_decl_typedef(foo_type); mlc_decl_typedef(foo_type);
mlc_decl_typedef(bar_type); mlc_decl_typedef(bar_type);
mlc_decl_typedef(baz_type); mlc_decl_typedef(baz_type);
mlc_decl_typedef(quux_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 @@ namespace my ...@@ -43,7 +44,6 @@ namespace my
} }
/*----. /*----.
| A. | | A. |
`----*/ `----*/
...@@ -51,10 +51,9 @@ namespace my ...@@ -51,10 +51,9 @@ namespace my
// Forward declaration. // Forward declaration.
struct A; struct A;
// FIXME: Rename as set_types<> when mlc/properties.hh is updated. /// Types associated to my::A.
// Associated types.
template<> template<>
struct set_types<category::my_cat, my::A> struct vtypes<category::my_cat, my::A>
{ {
typedef int foo_type; typedef int foo_type;
typedef float bar_type; typedef float bar_type;
...@@ -80,47 +79,93 @@ namespace my ...@@ -80,47 +79,93 @@ namespace my
// Warning, this sugar might me remove from properties.hh. // Warning, this sugar might me remove from properties.hh.
mlc_set_super(B, A); mlc_set_super(B, A);
/// \brief Redefined types associated to \a B. /// Types associated to my::B.
///
/// Keeping the inheritance is absolutely capital here (i.e., when
/// you redefine an associated type with redefine_types).
template<> template<>
struct redefine_types<category::my_cat, B> : struct vtypes<category::my_cat, B>
mlc_super_types_(category::my_cat, B)
{ {
// (foo is left untouched.)
// A type redefined here. // A type redefined here.
typedef double bar_type; typedef double bar_type;
// A type defined here (but declared abstract in the super class). // A type defined here (but declared abstract in the super class).
typedef char baz_type; 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<> 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 unsigned long ret;
typedef long quux_type;
}; };
struct B : public mlc_super(B) struct B : public mlc_super_(B)
{ {
// Aliases. // Aliases.
typedef my_type_of_(B, foo) foo_type; typedef my_type_of_(B, foo) foo_type;
typedef my_type_of_(B, bar) bar_type; typedef my_type_of_(B, bar) bar_type;
typedef my_type_of_(B, baz) baz_type; typedef my_type_of_(B, baz) baz_type;
typedef my_type_of_(B, quux) quux_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 int
main() main()
{ {
// Check associated types. // Check types associated to A.
mlc_eq(my::A::foo_type, int)::ensure (); mlc_eq(my::A::foo_type, int)::ensure ();
mlc_eq(my::A::bar_type, float)::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_neq(my::B::bar_type, my::A::bar_type)::ensure ();
mlc_eq(my::B::baz_type, char)::ensure (); mlc_eq(my::B::baz_type, char)::ensure ();
mlc_eq(my::B::quux_type, long)::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 ();
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment