https://svn.lrde.epita.fr/svn/oln/trunk/static
The support for multiple inheritance in SCOOP is not complete: the
mechanism for retrieving virtual types queries only the first base
class, not the (possible) other ones.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Allow multiple super classes in SCOOP's static hierarchies.
* stc/valist_aggregator.hh: New.
* stc/vtypes.hh: Include it.
(ERROR::PARAMETER_OF_get_super_types_helper_IS_NOT_A_VALID_VALIST):
New struct.
(set_super_type): Inherit from mlc::undefined by default.
(internal::maybe_super_type, get_supers_list)
(internal::get_super_types_helper, get_super_types)
(rec_get_vtype): s/stc_super/stc_get_super/.
s/stc_pseudosuper/stc_get_pseudosuper/.
(stc_set_super): Remove previous definition of this macro, and
make it a shortcut for...
(stc_set_nth_super): ...this one (new).
(stc_get_supers, stc_get_nth_super_, stc_get_nth_super_)
(stc_get_super_, stc_get_super_): New macros.
(stc_super, stc_super_): Remove macros.
(stc_pseudosuper, stc_pseudosuper_): Rename macros as...
(stc_get_pseudosuper, stc_get_pseudosuper_): ...these.
* tests/super.cc, tests/multiple-supers.cc: New tests.
* tests/vtypes.cc: s/stc_get_supers_/stc_get_supers/g.
* stc/Makefile.am (nobase_stc_HEADERS): Add exact.hh
and valist_aggregator.hh.
* tests/Makefile.am (check_PROGRAMS): Add multiple-supers, super.
(multiple_supers_SOURCES, super_SOURCES): New.
stc/Makefile.am | 2
stc/valist_aggregator.hh | 138 ++++++++++++++++++++++++++++++++
stc/vtypes.hh | 199 ++++++++++++++++++++++++++++++++++++++++-------
tests/Makefile.am | 4
tests/multiple-supers.cc | 109 +++++++++++++++++++++++++
tests/super.cc | 97 ++++++++++++++++++++++
tests/vtypes.cc | 4
7 files changed, 524 insertions(+), 29 deletions(-)
Index: tests/super.cc
--- tests/super.cc (revision 0)
+++ tests/super.cc (revision 0)
@@ -0,0 +1,97 @@
+// Copyright (C) 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, 51 Franklin Street, Fifth Floor,
+// 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.
+
+// Check Static's super relationship.
+
+#include <stc/vtypes.hh>
+#include <mlc/is_a.hh>
+#include <mlc/assert.hh>
+
+
+namespace my
+{
+
+ /*----------------------.
+ | Namespace equipment. |
+ `----------------------*/
+
+ stc_equip_namespace_with_vtypes();
+
+
+ /*----.
+ | A. |
+ `----*/
+
+ struct A
+ {
+ };
+
+
+ /*------------.
+ | B ---|> A. |
+ `------------*/
+
+ // Forward declaration.
+ struct B;
+
+ // Warning, this sugar might be removed in the future.
+ stc_set_super(B, A);
+
+ struct B : public stc_get_supers(B)
+ {
+ };
+
+
+ /*---.
+ | C. |
+ `---*/
+
+ // Forward declaration.
+ struct C;
+
+ /* C doesn't derive from B, but we want its vtypes to ``inherit''
+ from B's vtypes. Note that there are actually no vtypes in this
+ simple test, but it doesn't matter: we are only checking the
+ super relationship here. */
+
+ // Warning, this sugar might be removed in the future.
+ /// Link to B (``pseudo'' inheritance).
+ stc_set_pseudosuper(C, B);
+
+ struct C // no inheritance
+ {
+ };
+
+} // end of namespace my
+
+
+int
+main()
+{
+ mlc::assert_<mlc_is_a_(my::B, my::A)>::check();
+ mlc::assert_<mlc_is_not_a_(my::C, my::A)>::check();
+}
Property changes on: tests/exact.cc
___________________________________________________________________
Name: svn:executable
- *
Index: tests/Makefile.am
--- tests/Makefile.am (revision 492)
+++ tests/Makefile.am (working copy)
@@ -11,11 +11,15 @@
any \
entry \
exact \
+ multiple-supers \
+ super \
vtypes
any_SOURCES = any.cc
entry_SOURCES = entry.cc
exact_SOURCES = exact.cc
+multiple_supers_SOURCES = multiple-supers.cc
+super_SOURCES = super.cc
vtypes_SOURCES = vtypes.cc
TESTS = $(check_PROGRAMS)
Index: tests/vtypes.cc
--- tests/vtypes.cc (revision 492)
+++ tests/vtypes.cc (working copy)
@@ -156,7 +156,7 @@
typedef unsigned long ret;
};
- struct B : public stc_super_(B)
+ struct B : public stc_get_supers(B)
{
// Aliases.
typedef my_type_of_(B, foo) foo_type;
@@ -210,7 +210,7 @@
}
};
-}
+} // end of namespace my
int
Index: tests/multiple-supers.cc
--- tests/multiple-supers.cc (revision 0)
+++ tests/multiple-supers.cc (revision 0)
@@ -0,0 +1,109 @@
+// Copyright (C) 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, 51 Franklin Street, Fifth Floor,
+// 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.
+
+// Check Static's multiple super relationship.
+
+#include <stc/vtypes.hh>
+#include <mlc/is_a.hh>
+#include <mlc/assert.hh>
+
+
+namespace my
+{
+
+ /*----------------------.
+ | Namespace equipment. |
+ `----------------------*/
+
+ stc_equip_namespace_with_vtypes();
+
+
+ /*--.
+ | A |
+ `--*/
+
+ struct A
+ {
+ };
+
+
+ /*--.
+ | B |
+ `--*/
+
+ struct B
+ {
+ };
+
+
+ /*--.
+ | A |
+ | ^ |
+ | | |
+ | C |
+ `--*/
+
+ // Forward declaration.
+ struct C;
+
+ // Warning, this sugar might be removed in the future.
+ stc_set_super(C, A);
+
+ struct C : public stc_get_supers(C)
+ {
+ };
+
+
+ /*------.
+ | A B |
+ | ^ ^ |
+ | \ / |
+ | D |
+ `------*/
+
+ // Forward declaration.
+ struct D;
+
+ // Warning, this sugar might be removed in the future.
+ stc_set_nth_super(D, 1, A);
+ stc_set_nth_super(D, 2, B);
+
+ struct D : public stc_get_supers(D)
+ {
+ };
+
+} // end of namespace my
+
+
+int
+main()
+{
+ mlc::assert_<mlc_is_a_(my::C, my::A)>::check();
+
+ mlc::assert_<mlc_is_a_(my::D, my::A)>::check();
+ mlc::assert_<mlc_is_a_(my::D, my::B)>::check();
+}
Property changes on: stc/exact.hh
___________________________________________________________________
Name: svn:executable
- *
Index: stc/valist_aggregator.hh
--- stc/valist_aggregator.hh (revision 0)
+++ stc/valist_aggregator.hh (revision 0)
@@ -0,0 +1,138 @@
+// Copyright (C) 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, 51 Franklin Street, Fifth Floor,
+// 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.
+
+/// \file stc/valist_aggregator.hh
+/// \brief Super class aggregation mechanism.
+///
+/// Converts a mlc::valist_ into a class inheriting from all the
+/// elements of the list.
+
+#ifndef STATIC_VALIST_AGGREGATOR_HH
+# define STATIC_VALIST_AGGREGATOR_HH
+
+// FIXME: To be moved in Metalic?
+
+// FIXME: Propose a version where inheritance is virtual (with an
+// optional fine-grained version, where `virtual' presence can be
+// choose individually for each element?)
+
+#include <mlc/abort.hh>
+#include <mlc/valist.hh>
+
+namespace stc
+{
+ namespace ERROR
+ {
+
+ struct PARAMETER_OF_internal_valist_aggregator_OUT_OF_BOUNDS;
+
+ } // end of namespace stc::ERROR
+
+
+ // There is a lot a redundant code here; the Boost Preprocessor
+ // Library would be a nice solution, but we don't want to depend on
+ // third-party libraries.
+
+
+ /// Defaut version: abort.
+ template <typename super_list>
+ struct valist_aggregator :
+ private mlc::abort_<
+ super_list,
+ stc::ERROR::PARAMETER_OF_internal_valist_aggregator_OUT_OF_BOUNDS
+ >
+ {
+ };
+
+ /// Version for 2 super classes.
+ template <typename E1, typename E2>
+ struct valist_aggregator< mlc::valist_ <E1,E2> > :
+ public E1, public E2
+ {
+ };
+
+ /// Version for 3 super classes.
+ template <typename E1, typename E2, typename E3>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3 > > :
+ public E1, public E2, public E3
+ {
+ };
+
+ /// Version for 4 super classes.
+ template <typename E1, typename E2, typename E3, typename E4>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3,E4> > :
+ public E1, public E2, public E3, public E4
+ {
+ };
+
+ /// Version for 5 super classes.
+ template <typename E1, typename E2, typename E3, typename E4, typename E5>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3,E4,E5> > :
+ public E1, public E2, public E3, public E4, public E5
+ {
+ };
+
+ /// Version for 6 super classes.
+ template <typename E1, typename E2, typename E3, typename E4, typename E5,
+ typename E6>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3,E4,E5,E6> > :
+ public E1, public E2, public E3, public E4, public E5,
+ public E6
+ {
+ };
+
+ /// Version for 7 super classes.
+ template <typename E1, typename E2, typename E3, typename E4, typename E5,
+ typename E6, typename E7>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3,E4,E5,E6,E7> > :
+ public E1, public E2, public E3, public E4, public E5,
+ public E6, public E7
+ {
+ };
+
+ /// Version for 8 super classes.
+ template <typename E1, typename E2, typename E3, typename E4, typename E5,
+ typename E6, typename E7, typename E8>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3,E4,E5,E6,E7,E8> > :
+ public E1, public E2, public E3, public E4, public E5,
+ public E6, public E7, public E8
+ {
+ };
+
+ /// Version for 9 super classes.
+ template <typename E1, typename E2, typename E3, typename E4, typename E5,
+ typename E6, typename E7, typename E8, typename E9>
+ struct valist_aggregator< mlc::valist_ <E1,E2,E3,E4,E5,E6,E7,E8,E9> > :
+ public E1, public E2, public E3, public E4, public E5,
+ public E6, public E7, public E8, public E9
+ {
+ };
+ /// \}
+
+} // end of namespace stc
+
+#endif // ! STATIC_VALIST_AGGREGATOR_HH
Index: stc/vtypes.hh
--- stc/vtypes.hh (revision 492)
+++ stc/vtypes.hh (working copy)
@@ -36,11 +36,20 @@
# include <mlc/flags.hh>
# include <mlc/typedef.hh>
# include <mlc/ret.hh>
+
+# include <mlc/assert.hh>
+# include <mlc/abort.hh>
+
# include <mlc/bool.hh>
+# include <mlc/int.hh>
+
# include <mlc/cmp.hh>
# include <mlc/if.hh>
# include <mlc/is_a.hh>
-# include <mlc/assert.hh>
+
+# include <mlc/comma.hh>
+# include <mlc/valist.hh>
+# include <stc/valist_aggregator.hh>
/*-----------------.
@@ -52,8 +61,12 @@
/// Error messages raised by static assertions.
namespace ERROR
{
+
struct FIRST_PARAMETER_OF_rec_get_vtype_SHOULD_BE_A_TAG;
+ struct PARAMETER_OF_get_super_types_helper_IS_NOT_A_VALID_VALIST;
+
} // end of namespace stc::ERROR
+
} // end of namespace stc
@@ -66,7 +79,11 @@
# define stc_internal_get_typedef(Type, TypedefName) \
typename TypedefName::template from_< Type >::ret
-// FIXME: Add support for hierarchies with several super classes.
+
+// FIXME: Complete support for hierarchies with several super classes.
+
+// FIXME: Could we extract some classes from this gigantic macro?
+
# define stc_equip_namespace_with_vtypes() \
\
/* ----------------------- */ \
@@ -81,17 +98,103 @@
/* Inheritance. */ \
/* ------------- */ \
\
- template <typename type> \
- struct set_super_type \
+ /* Set super classes. */ \
+ \
+ template<typename type, unsigned N = 1> \
+ struct set_super_type : public mlc::undefined \
{ \
typedef mlc::none ret; \
}; \
\
\
+ /* Get supers list. */ \
+ \
+ namespace internal \
+ { \
+ template <typename type, unsigned N> \
+ struct maybe_super_type \
+ { \
+ typedef typename \
+ mlc::if_< mlc_is_a( mlc_comma_1( set_super_type<type, N> ), \
+ mlc::undefined ), \
+ mlc::internal::valist_none, \
+ mlc_ret(mlc_comma_1(set_super_type< type, N >)) >::ret \
+ ret; \
+ }; \
+ } /* end of namespace internal */ \
+ \
+ template <typename type> \
+ struct get_supers_list \
+ { \
+ /* FIXME: Factor with a macro? */ \
+ typedef typename internal::maybe_super_type<type, 1>::ret s1; \
+ typedef typename internal::maybe_super_type<type, 2>::ret s2; \
+ typedef typename internal::maybe_super_type<type, 3>::ret s3; \
+ typedef typename internal::maybe_super_type<type, 4>::ret s4; \
+ typedef typename internal::maybe_super_type<type, 5>::ret s5; \
+ typedef typename internal::maybe_super_type<type, 6>::ret s6; \
+ typedef typename internal::maybe_super_type<type, 7>::ret s7; \
+ typedef typename internal::maybe_super_type<type, 8>::ret s8; \
+ typedef typename internal::maybe_super_type<type, 9>::ret s9; \
+ \
+ typedef mlc::valist_<s1, s2, s3, s4, s5, s6, s7, s8, s9> ret; \
+ }; \
+ \
+ \
+ /* Get supers classes. */ \
+ \
+ namespace internal \
+ { \
+ \
+ /** Accessor helper. */ \
+ template<typename type> \
+ struct get_super_types_helper; \
+ \
+ /** Accessor helper: specialization for the case of a single */ \
+ /** super class. */ \
+ template<typename super> \
+ struct get_super_types_helper< mlc::valist_ <super> > \
+ { \
+ /** Return the super class directly. */ \
+ typedef super ret; \
+ }; \
+ \
+ /** Accessor helper: specializations for the case of two super */ \
+ /** classes or more. */ \
+ template <typename super1, typename super2, typename super3> \
+ struct get_super_types_helper< mlc::valist_ <super1, super2, super3> >
\
+ { \
+ /** Return an aggregate of the super classes. */ \
+ typedef stc::valist_aggregator< mlc::valist_ <super1, super2, super3> >
\
+ ret; \
+ }; \
+ \
+ /** Accessor helper: default case (abort). */ \
+ template<typename type> \
+ struct get_super_types_helper : \
+ public mlc::abort_< \
+ type, \
+ stc::ERROR::PARAMETER_OF_get_super_types_helper_IS_NOT_A_VALID_VALIST \
+ > \
+ { \
+ }; \
+ \
+ } /* end of namespace internal */ \
+ \
+ \
+ template<typename type> \
+ struct get_super_types \
+ { \
+ typedef typename get_supers_list<type>::ret supers_list; \
+ typedef typename internal::get_super_types_helper<supers_list>::ret ret; \
+ }; \
+ \
+ \
/* ------------------------ */ \
/* ``Pseudo'' inheritance. */ \
/* ------------------------ */ \
\
+ /* FIXME: Add a multiple pseudoinheritance mechanism? */ \
template <typename type> \
struct set_pseudosuper_type \
{ \
@@ -215,9 +318,9 @@
get_vtype<method, category, from_type, typedef_type>::ret type; \
\
/** Implicit parent (i.e. super), if any. */ \
- typedef stc_super(from_type) super; \
+ typedef stc_get_super(from_type) super; \
/** Pseudosuper class, if any. */ \
- typedef stc_pseudosuper(from_type) pseudosuper; \
+ typedef stc_get_pseudosuper(from_type) pseudosuper; \
\
typedef typename \
mlc::if_< \
@@ -376,17 +479,64 @@
| Macros. |
`---------*/
-/* FIXME: I don't know whether this macro will be really usable; what
+// ------------- //
+// Inheritance. //
+// ------------- //
+
+// Set.
+
+/* FIXME: I don't know whether these macros will be really usable; what
if Type is a template class? We would have to provide additional
- versions of this macro, with support for one parameter, two
+ versions of these macros, with support for one parameter, two
parameters, etc. */
/// \def Declare the immediate base class \a Super of \a Type.
-# define stc_set_super(Type, Super) \
+#define stc_set_nth_super(Type, N, Super) \
template <> \
- struct set_super_type<Type> \
+ struct set_super_type< Type, N > \
{ \
typedef Super ret; \
- }
+ };
+
+// Shortcut.
+#define stc_set_super(Type, Super) \
+ stc_set_nth_super(Type, 1, Super)
+
+
+// Get.
+
+/** \a stc_get_supers(Type) returns a class which inerits from all the
+ classes declared as super types of \a Type.
+
+ However, there is an exception when Type as single super:
+ stc_get_supers returns this super class directly, not a class
+ ineriting from it, to avoid a useless indirection. */
+#define stc_get_supers(Type) \
+ get_super_types< Type >::ret
+
+/// \def Get the Nth immediate base class(es) of Type (version to be
+/// used inside a template).
+# define stc_get_nth_super(Type, Nth) \
+ typename stc_get_nth_super_(Type, Nth)
+
+/// \def Get the Nth immediate base class(es) of Type (version to be
+/// used outside a template).
+# define stc_get_nth_super_(Type, Nth) \
+ set_super_type< Type, Nth >::ret
+
+/// \def Get the fisrt immediate base class of Type (version to be
+/// used inside a template).
+# define stc_get_super(Type) \
+ typename stc_get_super_(Type)
+
+/// \def Get the first immediate base class of Type (version to be
+/// used outside a template).
+# define stc_get_super_(Type) \
+ stc_get_nth_super_(Type, 1)
+
+
+// -------------------- //
+// Pseudo inheritance. //
+// -------------------- //
/* FIXME: I don't know whether this macro will be really usable; what
if Type is a template class? We would have to provide additional
@@ -400,25 +550,20 @@
typedef PseudoSuper ret; \
}
-/// \def Get the immediate base class of T (version to be used inside
-/// a template).
-# define stc_super(T) \
- typename stc_super_(T)
-
-/// \def Get the immediate base class of T (version to be used outside
-/// a template).
-# define stc_super_(T) \
- set_super_type<T>::ret
-
-/// \def Get the pseudosuper class of T (version to be used inside a
+/// \def Get the pseudosuper class of Type (version to be used inside a
/// template).
-# define stc_pseudosuper(T) \
- typename stc_pseudosuper_(T)
+# define stc_get_pseudosuper(Type) \
+ typename stc_get_pseudosuper_(Type)
-/// \def Get the pseudosuper class of T (version to be used outside a
+/// \def Get the pseudosuper class of Type (version to be used outside a
/// template).
-# define stc_pseudosuper_(T) \
- set_pseudosuper_type<T>::ret
+# define stc_get_pseudosuper_(Type) \
+ set_pseudosuper_type< Type >::ret
+
+
+// ---------------------- //
+// Virtual types access. //
+// ---------------------- //
// FIXME: Perhaps only ``external'' (i.e., non local) versions of
// stc_type_of are really useful (since they are more precise), and we
Index: stc/Makefile.am
--- stc/Makefile.am (revision 492)
+++ stc/Makefile.am (working copy)
@@ -4,4 +4,6 @@
nobase_stc_HEADERS = \
any.hh \
entry.hh \
+ exact.hh \
+ valist_aggregator.hh \
vtypes.hh