https://svn.lrde.epita.fr/svn/oln/trunk/static
This patch is followed by another one where packed_vtypes is removed
from oln/core/abstract/image.hh, since stc/properties.hh defines it now.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a facility for virtual types packing.
* stc/properties.hh (packed_vtypes): New packing structure, to
be specialized by the user. When properly defined, this structure
can be used to check if all the virtual types of a class are sound.
* tests/properties.cc (my_type_of): New macro.
Define a packed_vtypes structure for the top-most class (my::A) and
check these virtual types in my::A's subclasses.
stc/properties.hh | 7 +++++++
tests/properties.cc | 47 +++++++++++++++++++++++++++++++++++++++++------
2 files changed, 48 insertions, 6 deletions
Index: tests/properties.cc
--- tests/properties.cc (revision 466)
+++ tests/properties.cc (working copy)
@@ -29,13 +29,13 @@
#include <mlc/cmp.hh>
#include <mlc/assert.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 stc/properties.hh so as to make a list of the features to be
-// checked.
+// This test focuses on the virtual types system, so the exact type of
+// classes is not propagated here (stc::any is not used).
+
+// Helper macros.
+#define my_type_of(FromType, Typedef) \
+ typename my_type_of_(FromType, Typedef)
-// Helper macro.
#define my_type_of_(FromType, Typedef) \
stc_typeof_(my::category::my_cat, FromType, Typedef)
@@ -87,12 +87,35 @@
typedef mlc::undefined baz_type;
};
+ /// Packing of virtual types of any A class.
+ template <typename T>
+ struct packed_vtypes <category::my_cat, T>
+ {
+ typedef my_type_of(T, foo) foo_type;
+ typedef my_type_of(T, bar) bar_type;
+ typedef my_type_of(T, baz) baz_type;
+
+ static void ensure()
+ {
+ mlc::assert_< mlc_is_ok(foo_type) >::check();
+ mlc::assert_< mlc_is_ok(bar_type) >::check();
+ mlc::assert_< mlc_is_ok(baz_type) >::check();
+ }
+ };
+
struct 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;
+
+ ~A()
+ {
+ // packed_vtypes<category::my, A> is not checked here, since A's
+ // baz_type virtual type is undefined.
+ }
+
};
@@ -135,6 +158,12 @@
typedef my_type_of_(B, baz) baz_type;
typedef my_type_of_(B, quux) quux_type;
typedef my_type_of_(B, yin) yin_type;
+
+ // Check B's vtypes.
+ ~B()
+ {
+ packed_vtypes<category::my_cat, B>::ensure();
+ }
};
@@ -167,6 +196,12 @@
typedef my_type_of_(C, foo) foo_type;
typedef my_type_of_(C, quux) quux_type;
typedef my_type_of_(C, zorg) zorg_type;
+
+ // Check C's vtypes.
+ ~C()
+ {
+ packed_vtypes<category::my_cat, C>::ensure();
+ }
};
}
Index: stc/properties.hh
--- stc/properties.hh (revision 466)
+++ stc/properties.hh (working copy)
@@ -116,6 +116,13 @@
{ \
}; \
\
+ /** Optional packing structure, to be specialized by the user. */ \
+ /** See tests/properties.hh for an example of use. */ \
+ template <typename category, typename from_type> \
+ struct packed_vtypes \
+ { \
+ }; \
+ \
\
/* -------------------- */ \
/* Internal machinery. */ \