https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Update SCOOP 2 alternative implementation.
* stc/scoop-alt.hh: Split this file into...
* stc/scoop-alt.hh, stc/scoop-alt.inc: ...these.
Catch up with the interface of oln/stc/scoop.hh and
oln/stc/scoop.hxx.
* stc/Makefile.am (nobase_stc_HEADERS): Add scoop-alt.inc.
* tests/scoop-alt.cc: Adjust existing tests.
(ex8, ex9): New tests.
(main): Run them.
stc/Makefile.am | 1
stc/scoop-alt.hh | 720 ++++---------------------
stc/scoop-alt.inc | 1471 +++++++++++++++++++++++++++++------------------------
tests/scoop-alt.cc | 393 +++++++++++---
4 files changed, 1255 insertions(+), 1330 deletions(-)
Index: tests/scoop-alt.cc
--- tests/scoop-alt.cc (revision 877)
+++ tests/scoop-alt.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2006, 2007 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
@@ -31,31 +31,42 @@
/// These examples comes from doc/algorithm.ml.
+#include <cassert>
-#include <mlc/cmp.hh>
#include <mlc/assert.hh>
+#include <mlc/cmp.hh>
#include <stc/scoop-alt.hh>
-// Namespace equipment.
-stc_scoop_equipment_for_namespace(my);
+#include <mlc/int.hh>
// FIXME: Check single_vtype, too.
namespace my
{
+
+ // ------------------------------------------------- Namespace equipment.
+
+# include <stc/scoop-alt.inc>
+
+
// ------------------------------------------------------------ Typedefs.
mlc_decl_typedef(my_type);
- mlc_decl_typedef(foo_type);
- mlc_decl_typedef(bar_type);
- mlc_decl_typedef(baz_type);
- mlc_decl_typedef(quux_type);
- mlc_decl_typedef(hop_type);
+ mlc_decl_typedef(foo);
+ mlc_decl_typedef(bar);
+ mlc_decl_typedef(baz);
+ mlc_decl_typedef(quux);
+ mlc_decl_typedef(hop);
+
+ mlc_decl_typedef(value);
- mlc_decl_typedef(value_type);
+ mlc_decl_typedef(dim);
+ mlc_decl_typedef(mydim);
+
+ mlc_decl_typedef(grid);
@@ -78,7 +89,7 @@
}
// Set super type.
- template <> struct set_super_type<ex1::A> { typedef stc::none ret; };
+ template <> struct super_trait_<ex1::A> { typedef stc::none ret; };
/// Virtual types associated to A.
template <>
@@ -95,7 +106,7 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex1::A, my), int)
+ mlc_eq(stc_find_type_(my::ex1::A, my_type), int)
::check();
}
}
@@ -131,9 +142,9 @@
}
// Set super types.
- template <> struct set_super_type<ex2::A> { typedef stc::none ret; };
- template <> struct set_super_type<ex2::B> { typedef ex2::A ret; };
- template <> struct set_super_type<ex2::C> { typedef ex2::B ret; };
+ template <> struct super_trait_<ex2::A> { typedef stc::none ret; };
+ template <> struct super_trait_<ex2::B> { typedef ex2::A ret; };
+ template <> struct super_trait_<ex2::C> { typedef ex2::B ret; };
/// Virtual types associated to A.
template <>
@@ -166,15 +177,15 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex2::A, my), int)
+ mlc_eq(stc_find_type_(my::ex2::A, my_type), int)
::check();
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex2::B, my), float)
+ mlc_eq(stc_find_type_(my::ex2::B, my_type), float)
::check();
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex2::C, my), int)
+ mlc_eq(stc_find_type_(my::ex2::C, my_type), int)
::check();
}
}
@@ -205,8 +216,8 @@
}
// Set super types.
- template <> struct set_super_type<ex3::A> { typedef stc::none ret; };
- template <> struct set_super_type<ex3::B> { typedef ex3::A ret; };
+ template <> struct super_trait_<ex3::A> { typedef stc::none ret; };
+ template <> struct super_trait_<ex3::B> { typedef ex3::A ret; };
/// Virtual types associated to A.
template <>
@@ -231,7 +242,7 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex3::B, my), int)
+ mlc_eq(stc_find_type_(my::ex3::B, my_type), int)
::check();
}
}
@@ -258,7 +269,7 @@
}
// Set super type.
- template <> struct set_super_type<ex4::A> { typedef stc::none ret; };
+ template <> struct super_trait_<ex4::A> { typedef stc::none ret; };
/// Virtual types associated to A.
template <>
@@ -275,7 +286,7 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex4::A, my), int)
+ mlc_eq(stc_find_type_(my::ex4::A, my_type), int)
::check();
}
}
@@ -303,7 +314,7 @@
// C<>--D
class C < stc::none
{
- vtype delegatee_type = D;
+ vtype delegatee = D;
}
type t = C#my_type;
@@ -318,9 +329,9 @@
}
// Set super types.
- template <> struct set_super_type<ex5::A> { typedef stc::none ret; };
- template <> struct set_super_type<ex5::D> { typedef stc::none ret; };
- template <> struct set_super_type<ex5::C> { typedef ex5::A ret; };
+ template <> struct super_trait_<ex5::A> { typedef stc::none ret; };
+ template <> struct super_trait_<ex5::D> { typedef stc::none ret; };
+ template <> struct super_trait_<ex5::C> { typedef ex5::A ret; };
/// Virtual types associated to A.
template <>
@@ -339,7 +350,7 @@
template <>
struct vtypes<ex5::C>
{
- typedef ex5::D delegatee_type;
+ typedef ex5::D delegatee;
};
namespace ex5
@@ -352,7 +363,7 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex5::C, my), stc::not_found)
+ mlc_eq(stc_find_type_(my::ex5::C, my_type), stc::not_found)
::check();
}
}
@@ -381,7 +392,7 @@
class A < stc::none | class C < B
{ | {
- } | vtype delegatee_type = Y;
+ } | vtype delegatee = Y;
class B < A | vtype foo = int;
{ | vtype baz = not_delegated;
vtype foo = 0; | vtype hop = not_delegated;
@@ -414,15 +425,15 @@
}
// Set super types.
- template <> struct set_super_type<ex6::A> { typedef stc::none ret; };
- template <> struct set_super_type<ex6::B> { typedef ex6::A ret; };
+ template <> struct super_trait_<ex6::A> { typedef stc::none ret; };
+ template <> struct super_trait_<ex6::B> { typedef ex6::A ret; };
- template <> struct set_super_type<ex6::X> { typedef stc::none ret; };
- template <> struct set_super_type<ex6::Y> { typedef ex6::X ret; };
+ template <> struct super_trait_<ex6::X> { typedef stc::none ret; };
+ template <> struct super_trait_<ex6::Y> { typedef ex6::X ret; };
- template <> struct set_super_type<ex6::C> { typedef ex6::B ret; };
- template <> struct set_super_type<ex6::D> { typedef ex6::C ret; };
- template <> struct set_super_type<ex6::E> { typedef ex6::D ret; };
+ template <> struct super_trait_<ex6::C> { typedef ex6::B ret; };
+ template <> struct super_trait_<ex6::D> { typedef ex6::C ret; };
+ template <> struct super_trait_<ex6::E> { typedef ex6::D ret; };
/// Virtual types associated to A.
template <>
@@ -434,47 +445,47 @@
template <>
struct vtypes<ex6::B>
{
- typedef stc::abstract foo_type;
+ typedef stc::abstract foo;
};
/// Virtual types associated to X.
template <>
struct vtypes<ex6::X>
{
- typedef stc::abstract bar_type;
- typedef int hop_type;
+ typedef stc::abstract bar;
+ typedef int hop;
};
/// Virtual types associated to Y.
template <>
struct vtypes<ex6::Y>
{
- typedef short baz_type;
- typedef char bar_type;
+ typedef short baz;
+ typedef char bar;
};
/// Virtual types associated to C.
template <>
struct vtypes<ex6::C>
{
- typedef ex6::Y delegatee_type;
- typedef int foo_type;
- typedef stc::not_delegated baz_type;
- typedef stc::not_delegated hop_type;
+ typedef ex6::Y delegatee;
+ typedef int foo;
+ typedef stc::not_delegated baz;
+ typedef stc::not_delegated hop;
};
/// Virtual types associated to D.
template <>
struct vtypes<ex6::D>
{
- typedef unsigned quux_type;
+ typedef unsigned quux;
};
/// Virtual types associated to E.
template <>
struct vtypes<ex6::E>
{
- typedef float baz_type;
+ typedef float baz;
};
namespace ex6
@@ -493,23 +504,23 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex6::E, foo), int)
+ mlc_eq(stc_find_type_(my::ex6::E, foo), int)
::check();
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex6::E, bar), char)
+ mlc_eq(stc_find_type_(my::ex6::E, bar), char)
::check();
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex6::E, baz), float)
+ mlc_eq(stc_find_type_(my::ex6::E, baz), float)
::check();
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex6::E, quux), unsigned)
+ mlc_eq(stc_find_type_(my::ex6::E, quux), unsigned)
::check();
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex6::E, hop), stc::not_found)
+ mlc_eq(stc_find_type_(my::ex6::E, hop), stc::not_found)
::check();
}
}
@@ -521,24 +532,24 @@
class /image_entry/ < stc::none
{
- vtype value_type = 0;
+ vtype value = 0;
}
class image2d<int> < image_entry
{
- vtypes value_type = int;
+ vtypes value = int;
}
class /value_morpher/ < image_entry
{
- vtype delegatee_type = 0;
- vtype value_type = stc::not_delegated;
+ vtype delegatee = 0;
+ vtype value = stc::not_delegated;
}
class value_cast<image2d<int>, float> < value_morpher
{
- vtype delegatee_type = image2d<int>;
- vtype value_type = float;
+ vtype delegatee = image2d<int>;
+ vtype value = float;
}
*/
@@ -557,22 +568,22 @@
// Set super types.
template <>
- struct set_super_type<ex7::abstract::image_entry>
+ struct super_trait_<ex7::abstract::image_entry>
{
typedef stc::none ret;
};
template <>
- struct set_super_type<ex7::abstract::value_morpher>
+ struct super_trait_<ex7::abstract::value_morpher>
{
typedef ex7::abstract::image_entry ret;
};
template <typename T>
- struct set_super_type< ex7::image2d<T> >
+ struct super_trait_< ex7::image2d<T> >
{
typedef ex7::abstract::image_entry ret;
};
template <typename I, typename T>
- struct set_super_type< ex7::value_cast<I, T> >
+ struct super_trait_< ex7::value_cast<I, T> >
{
typedef ex7::abstract::value_morpher ret;
};
@@ -582,30 +593,30 @@
template <>
struct vtypes<ex7::abstract::image_entry>
{
- typedef stc::abstract value_type;
+ typedef stc::abstract value;
};
/// Virtual types associated to abstract::value_morpher.
template <>
struct vtypes<ex7::abstract::value_morpher>
{
- typedef stc::abstract delegatee_type;
- typedef stc::not_delegated value_type;
+ typedef stc::abstract delegatee;
+ typedef stc::not_delegated value;
};
/// Virtual types associated to image2d<T>.
template <typename T>
struct vtypes< ex7::image2d<T> >
{
- typedef T value_type;
+ typedef T value;
};
/// Virtual types associated to value_cast<I, T>.
template <typename I, typename T>
struct vtypes< ex7::value_cast<I, T> >
{
- typedef I delegatee_type;
- typedef T value_type;
+ typedef I delegatee;
+ typedef T value;
};
@@ -628,16 +639,254 @@
check()
{
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, my::ex7::image2d<int>, value), int)
+ mlc_eq(stc_find_type_(my::ex7::image2d<int>, value), int)
::check();
typedef value_cast< image2d<int>, float> morphed_type;
mlc::assert_<
- mlc_eq(stc_find_vtype_(my, morphed_type, value), float)
+ mlc_eq(stc_find_type_(morphed_type, value), float)
::check();
}
}
+
+ /* ---------------------------------------------------------------- Ex 8.
+
+ Another Olena-like example with recursive definitions.
+
+ class internal_dpoint_nd < stc::none
+ {
+ vtype mydim = find dpoint2d "dim";
+ }
+
+ class dpoint2d < internal_dpoint_nd
+ {
+ // Dummy value (because our C++ types are limited in this prototype).
+ vtype dim = int
+ }
+
+ This example is translated to C++ using the Exact-type-passing
+ technique in order to perform a test closer to what can be found
+ in Olena. */
+
+ namespace ex8
+ {
+ // Forward declarations.
+ template <typename Exact> struct internal_dpoint_nd;
+ struct dpoint2d;
+ }
+
+ // Set super types.
+ template <typename Exact>
+ struct super_trait_< ex8::internal_dpoint_nd<Exact> >
+ {
+ typedef stc::none ret;
+ };
+ template <>
+ struct super_trait_<ex8::dpoint2d>
+ {
+ typedef ex8::internal_dpoint_nd< ex8::dpoint2d > ret;
+ };
+
+ /// Virtual types associated to internal_dpoint_nd<Exact>.
+ template <typename Exact>
+ struct vtypes< ex8::internal_dpoint_nd <Exact> >
+ {
+ typedef stc_find_type(Exact, dim) mydim;
+ };
+ /// Virtual types associated to dpoint2d.
+ template <>
+ struct vtypes< ex8::dpoint2d >
+ {
+ typedef int dim;
+ };
+
+ namespace ex8
+ {
+ template <typename Exact>
+ struct internal_dpoint_nd : public stc::none
+ {
+ };
+ struct dpoint2d : public internal_dpoint_nd< dpoint2d >
+ {
+ };
+
+ void
+ check()
+ {
+ mlc::assert_<
+ mlc_eq(stc_find_type_(my::ex8::dpoint2d, mydim), int)
+ >::check();
+ }
+
+ } // end of namespace my::ex8
+
+
+ /* ---------------------------------------------------------------- Ex 9.
+
+ Another Olena-inspired example.
+
+ ...
+
+ There are other virtual types in the Olena version of the
+ following classes, but we don't need them for this simple test. */
+
+ // FIXME: I (Roland) don't know why this test succeeds, while the
+ // equivalent SCOOP 2 hierarchy doesn't work in Olena.
+
+ /*------------------------.
+ | internal::point_base_. |
+ `------------------------*/
+
+ // Forward declaration.
+ namespace ex9
+ {
+ namespace internal
+ {
+ template <typename Exact> struct point_base_;
+ }
+ }
+
+ /// Set super type.
+ template <typename Exact>
+ struct super_trait_< ex9::internal::point_base_<Exact> >
+ {
+ typedef stc::none ret;
+ };
+
+ /// Virtual types associated to internal::point_base_<Exact>
+ template <typename Exact>
+ struct vtypes< ex9::internal::point_base_<Exact> >
+ {
+ typedef stc::abstract grid;
+
+ typedef stc_deferred(grid) grid__;
+ typedef stc::final<stc_type(grid__, dim)> dim;
+
+ };
+
+ // Actual definition.
+ namespace ex9
+ {
+ namespace internal
+ {
+ template <typename Exact>
+ struct point_base_ : public stc::none
+ {
+ stc_typename(dim);
+ static const unsigned dim_val = mlc_value(dim);
+ };
+ } // end of namespace my::ex9::internal
+ }
+
+
+ /*---------------------.
+ | internal::point2d_. |
+ `---------------------*/
+
+ // FIXME: Add internal::point2d_, as in Olena, and check whether
+ // this addition triggers the same behavior observed in Olena.
+
+// namespace ex9
+// {
+// // Forward declarations.
+// namespace internal
+// {
+// template <typename Exact> struct point2d_;
+// }
+// }
+
+ // ...
+
+
+ /*---------.
+ | grid2d. |
+ `---------*/
+
+ // Forward declaration.
+ namespace ex9
+ {
+ struct grid2d;
+ }
+
+ /// Set super type.
+ template <>
+ struct super_trait_< ex9::grid2d >
+ {
+ typedef stc::none ret;
+ };
+
+ /// Virtual types associated to grid2d.
+ template <>
+ struct vtypes< ex9::grid2d >
+ {
+ typedef mlc::uint_<2u> dim;
+ };
+
+ // Actual definition.
+ namespace ex9
+ {
+ struct grid2d : public stc::none
+ {
+ };
+ }
+
+
+ /*----------.
+ | point2d. |
+ `----------*/
+
+ // Forward declaration.
+ namespace ex9
+ {
+ struct point2d;
+ }
+
+ /// Set super type.
+ template <>
+ struct super_trait_< ex9::point2d >
+ {
+ typedef ex9::internal::point_base_<ex9::point2d> ret;
+ };
+
+
+ /// Virtual types associated to point2d.
+ template <>
+ struct vtypes< ex9::point2d >
+ {
+ typedef ex9::grid2d grid;
+ };
+
+ // Actual definition.
+ namespace ex9
+ {
+ struct point2d : public internal::point_base_< point2d >
+ {
+ };
+ }
+
+
+ /*---------------------.
+ | Client (test) code. |
+ `---------------------*/
+
+ namespace ex9
+ {
+ void
+ check()
+ {
+ mlc::assert_<
+ mlc_eq(stc_find_type_(my::ex9::point2d, dim), mlc::uint_<2u>)
+ >::check();
+
+ assert(ex9::point2d::dim_val == 2);
+
+ point2d p;
+ }
+
+ } // end of namespace my::ex9
+
+
} // end of namespace my
@@ -651,4 +900,6 @@
my::ex5::check();
my::ex6::check();
my::ex7::check();
+ my::ex8::check();
+ my::ex9::check();
}
Index: stc/scoop-alt.hh
--- stc/scoop-alt.hh (revision 877)
+++ stc/scoop-alt.hh (working copy)
@@ -35,9 +35,15 @@
#ifndef STC_SCOOP_ALT_HH
# define STC_SCOOP_ALT_HH
+/** Define a stick-macro so that we can check in
+ \file stc/scoop-alt.inc that \file stc/scoop-alt.hh has been
+ included (or not) when including the former from client code. */
+# define STATIC_SCOOP_ALT_HH_INCLUDED
+
# include <mlc/flags.hh>
# include <mlc/typedef.hh>
# include <mlc/abort.hh>
+# include <mlc/case.hh>
# include <stc/internal/match-with.hh>
@@ -53,31 +59,46 @@
#endif
using mlc::none;
+ // FIXME: Likewise, define a true stc::not_found type.
+#if 0
struct not_found;
+#endif
+ typedef mlc::not_found not_found;
struct abstract;
struct not_delegated;
struct not_delegated_abstract;
template <typename T> struct final;
+ template < template <class> class category >
+ struct is;
- /// \brief Shortcuts for comparison with stc::not_found.
- ///
- /// Duplicate with their Metalic's homonyms, but still useful, since
- /// they deal with std::not_found (not mlc::not_found).
+
+
+ /// Equality test between a couple of types.
/// \{
template <typename T>
- struct is_not_found_ : public mlc_is_a(T, stc::not_found)::bexpr
- {
- };
+ struct is_found : public mlc::bexpr_<true>
+ {};
+
+ template <>
+ struct is_found< mlc::not_found > : public mlc::bexpr_<false>
+ {};
template <typename T>
- struct is_found_ : public mlc_is_not_a(T, stc::not_found)::bexpr
- {
- };
+ struct is_not_found : public mlc::bexpr_<false>
+ {};
+
+ template <>
+ struct is_not_found< mlc::not_found > : public mlc::bexpr_<true>
+ {};
/// \}
+
namespace ERROR
{
+ template <typename class_name>
+ struct super_trait_not_defined_for_;
+
struct IN_find_VIRTUAL_TYPE_IS_ABSTRACT;
struct IN_find_local_VIRTUAL_TYPE_MULTIPLY_DEFINED;
@@ -98,613 +119,108 @@
} // end of namespace stc
-#define stc_super(T) typename set_super_type< T >::ret
+/*------------------.
+| Shortcuts macro. |
+`------------------*/
-// Based on doc/algorithm.ml.
+# define stc_decl_associated_type mlc_decl_typedef
+# define stc_super(T) typename super_trait_< T >::ret
-#define stc_scoop_equipment_for_namespace(SCOOPED_NAMESPACE) \
- \
-namespace SCOOPED_NAMESPACE \
-{ \
- \
- /* Declare delegatee_type. */ \
- mlc_decl_typedef(delegatee_type); \
- \
- \
- template <typename class_name> \
- struct set_super_type \
- { \
- }; \
- \
- template <typename class_name> \
- struct vtypes \
- { \
- }; \
- \
- template <typename class_name, typename type_name> \
- struct single_vtype \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- /* ----------------------------------------------------- find_local. */ \
- \
- /* Highly inspired from Th�o's get_stm! */ \
- \
- namespace find_local_ \
- { \
- /* Forward declaration. */ \
- template <typename T, typename U> struct match_with; \
- \
- template <typename T> \
- struct match_with <T, mlc::not_found> \
- { \
- typedef T ret; \
- }; \
- \
- template <typename U> \
- struct match_with <mlc::not_found, U> \
- { \
- typedef U ret; \
- }; \
- \
- template <> \
- struct match_with <mlc::not_found, mlc::not_found> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename T, typename U> \
- struct match_with : \
- mlc::abort_<T, \
- stc::ERROR::IN_find_local_VIRTUAL_TYPE_MULTIPLY_DEFINED> \
- { \
- }; \
- \
- } /* end of namespace find_local_ */ \
- \
- template <typename source, typename target> \
- struct find_local \
- { \
- typedef SCOOPED_NAMESPACE::vtypes<source> decl1; \
- typedef typename target::template from_<decl1>::ret res1; \
- \
- typedef SCOOPED_NAMESPACE::single_vtype<source, target> decl2; \
- typedef typename decl2::ret ret2; \
- \
- \
- /* Result. */ \
- typedef typename find_local_::match_with<res1, ret2>::ret ret; \
- }; \
- \
- \
- /* --------------------------------------------------------- merge2. */ \
- \
- \
- namespace merge2_ \
- { \
- /* Forward declaration. */ \
- template <typename T, typename U> struct match_with; \
- \
- \
- /* ----------------------------- */ \
- /* local_res == stc::not_found. */ \
- /* ----------------------------- */ \
- \
- stc_internal_match_pair_0p_with(stc::not_found, stc::not_found, \
- stc::not_found); \
- \
- stc_internal_match_pair_0p_with(stc::not_found, stc::abstract, \
- stc::not_found); \
- \
- stc_internal_match_pair_1p_with(U, \
- stc::not_found, stc::final<U>, \
- stc::final<U>); \
- \
- stc_internal_match_pair_1p_with(U, \
- stc::not_found, U, \
- U); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::abstract. */ \
- /* ---------------------------- */ \
- \
- stc_internal_match_pair_0p_with(stc::abstract, stc::not_found, \
- stc::abstract); \
- \
- stc_internal_match_pair_0p_with(stc::abstract, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_pair_1p_with_error(U, \
- stc::abstract, stc::final<U>, \
- stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- stc_internal_match_pair_1p_with_error(U, \
- stc::abstract, U, \
- stc::ERROR::IN_merge2_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::final<T>. */ \
- /* ---------------------------- */ \
- \
- stc_internal_match_pair_1p_with(T, \
- stc::final<T>, stc::not_found, \
- stc::final<T>); \
- \
- stc_internal_match_pair_1p_with(T, \
- stc::final<T>, stc::abstract, \
- stc::final<T>); \
- \
- stc_internal_match_pair_2p_with_error(T, U, \
- stc::final<T>, stc::final<U>, \
- stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL); \
- \
- stc_internal_match_pair_2p_with(T, U, \
- stc::final<T>, U, \
- stc::final<T>); \
- \
- \
- /* ---------------- */ \
- /* local_res == T. */ \
- /* ---------------- */ \
- \
- stc_internal_match_pair_1p_with(T, \
- T, stc::not_found, \
- T); \
- \
- stc_internal_match_pair_1p_with(T, \
- T, stc::abstract, \
- T); \
- \
- stc_internal_match_pair_2p_with_error(T, U, \
- T, stc::final<U>, \
- stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED); \
- \
- template <typename T, typename U> \
- struct match_with \
- { \
- typedef T ret; \
- }; \
- \
- } /* end of namespace merge2_ */ \
- \
- template <typename local_res, typename super_res> \
- struct merge2 \
- { \
- /* Result. */ \
- typedef typename merge2_::match_with<local_res, super_res>::ret ret; \
- }; \
- \
- \
- /* --------------------------------------------------------- merge3. */ \
- \
- \
- namespace merge3_ \
- { \
- /* Forward declaration. */ \
- template <typename T, typename U, typename V> struct match_with; \
- \
- \
- /* ----------------------------- */ \
- /* local_res == stc::not_found. */ \
- /* ----------------------------- */ \
- \
- /* super_res == stc::not_found. */ \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::not_found, stc::not_found, \
- stc::not_found); \
- \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::not_found, stc::abstract, \
- stc::not_found); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::not_found, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::not_found, V, \
- V); \
- \
- /* super_res == stc::abstract. */ \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::abstract, stc::not_found, \
- stc::not_found); \
- \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::abstract, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::abstract, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::abstract, V, \
- V); \
- \
- /* super_res is a concrete type. */ \
- stc_internal_match_triple_2p_with(U, V, \
- stc::not_found, stc::final<U>, V, \
- stc::final<U>); \
- \
- stc_internal_match_triple_2p_with(U, V, \
- stc::not_found, U, V, \
- U); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::abstract. */ \
- /* ---------------------------- */ \
- \
- /* super_res == stc::not_found. */ \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::not_found, stc::not_found, \
- stc::abstract); \
- \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::not_found, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_found, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_found, V, \
- V); \
- \
- \
- /* super_res == stc::abstract. */ \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::abstract, stc::not_found, \
- stc::abstract); \
- \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::abstract, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::abstract, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::abstract, V, \
- V); \
- \
- \
- /* super_res == stc::not_delegated_abstract. */ \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_delegated_abstract, V, \
- stc::not_delegated_abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_delegated, V, \
- stc::not_delegated_abstract); \
- \
- \
- /* super_res is a concrete type. */ \
- stc_internal_match_triple_2p_with_error(U, V, \
- stc::abstract, stc::final<U>, V, \
- stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- stc_internal_match_triple_2p_with_error(U, V, \
- stc::abstract, U, V, \
- stc::ERROR::IN_merge3_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- \
- /* --------------------------------- */ \
- /* local_res == stc::not_delegated. */ \
- /* --------------------------------- */ \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_delegated, stc::not_found, V, \
- stc::not_delegated); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_delegated, stc::abstract, V, \
- stc::not_delegated_abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_delegated, stc::not_delegated_abstract, V, \
- stc::not_delegated_abstract); \
- \
- \
- /* ------------------------------------------ */ \
- /* local_res == stc::not_delegated_abstract. */ \
- /* ------------------------------------------ */ \
- \
- /* FIXME: Shouldn't we introduce a means to tag a vtype both as */ \
- /* abstract *and* not delegated? (Currently, the rule below */ \
- /* prevents this). */ \
- stc_internal_match_triple_2p_with_error(U, V, \
- stc::not_delegated_abstract, U, V, \
- stc::ERROR::IN_merge3_LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::final<T>. */ \
- /* ---------------------------- */ \
- \
- stc_internal_match_triple_3p_with_error(T, U, V, \
- stc::final<T>, stc::final<U>, V, \
- stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL); \
- \
- stc_internal_match_triple_3p_with(T, U, V, \
- stc::final<T>, U, V, \
- stc::final<T>); \
- \
- \
- /* ---------------- */ \
- /* local_res == T. */ \
- /* ---------------- */ \
- \
- stc_internal_match_triple_3p_with_error(T, U, V, \
- T, stc::final<U>, V, \
- stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED); \
- \
- template <typename T, typename U, typename V> \
- struct match_with \
- { \
- typedef T ret; \
- }; \
- \
- } /* end of namespace merge3_ */ \
- \
- \
- template <typename local_res, typename super_res, typename delegatee_res> \
- struct merge3 \
- { \
- /* Result. */ \
- typedef typename \
- merge3_::match_with<local_res, super_res, delegatee_res>::ret ret; \
- }; \
- \
- \
- /* ------------------------------------------------------ find_rec. */ \
- \
- /* Forward declarations. */ \
- template <typename source, typename target> struct find_rec; \
- template <typename source, typename target> struct find_rec_in_supers; \
- \
- \
- namespace find_rec_ \
- { \
- \
- namespace find_delegatee_res_ \
- { \
- /* Forward declaration. */ \
- template <typename delegatee, typename target> struct match_with; \
- \
- template <typename target> \
- struct match_with<stc::not_found, target> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename target> \
- struct match_with<stc::abstract, target> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename delegatee, typename target> \
- struct match_with \
- { \
- typedef typename find_rec<delegatee, target>::ret ret; \
- }; \
- \
- } /* end of namespace find_delegatee_res_ */ \
- \
- \
- /* Forward declaration. */ \
- template <typename source, typename target> struct match_with; \
- \
- template <typename target> \
- struct match_with<stc::none, target> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename source, typename target> \
- struct match_with \
- { \
- typedef typename find_local<source, target>::ret local_res; \
- typedef typename find_rec<stc_super(source), target>::ret super_res; \
- /* delegatee_type is the name of the (optional) virtual type */ \
- /* containing the (type of the) delgatee. */ \
- typedef typename \
- find_rec_in_supers<source, typedef_::delegatee_type>::ret delegatee; \
- \
- typedef typename \
- find_delegatee_res_::match_with<delegatee, target>::ret delegatee_res; \
- typedef typename \
- merge3<local_res, super_res, delegatee_res>::ret ret; \
- }; \
- \
- } /* end of namespace find_rec_ */ \
- \
- template <typename source, typename target> \
- struct find_rec \
- { \
- /* Result. */ \
- typedef typename find_rec_::match_with<source, target>::ret ret; \
- }; \
- \
- \
- /* --------------------------------------------- find_rec_in_supers. */ \
- \
- namespace find_rec_in_supers_ \
- { \
- /* Forward declaration. */ \
- template <typename source, typename target> struct match_with; \
- \
- template <typename target> \
- struct match_with<stc::none, target> \
- { \
- typedef stc::none ret; \
- }; \
- \
- template <typename source, typename target> \
- struct match_with \
- { \
- typedef typename find_local<source, target>::ret local_res; \
- typedef typename find_rec<stc_super(source), target>::ret super_res; \
- typedef typename merge2<local_res, super_res>::ret ret; \
- }; \
- \
- } /* end of namespace find_rec_in_supers_ */ \
- \
- template <typename source, typename target> \
- struct find_rec_in_supers \
- { \
- /* Result. */ \
- typedef typename \
- find_rec_in_supers_::match_with<source, target>::ret ret; \
- }; \
- \
- \
- /* ----------------------------------------------------------- find. */ \
- \
- namespace find_ \
- { \
- /* Forward declaration. */ \
- template <typename T> struct match_with; \
- \
- /* FIXME: We'd like to add a static abort here, but we can't, */ \
- /* since stc::abstract is not a free parameter (enabling this */ \
- /* abort statement would prevent any compilation). */ \
- template <> \
- struct match_with<stc::abstract> \
- /* : mlc::abort_<stc::abstract, \
- stc::ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT> */ \
- { \
- }; \
- \
- /* FIXME: We'd like to add a static abort here, but we can't, */ \
- /* since stc::not_delegated_abstract is not a free parameter */ \
- /* (enabling this abort statement would prevent any */ \
- /* compilation). */ \
- template <> \
- struct match_with<stc::not_delegated_abstract> \
- /* : mlc::abort_<stc::not_delegated_abstract, */ \
- /* stc::ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT> */ \
- { \
- }; \
- \
- template <> \
- struct match_with<stc::not_delegated> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename T> \
- struct match_with< stc::final<T> > \
- { \
- typedef T ret; \
- }; \
- \
- template <typename T> \
- struct match_with \
- { \
- typedef T ret; \
- }; \
- \
- } /* end of namespace find_ */ \
- \
- \
- /** Find a virtual type. */ \
- template <typename source, typename target> \
- struct find_vtype \
- { \
- typedef typename find_rec<source, target>::ret res; \
- /* Result. */ \
- typedef typename find_::match_with<res>::ret ret; \
- }; \
- \
- \
- /** Find a virtual type, and ensure it is found. */ \
- template <typename from, typename target> \
- struct vtype \
- { \
- typedef typename find_vtype<from, target>::ret res; \
- struct check_ : mlc::assert_< mlc::is_found_<res> > \
- { \
- typedef res ret; \
- }; \
- typedef typename check_::ret ret; \
- }; \
- \
-} /* end of SCOOPED_NAMESPACE */ \
- \
-struct e_n_d___w_i_t_h___s_e_m_i_c_o_l_o_n;
+// FIXME: Document all these macros.
-/*------------------.
-| Shortcuts macro. |
-`------------------*/
+/// Access to associated type.
+/// \{
+# define stc_type_(Source, Target) vtype<Source, typedef_::Target>::ret
+# define stc_type(Source, Target) typename stc_type_(Source, Target)
+
+# define stc_type_in_(Namespace, Source, Target) \
+ Namespace::vtype<Source, Namespace::typedef_::Target>::ret
+# define stc_type_in(Namespace, Source, Target) \
+ typename stc_type_in_(Namespace, Source, Target)
+
+/// Access from the interior of the class.
+/// \{
+# define stc_get_type_(Target) vtype<Exact, typedef_::Target>::ret
+# define stc_get_type(Target) typename stc_get_type_(Target)
+/// \}
+
+/// \}
+
+
+/// Likewise, but more tolerant.
+/// \{
+# define stc_find_type_(Source, Target) \
+ find_vtype<Source, typedef_::Target>::ret
+# define stc_find_type(Source, Target) \
+ typename stc_find_type_(Source, Target)
+/// \}
+
+/// Boolean expression counterpart of stc_find_type
+/// \{
+# define stc_type_is_found(Target) \
+ stc::is_found< stc_deferred(Target) >
+# define stc_type_is_not_found(Target) \
+ stc::is_not_found< stc_deferred(Target) >
+/// \}
-// FIXME: Document all these macros.
-# define stc_find_vtype_(Namespace, Source, Target) \
- Namespace::find_vtype<Source, Namespace::typedef_::Target##_type>::ret
+# define stc_is_a(T, U) \
+ mlc::wrap_< \
+ typename mlc::is_a_< sizeof(mlc::form::of< U >()) > \
+ ::template ret< typename mlc::basic_< stc_deferred(T) >::ret, U > \
+ >
-# define stc_find_vtype(Namespace, Source, Target) \
- typename stc_find_vtype_(Namespace, Source, Target)
+
+/// For concepts.
+/// \{
+# define stc_typename(Target) typedef stc_type(Exact, Target) Target
+# define stc_using(Target) typedef typename super::Target Target
+# define stc_using_from(Abstraction, Target) \
+ typedef typename Abstraction<Exact>::Target Target
+# define stc_deduce_typename(Src, Target) typedef stc_type(Src, Target) Target
+/// \}
+
+
+/// For implementation classes.
+/// \{
+/// Dummy
+# define stc_deferred(Target) \
+ stc_find_type(Exact, Target)
+// typename deferred_vtype<Exact, typedef_::Target >::ret
+# define stc_lookup(Target) \
+ typedef typename vtype< stc_type(current, exact_type), \
+ typedef_::Target>::ret Target
+/// \}
+
+
+/// For set_impl classes.
+/// \{
+# define stc_deferred_typename(Target) typedef stc_deferred(Target) Target
+/// \}
// Dummy alias, for compatibility purpose (deferred virtual types are
// not currently handled by this version of stc/scoop2.hh).
-# define stc_deferred_vtype(Namespace, From, Target) \
- stc_find_vtype(Namespace, From, Target)
+# define stc_deferred_type(Source, Target) \
+ stc_find_type(Source, Target)
-# define stc_vtype_(Namespace, From, Target) \
- Namespace::vtype<From, Namespace::typedef_::Target##_type>::ret
-# define stc_vtype(Namespace, From, Target) \
- typename stc_vtype_(Namespace, From, Target)
+// The macro below was called stc_prop which was ambiguous
+// (that lets us think that it is true_ or false_) but the
+// result is a mlc::bexpr_! So it has been renamed as stc_is.
+# define stc_is(Target) mlc::eq_< stc_find_type(E, Target), stc::true_ >
+
+// Likewise.
+# define stc_is_not(Target) \
+ mlc::or_< mlc::eq_< stc_find_type(E, Target), \
+ mlc::not_found >, \
+ mlc::eq_< stc_find_type(E, Target), \
+ stc::false_ > >
-# define stc_find_deduce_vtype_(Namespace, From, Target1, Target2) \
- Namespace::find_vtype< \
- Namespace::find_vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
-
-# define stc_find_deduce_vtype(Namespace, From, Target1, Target2) \
- typename Namespace::find_vtype< \
- typename Namespace::find_vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
-
-# define stc_deduce_deferred_vtype(Namespace, From, Target1, Target2) \
- stc_find_deduce_vtype(Namespace, From, Target1, Target2)
-
-# define stc_deduce_vtype_(Namespace, From, Target1, Target2) \
- Namespace::vtype< \
- Namespace::vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
-
-# define stc_deduce_vtype(Namespace, From, Target1, Target2) \
- typename Namespace::vtype< \
- typename Namespace::vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
+# define stc_prop(Source, Target) \
+ typename mlc::eq_< stc_find_type(Source, Target), stc::true_ >::eval
#endif // ! STC_SCOOP_ALT_HH
Index: stc/Makefile.am
--- stc/Makefile.am (revision 877)
+++ stc/Makefile.am (working copy)
@@ -8,6 +8,7 @@
find_exact.hh \
scoop.hh \
scoop-alt.hh \
+ scoop-alt.inc \
valist_aggregator.hh \
\
internal/extract_vtype_from_list.hh \
Index: stc/scoop-alt.inc
--- stc/scoop-alt.inc (revision 877)
+++ stc/scoop-alt.inc (working copy)
@@ -1,3 +1,5 @@
+ // -*- C++ -*-
+
// Copyright (C) 2005, 2006, 2007 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
@@ -26,685 +28,840 @@
// Public License.
-/* \file stc/scoop-alt.hh
+#ifndef STATIC_SCOOP_ALT_HH_INCLUDED
+# error "alt/scoop.inc included but alt/scoop.hh hasn't been included"
+#endif
+
+
+/* \file stc/scoop-alt.inc
\brief Alternative equipment for SCOOP 2 (in particular, virtual
- types). */
+ types).
+
+ To be included inside the namespace to equip. \file
+ stc/scoop-alt.hh must have been previously included before this
+ file. */
-#ifndef STC_SCOOP_ALT_HH
-# define STC_SCOOP_ALT_HH
+/* Install core virtual types in the equipped namespace. */
+/* \{ */
+mlc_decl_typedef(exact_);
-# include <mlc/flags.hh>
-# include <mlc/typedef.hh>
-# include <mlc/abort.hh>
+mlc_decl_typedef(category);
+mlc_decl_typedef(behavior);
+mlc_decl_typedef(delegatee);
+/* \} */
-# include <stc/internal/match-with.hh>
+/*--------.
+| Super. |
+`--------*/
-namespace stc
+/// Default version.
+template <typename class_name>
+struct super_trait_ :
+ mlc::abort_< class_name,
+ stc::ERROR::super_trait_not_defined_for_< class_name > >
{
- /* FIXME: Define a real stc::none, instead of making it an alias of
- mlc::none. For compatibility purpose with the current
- implementation of the SCOOP 2 paradigm (see stc/scoop.hh), we
- need to have stc::none be equal to mlc::none. */
-#if 0
- struct none {};
-#endif
- using mlc::none;
+ typedef mlc::none ret;
+};
- struct not_found;
- struct abstract;
- struct not_delegated;
- struct not_delegated_abstract;
- template <typename T> struct final;
+/// Version for abstractions (security cap).
+template <template <class> class abstraction, typename Exact>
+struct super_trait_< abstraction<Exact> >
+{
+ typedef mlc::none ret;
+};
+/// Helper for const versions.
+template <typename class_name>
+struct super_trait_ <const class_name> : public super_trait_<class_name>
+{
+};
+
+
+/*---------.
+| Vtypes. |
+`---------*/
+
+template <typename class_name>
+struct vtypes
+{
+};
+
+/// Helper for const versions.
+template <typename class_name>
+struct vtypes <const class_name> : public vtypes <class_name>
+{
+};
+
+template <typename class_name, typename type_name>
+struct single_vtype
+{
+ typedef mlc::not_found ret;
+};
+
+
+
+/*------.
+| Any. |
+`------*/
+
+// FIXME: Get rid of stc/any.hh?
+
+template <typename Exact>
+struct Any;
+
+template <typename Exact>
+struct super_trait_< Any<Exact> >
+{
+ typedef mlc::none ret;
+};
+
+template <typename Exact>
+struct vtypes< Any<Exact> >
+{
+ typedef stc::final<Exact> exact_;
+};
+
+template <typename Exact>
+struct Any
+{
+ typedef Exact exact_;
+protected:
+ Any() {}
+};
+
+
+/*--------.
+| Exact. |
+`--------*/
+
+template <typename Exact>
+Exact& exact(Any<Exact>& ref)
+{
+ return *(Exact*)(void*)(&ref);
+}
+
+template <typename Exact>
+const Exact& exact(const Any<Exact>& cref)
+{
+ return *(const Exact*)(const void*)(&cref);
+}
+
+
+template <typename Exact>
+Exact* exact(Any<Exact>* ptr)
+{
+ return (Exact*)(void*)(ptr);
+}
+
+template <typename Exact>
+const Exact* exact(const Any<Exact>* cptr)
+{
+ return (const Exact*)(const void*)(cptr);
+}
+
+template <typename Exact>
+const Exact* my_exact(const Any<Exact>* cptr)
+{
+ return (const Exact*)(const void*)(cptr);
+}
+
+
+/*----------------------.
+| Virtual type lookup. |
+`----------------------*/
+
+/* ----------------------------------------------------- find_local. */
+
+/* Highly inspired from Th�o's get_stm! */
+
+namespace find_local_
+{
+ /* Forward declaration. */
+ template <typename T, typename U> struct match_with;
+
+ template <typename T>
+ struct match_with <T, mlc::not_found>
+ {
+ typedef T ret;
+ };
+
+ template <typename U>
+ struct match_with <mlc::not_found, U>
+ {
+ typedef U ret;
+ };
+
+ template <>
+ struct match_with <mlc::not_found, mlc::not_found>
+ {
+ typedef stc::not_found ret;
+ };
+
+ template <typename T, typename U>
+ struct match_with :
+ mlc::abort_<T,
+ stc::ERROR::IN_find_local_VIRTUAL_TYPE_MULTIPLY_DEFINED>
+ {
+ };
+
+} /* End of namespace find_local_. */
+
+template <typename source, typename target>
+struct find_local
+{
+ typedef vtypes<source> decl1;
+ typedef typename target::template from_<decl1>::ret res1;
+
+ typedef single_vtype<source, target> decl2;
+ typedef typename decl2::ret ret2;
+
+
+ /* Result. */
+ typedef typename find_local_::match_with<res1, ret2>::ret ret;
+};
+
+
+/* --------------------------------------------------------- merge2. */
+
+
+namespace merge2_
+{
+ /* Forward declaration. */
+ template <typename T, typename U> struct match_with;
+
+
+ /* ----------------------------- */
+ /* local_res == stc::not_found. */
+ /* ----------------------------- */
+
+ stc_internal_match_pair_0p_with(stc::not_found, stc::not_found,
+ stc::not_found);
+
+ stc_internal_match_pair_0p_with(stc::not_found, stc::abstract,
+ stc::not_found);
+
+ stc_internal_match_pair_1p_with(U,
+ stc::not_found, stc::final<U>,
+ stc::final<U>);
+
+ stc_internal_match_pair_1p_with(U,
+ stc::not_found, U,
+ U);
+
+
+ /* ---------------------------- */
+ /* local_res == stc::abstract. */
+ /* ---------------------------- */
+
+ stc_internal_match_pair_0p_with(stc::abstract, stc::not_found,
+ stc::abstract);
+
+ stc_internal_match_pair_0p_with(stc::abstract, stc::abstract,
+ stc::abstract);
+
+ stc_internal_match_pair_1p_with_error(U,
+ stc::abstract, stc::final<U>,
+ stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT);
+
+ stc_internal_match_pair_1p_with_error(U,
+ stc::abstract, U,
+ stc::ERROR::IN_merge2_VIRTUAL_TYPE_REDEFINED_ABSTRACT);
+
+
+ /* ---------------------------- */
+ /* local_res == stc::final<T>. */
+ /* ---------------------------- */
+
+ stc_internal_match_pair_1p_with(T,
+ stc::final<T>, stc::not_found,
+ stc::final<T>);
+
+ stc_internal_match_pair_1p_with(T,
+ stc::final<T>, stc::abstract,
+ stc::final<T>);
+
+ stc_internal_match_pair_2p_with_error(T, U,
+ stc::final<T>, stc::final<U>,
+ stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL);
+
+ stc_internal_match_pair_2p_with(T, U,
+ stc::final<T>, U,
+ stc::final<T>);
+
+
+ /* ---------------- */
+ /* local_res == T. */
+ /* ---------------- */
+
+ stc_internal_match_pair_1p_with(T,
+ T, stc::not_found,
+ T);
+
+ stc_internal_match_pair_1p_with(T,
+ T, stc::abstract,
+ T);
+
+ stc_internal_match_pair_2p_with_error(T, U,
+ T, stc::final<U>,
+ stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED);
+
+ template <typename T, typename U>
+ struct match_with
+ {
+ typedef T ret;
+ };
+
+} /* End of namespace merge2_. */
+
+template <typename local_res, typename super_res>
+struct merge2
+{
+ /* Result. */
+ typedef typename merge2_::match_with<local_res, super_res>::ret ret;
+};
+
+
+/* --------------------------------------------------------- merge3. */
+
+
+namespace merge3_
+{
+ /* Forward declaration. */
+ template <typename T, typename U, typename V> struct match_with;
+
+
+ /* ----------------------------- */
+ /* local_res == stc::not_found. */
+ /* ----------------------------- */
+
+ /* super_res == stc::not_found. */
+ stc_internal_match_triple_0p_with(
+ stc::not_found, stc::not_found, stc::not_found,
+ stc::not_found);
+
+ stc_internal_match_triple_0p_with(
+ stc::not_found, stc::not_found, stc::abstract,
+ stc::not_found);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_found, stc::not_found, stc::final<V>,
+ stc::final<V>);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_found, stc::not_found, V,
+ V);
+
+ /* super_res == stc::abstract. */
+ stc_internal_match_triple_0p_with(
+ stc::not_found, stc::abstract, stc::not_found,
+ stc::not_found);
+
+ stc_internal_match_triple_0p_with(
+ stc::not_found, stc::abstract, stc::abstract,
+ stc::abstract);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_found, stc::abstract, stc::final<V>,
+ stc::final<V>);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_found, stc::abstract, V,
+ V);
+
+ /* super_res is a concrete type. */
+ stc_internal_match_triple_2p_with(U, V,
+ stc::not_found, stc::final<U>, V,
+ stc::final<U>);
+
+ stc_internal_match_triple_2p_with(U, V,
+ stc::not_found, U, V,
+ U);
+
+
+ /* ---------------------------- */
+ /* local_res == stc::abstract. */
+ /* ---------------------------- */
+
+ /* super_res == stc::not_found. */
+ stc_internal_match_triple_0p_with(
+ stc::abstract, stc::not_found, stc::not_found,
+ stc::abstract);
+
+ stc_internal_match_triple_0p_with(
+ stc::abstract, stc::not_found, stc::abstract,
+ stc::abstract);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::abstract, stc::not_found, stc::final<V>,
+ stc::final<V>);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::abstract, stc::not_found, V,
+ V);
+
+
+ /* super_res == stc::abstract. */
+ stc_internal_match_triple_0p_with(
+ stc::abstract, stc::abstract, stc::not_found,
+ stc::abstract);
+
+ stc_internal_match_triple_0p_with(
+ stc::abstract, stc::abstract, stc::abstract,
+ stc::abstract);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::abstract, stc::abstract, stc::final<V>,
+ stc::final<V>);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::abstract, stc::abstract, V,
+ V);
+
+
+ /* super_res == stc::not_delegated_abstract. */
+ stc_internal_match_triple_1p_with(V,
+ stc::abstract, stc::not_delegated_abstract, V,
+ stc::not_delegated_abstract);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::abstract, stc::not_delegated, V,
+ stc::not_delegated_abstract);
+
+
+ /* super_res is a concrete type. */
+ stc_internal_match_triple_2p_with_error(U, V,
+ stc::abstract, stc::final<U>, V,
+ stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT);
+
+ stc_internal_match_triple_2p_with_error(U, V,
+ stc::abstract, U, V,
+ stc::ERROR::IN_merge3_VIRTUAL_TYPE_REDEFINED_ABSTRACT);
+
+
+ /* --------------------------------- */
+ /* local_res == stc::not_delegated. */
+ /* --------------------------------- */
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_delegated, stc::not_found, V,
+ stc::not_delegated);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_delegated, stc::abstract, V,
+ stc::not_delegated_abstract);
+
+ stc_internal_match_triple_1p_with(V,
+ stc::not_delegated, stc::not_delegated_abstract, V,
+ stc::not_delegated_abstract);
+
+
+ /* ------------------------------------------ */
+ /* local_res == stc::not_delegated_abstract. */
+ /* ------------------------------------------ */
+
+ /* FIXME: Shouldn't we introduce a means to tag a vtype both as */
+ /* abstract *and* not delegated? (Currently, the rule below */
+ /* prevents this). */
+ stc_internal_match_triple_2p_with_error(U, V,
+ stc::not_delegated_abstract, U, V,
+ stc::ERROR::IN_merge3_LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT);
+
+
+ /* ---------------------------- */
+ /* local_res == stc::final<T>. */
+ /* ---------------------------- */
+
+ stc_internal_match_triple_3p_with_error(T, U, V,
+ stc::final<T>, stc::final<U>, V,
+ stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL);
+
+ stc_internal_match_triple_3p_with(T, U, V,
+ stc::final<T>, U, V,
+ stc::final<T>);
+
+
+ /* ---------------- */
+ /* local_res == T. */
+ /* ---------------- */
+
+ stc_internal_match_triple_3p_with_error(T, U, V,
+ T, stc::final<U>, V,
+ stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED);
+
+ template <typename T, typename U, typename V>
+ struct match_with
+ {
+ typedef T ret;
+ };
+
+} /* End of namespace merge3_. */
+
+
+template <typename local_res, typename super_res, typename delegatee_res>
+struct merge3
+{
+ /* Result. */
+ typedef typename
+ merge3_::match_with<local_res, super_res, delegatee_res>::ret ret;
+};
+
+
+/* ------------------------------------------------------ find_rec. */
+
+/* Forward declarations. */
+template <typename source, typename target> struct find_rec;
+template <typename source, typename target> struct find_rec_in_supers;
+
+
+namespace find_rec_
+{
+
+ namespace find_delegatee_res_
+ {
+ /* Forward declaration. */
+ template <typename delegatee, typename target> struct match_with;
+
+ template <typename target>
+ struct match_with<stc::not_found, target>
+ {
+ typedef stc::not_found ret;
+ };
+
+ template <typename target>
+ struct match_with<stc::abstract, target>
+ {
+ typedef stc::not_found ret;
+ };
+
+ template <typename delegatee, typename target>
+ struct match_with
+ {
+ typedef typename find_rec<delegatee, target>::ret ret;
+ };
+
+ } /* End of namespace find_delegatee_res_. */
+
+
+ /* Forward declaration. */
+ template <typename source, typename target> struct match_with;
+
+ template <typename target>
+ struct match_with<stc::none, target>
+ {
+ typedef stc::not_found ret;
+ };
+
+ template <typename source, typename target>
+ struct match_with
+ {
+ typedef typename find_local<source, target>::ret local_res;
+ typedef typename find_rec<stc_super(source), target>::ret super_res;
+ /* delegatee is the name of the (optional) virtual type */
+ /* containing the (type of the) delgatee. */
+ typedef typename
+ find_rec_in_supers<source, typedef_::delegatee>::ret delegatee;
+
+ typedef typename
+ find_delegatee_res_::match_with<delegatee, target>::ret delegatee_res;
+ typedef typename
+ merge3<local_res, super_res, delegatee_res>::ret ret;
+ };
+
+} /* End of namespace find_rec_. */
+
+template <typename source, typename target>
+struct find_rec
+{
+ /* Result. */
+ typedef typename find_rec_::match_with<source, target>::ret ret;
+};
+
+
+/* --------------------------------------------- find_rec_in_supers. */
+
+namespace find_rec_in_supers_
+{
+ /* Forward declaration. */
+ template <typename source, typename target> struct match_with;
+
+ template <typename target>
+ struct match_with<stc::none, target>
+ {
+ typedef stc::none ret;
+ };
+
+ template <typename source, typename target>
+ struct match_with
+ {
+ typedef typename find_local<source, target>::ret local_res;
+ typedef typename find_rec<stc_super(source), target>::ret super_res;
+ typedef typename merge2<local_res, super_res>::ret ret;
+ };
+
+} /* End of namespace find_rec_in_supers_. */
+
+template <typename source, typename target>
+struct find_rec_in_supers
+{
+ /* Result. */
+ typedef typename
+ find_rec_in_supers_::match_with<source, target>::ret ret;
+};
+
+
+/* ----------------------------------------------------------- find. */
+
+namespace find_
+{
+ /* Forward declaration. */
+ template <typename T> struct match_with;
+
+ /* FIXME: We'd like to add a static abort here, but we can't, */
+ /* since stc::abstract is not a free parameter (enabling this */
+ /* abort statement would prevent any compilation). */
+ template <>
+ struct match_with<stc::abstract>
+ /* : mlc::abort_<stc::abstract, */
+ /* stc::ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT> */
+ {
+ };
+
+ /* FIXME: We'd like to add a static abort here, but we can't, */
+ /* since stc::not_delegated_abstract is not a free parameter */
+ /* (enabling this abort statement would prevent any */
+ /* compilation). */
+ template <>
+ struct match_with<stc::not_delegated_abstract>
+ /* : mlc::abort_<stc::not_delegated_abstract, */
+ /* stc::ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT> */
+ {
+ };
+
+ template <>
+ struct match_with<stc::not_delegated>
+ {
+ typedef stc::not_found ret;
+ };
- /// \brief Shortcuts for comparison with stc::not_found.
- ///
- /// Duplicate with their Metalic's homonyms, but still useful, since
- /// they deal with std::not_found (not mlc::not_found).
- /// \{
template <typename T>
- struct is_not_found_ : public mlc_is_a(T, stc::not_found)::bexpr
+ struct match_with< stc::final<T> >
{
+ typedef T ret;
};
template <typename T>
- struct is_found_ : public mlc_is_not_a(T, stc::not_found)::bexpr
+ struct match_with
{
+ typedef T ret;
};
- /// \}
- namespace ERROR
+} /* End of namespace find_. */
+
+
+/** Find a virtual type. */
+template <typename source, typename target>
+struct find_vtype
+{
+ typedef typename find_rec<source, target>::ret res;
+ /* Result. */
+ typedef typename find_::match_with<res>::ret ret;
+};
+
+
+/** Find a virtual type, and ensure it is found. */
+template <typename from, typename target>
+struct vtype
+{
+ typedef typename find_vtype<from, target>::ret res;
+ struct check_ : mlc::assert_< mlc::is_found_<res> >
+ {
+ typedef res ret;
+ };
+ typedef typename check_::ret ret;
+};
+
+
+/*------------.
+| Selectors. |
+`------------*/
+
+// FIXME: This part has been copied as-is from Th�o's version
+// (oln/stc/scoop.hxx).
+
+mlc_case_equipment_for_namespace(internal);
+
+
+namespace internal
+{
+
+
+ template < template <class> class abstraction,
+ unsigned num = 1 >
+ struct selector
{
- struct IN_find_VIRTUAL_TYPE_IS_ABSTRACT;
+ protected: selector() {}
+ };
+
+
+ /* fwd decl */
+ template < template <class> class abstraction, typename E, unsigned num >
+ struct plug_node;
+
+ template < template <class> class abstraction,
+ typename E,
+ unsigned num,
+ typename another_selector = mlc::false_ >
+ struct next_plug_node
+ {
+ /* here: no other selector */
+ protected: next_plug_node() {}
+ };
+
+ template < template <class> class abstraction,
+ typename E >
+ struct next_plug_node < abstraction, E, 1, mlc::false_ >
+ : public abstraction<E>
+ {
+ protected: next_plug_node() {}
+ };
+
+
+ template < template <class> class abstraction,
+ typename E,
+ unsigned num >
+ struct next_plug_node < abstraction,
+ E,
+ num,
+ mlc::true_>
+
+ : /* plug to client selectors */
+ public virtual switch_< selector<abstraction, num>, E >::ret,
+
+ /* here: another selector (number is 'num + 1') */
+ public plug_node<abstraction, E, num + 1>
+ {
+ protected: next_plug_node() {}
+ };
+
+
+ template < template <class> class abstraction,
+ typename E,
+ unsigned num >
+ struct plug_node
+ : public next_plug_node< abstraction,
+ E,
+ num,
+ typename mlc::is_defined_< case_< selector<abstraction, num>,
+ E, 1 > >::eval >
+ {
+ protected: plug_node() {}
+ };
+
- struct IN_find_local_VIRTUAL_TYPE_MULTIPLY_DEFINED;
+ template < template <class> class abstraction,
+ unsigned num,
+ typename E >
+ struct default_case_ < selector<abstraction, num>,
+ E >
+ {
+ typedef abstraction<E> ret;
+ };
+
+
+ template < template <class> class abstraction,
+ typename E >
+ struct plug : public plug_node<abstraction, E, 1>
+ {
+ protected: plug() {}
+ };
+
+ template <typename abstraction, typename E>
+ struct top__;
+
+ template <template<class> class abstraction, typename E>
+ struct top__ < stc::is<abstraction>, E > : public plug< abstraction, E
>
+ {
+ protected: top__() {}
+ };
+
+ template <typename E>
+ struct top__ < mlc::none, E > : public Any<E>
+ {
+ protected: top__() {}
+ };
+
+ template <typename E>
+ struct top__ < mlc::not_found, E >; /* FIXME: Error msg here */
+
+
+} /* End of namespace internal. */
+
+
+/*--------------------------------------------.
+| Top class of the implementation hierarchy. |
+`--------------------------------------------*/
+
+// FIXME: This part has been copied as-is from Th�o's version
+// (oln/stc/scoop.hxx).
+
+template <typename E> struct top;
+
+template <typename E>
+struct vtypes< top<E> >
+{
+ typedef stc::final<E> exact;
+ /* default is "no category" */
+};
+
+template <typename E>
+struct top : public internal::top__< stc_find_type(E, category), E >
+{
+protected:
+ top() {}
+};
+
+
+/*----------------------------.
+| Automatic implementations. |
+`----------------------------*/
+
+// FIXME: This part has been copied (almost) as-is from Th�o's version
+// (oln/stc/scoop.hxx).
+
+namespace automatic
+{
+
+ /// set_impl
+ ///
+ /// To be defined by the client.
+ template < template <class> class abstraction, typename behavior,
+ typename E >
+ struct set_impl;
+
+
+ /// impl
+ /// \{
+ template < template <class> class abstraction, typename behavior,
+ typename E >
+ struct impl : public set_impl< abstraction, behavior, E >
+ { /* fetch */ };
+
+ template < template <class> class abstraction, typename E >
+ struct impl< abstraction, /* behavior is */ mlc::not_found, E >
+ { /* nothing */ };
+
+ template < template <class> class abstraction, typename E >
+ struct impl< abstraction, mlc::none /* behavior */, E >
+ { /* nothing */ };
+ /// \}
- struct IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT;
- struct IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL;
- struct IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED;
- struct IN_merge2_VIRTUAL_TYPE_REDEFINED_ABSTRACT;
-
- struct IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT;
- struct IN_merge3_VIRTUAL_TYPE_REDEFINED_ABSTRACT;
- struct IN_merge3_LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT;
- struct IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL;
- struct IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED;
-
- } // end of namespace ERROR
-
-} // end of namespace stc
-
-
-#define stc_super(T) typename set_super_type< T >::ret
-
-// Based on doc/algorithm.ml.
-
-
-
-#define stc_scoop_equipment_for_namespace(SCOOPED_NAMESPACE) \
- \
-namespace SCOOPED_NAMESPACE \
-{ \
- \
- /* Declare delegatee_type. */ \
- mlc_decl_typedef(delegatee_type); \
- \
- \
- template <typename class_name> \
- struct set_super_type \
- { \
- }; \
- \
- template <typename class_name> \
- struct vtypes \
- { \
- }; \
- \
- template <typename class_name, typename type_name> \
- struct single_vtype \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- /* ----------------------------------------------------- find_local. */ \
- \
- /* Highly inspired from Th�o's get_stm! */ \
- \
- namespace find_local_ \
- { \
- /* Forward declaration. */ \
- template <typename T, typename U> struct match_with; \
- \
- template <typename T> \
- struct match_with <T, mlc::not_found> \
- { \
- typedef T ret; \
- }; \
- \
- template <typename U> \
- struct match_with <mlc::not_found, U> \
- { \
- typedef U ret; \
- }; \
- \
- template <> \
- struct match_with <mlc::not_found, mlc::not_found> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename T, typename U> \
- struct match_with : \
- mlc::abort_<T, \
- stc::ERROR::IN_find_local_VIRTUAL_TYPE_MULTIPLY_DEFINED> \
- { \
- }; \
- \
- } /* end of namespace find_local_ */ \
- \
- template <typename source, typename target> \
- struct find_local \
- { \
- typedef SCOOPED_NAMESPACE::vtypes<source> decl1; \
- typedef typename target::template from_<decl1>::ret res1; \
- \
- typedef SCOOPED_NAMESPACE::single_vtype<source, target> decl2; \
- typedef typename decl2::ret ret2; \
- \
- \
- /* Result. */ \
- typedef typename find_local_::match_with<res1, ret2>::ret ret; \
- }; \
- \
- \
- /* --------------------------------------------------------- merge2. */ \
- \
- \
- namespace merge2_ \
- { \
- /* Forward declaration. */ \
- template <typename T, typename U> struct match_with; \
- \
- \
- /* ----------------------------- */ \
- /* local_res == stc::not_found. */ \
- /* ----------------------------- */ \
- \
- stc_internal_match_pair_0p_with(stc::not_found, stc::not_found, \
- stc::not_found); \
- \
- stc_internal_match_pair_0p_with(stc::not_found, stc::abstract, \
- stc::not_found); \
- \
- stc_internal_match_pair_1p_with(U, \
- stc::not_found, stc::final<U>, \
- stc::final<U>); \
- \
- stc_internal_match_pair_1p_with(U, \
- stc::not_found, U, \
- U); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::abstract. */ \
- /* ---------------------------- */ \
- \
- stc_internal_match_pair_0p_with(stc::abstract, stc::not_found, \
- stc::abstract); \
- \
- stc_internal_match_pair_0p_with(stc::abstract, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_pair_1p_with_error(U, \
- stc::abstract, stc::final<U>, \
- stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- stc_internal_match_pair_1p_with_error(U, \
- stc::abstract, U, \
- stc::ERROR::IN_merge2_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::final<T>. */ \
- /* ---------------------------- */ \
- \
- stc_internal_match_pair_1p_with(T, \
- stc::final<T>, stc::not_found, \
- stc::final<T>); \
- \
- stc_internal_match_pair_1p_with(T, \
- stc::final<T>, stc::abstract, \
- stc::final<T>); \
- \
- stc_internal_match_pair_2p_with_error(T, U, \
- stc::final<T>, stc::final<U>, \
- stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL); \
- \
- stc_internal_match_pair_2p_with(T, U, \
- stc::final<T>, U, \
- stc::final<T>); \
- \
- \
- /* ---------------- */ \
- /* local_res == T. */ \
- /* ---------------- */ \
- \
- stc_internal_match_pair_1p_with(T, \
- T, stc::not_found, \
- T); \
- \
- stc_internal_match_pair_1p_with(T, \
- T, stc::abstract, \
- T); \
- \
- stc_internal_match_pair_2p_with_error(T, U, \
- T, stc::final<U>, \
- stc::ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED); \
- \
- template <typename T, typename U> \
- struct match_with \
- { \
- typedef T ret; \
- }; \
- \
- } /* end of namespace merge2_ */ \
- \
- template <typename local_res, typename super_res> \
- struct merge2 \
- { \
- /* Result. */ \
- typedef typename merge2_::match_with<local_res, super_res>::ret ret; \
- }; \
- \
- \
- /* --------------------------------------------------------- merge3. */ \
- \
- \
- namespace merge3_ \
- { \
- /* Forward declaration. */ \
- template <typename T, typename U, typename V> struct match_with; \
- \
- \
- /* ----------------------------- */ \
- /* local_res == stc::not_found. */ \
- /* ----------------------------- */ \
- \
- /* super_res == stc::not_found. */ \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::not_found, stc::not_found, \
- stc::not_found); \
- \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::not_found, stc::abstract, \
- stc::not_found); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::not_found, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::not_found, V, \
- V); \
- \
- /* super_res == stc::abstract. */ \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::abstract, stc::not_found, \
- stc::not_found); \
- \
- stc_internal_match_triple_0p_with( \
- stc::not_found, stc::abstract, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::abstract, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_found, stc::abstract, V, \
- V); \
- \
- /* super_res is a concrete type. */ \
- stc_internal_match_triple_2p_with(U, V, \
- stc::not_found, stc::final<U>, V, \
- stc::final<U>); \
- \
- stc_internal_match_triple_2p_with(U, V, \
- stc::not_found, U, V, \
- U); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::abstract. */ \
- /* ---------------------------- */ \
- \
- /* super_res == stc::not_found. */ \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::not_found, stc::not_found, \
- stc::abstract); \
- \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::not_found, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_found, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_found, V, \
- V); \
- \
- \
- /* super_res == stc::abstract. */ \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::abstract, stc::not_found, \
- stc::abstract); \
- \
- stc_internal_match_triple_0p_with( \
- stc::abstract, stc::abstract, stc::abstract, \
- stc::abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::abstract, stc::final<V>, \
- stc::final<V>); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::abstract, V, \
- V); \
- \
- \
- /* super_res == stc::not_delegated_abstract. */ \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_delegated_abstract, V, \
- stc::not_delegated_abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::abstract, stc::not_delegated, V, \
- stc::not_delegated_abstract); \
- \
- \
- /* super_res is a concrete type. */ \
- stc_internal_match_triple_2p_with_error(U, V, \
- stc::abstract, stc::final<U>, V, \
- stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- stc_internal_match_triple_2p_with_error(U, V, \
- stc::abstract, U, V, \
- stc::ERROR::IN_merge3_VIRTUAL_TYPE_REDEFINED_ABSTRACT); \
- \
- \
- /* --------------------------------- */ \
- /* local_res == stc::not_delegated. */ \
- /* --------------------------------- */ \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_delegated, stc::not_found, V, \
- stc::not_delegated); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_delegated, stc::abstract, V, \
- stc::not_delegated_abstract); \
- \
- stc_internal_match_triple_1p_with(V, \
- stc::not_delegated, stc::not_delegated_abstract, V, \
- stc::not_delegated_abstract); \
- \
- \
- /* ------------------------------------------ */ \
- /* local_res == stc::not_delegated_abstract. */ \
- /* ------------------------------------------ */ \
- \
- /* FIXME: Shouldn't we introduce a means to tag a vtype both as */ \
- /* abstract *and* not delegated? (Currently, the rule below */ \
- /* prevents this). */ \
- stc_internal_match_triple_2p_with_error(U, V, \
- stc::not_delegated_abstract, U, V, \
- stc::ERROR::IN_merge3_LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT); \
- \
- \
- /* ---------------------------- */ \
- /* local_res == stc::final<T>. */ \
- /* ---------------------------- */ \
- \
- stc_internal_match_triple_3p_with_error(T, U, V, \
- stc::final<T>, stc::final<U>, V, \
- stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL); \
- \
- stc_internal_match_triple_3p_with(T, U, V, \
- stc::final<T>, U, V, \
- stc::final<T>); \
- \
- \
- /* ---------------- */ \
- /* local_res == T. */ \
- /* ---------------- */ \
- \
- stc_internal_match_triple_3p_with_error(T, U, V, \
- T, stc::final<U>, V, \
- stc::ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED); \
- \
- template <typename T, typename U, typename V> \
- struct match_with \
- { \
- typedef T ret; \
- }; \
- \
- } /* end of namespace merge3_ */ \
- \
- \
- template <typename local_res, typename super_res, typename delegatee_res> \
- struct merge3 \
- { \
- /* Result. */ \
- typedef typename \
- merge3_::match_with<local_res, super_res, delegatee_res>::ret ret; \
- }; \
- \
- \
- /* ------------------------------------------------------ find_rec. */ \
- \
- /* Forward declarations. */ \
- template <typename source, typename target> struct find_rec; \
- template <typename source, typename target> struct find_rec_in_supers; \
- \
- \
- namespace find_rec_ \
- { \
- \
- namespace find_delegatee_res_ \
- { \
- /* Forward declaration. */ \
- template <typename delegatee, typename target> struct match_with; \
- \
- template <typename target> \
- struct match_with<stc::not_found, target> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename target> \
- struct match_with<stc::abstract, target> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename delegatee, typename target> \
- struct match_with \
- { \
- typedef typename find_rec<delegatee, target>::ret ret; \
- }; \
- \
- } /* end of namespace find_delegatee_res_ */ \
- \
- \
- /* Forward declaration. */ \
- template <typename source, typename target> struct match_with; \
- \
- template <typename target> \
- struct match_with<stc::none, target> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename source, typename target> \
- struct match_with \
- { \
- typedef typename find_local<source, target>::ret local_res; \
- typedef typename find_rec<stc_super(source), target>::ret super_res; \
- /* delegatee_type is the name of the (optional) virtual type */ \
- /* containing the (type of the) delgatee. */ \
- typedef typename \
- find_rec_in_supers<source, typedef_::delegatee_type>::ret delegatee; \
- \
- typedef typename \
- find_delegatee_res_::match_with<delegatee, target>::ret delegatee_res; \
- typedef typename \
- merge3<local_res, super_res, delegatee_res>::ret ret; \
- }; \
- \
- } /* end of namespace find_rec_ */ \
- \
- template <typename source, typename target> \
- struct find_rec \
- { \
- /* Result. */ \
- typedef typename find_rec_::match_with<source, target>::ret ret; \
- }; \
- \
- \
- /* --------------------------------------------- find_rec_in_supers. */ \
- \
- namespace find_rec_in_supers_ \
- { \
- /* Forward declaration. */ \
- template <typename source, typename target> struct match_with; \
- \
- template <typename target> \
- struct match_with<stc::none, target> \
- { \
- typedef stc::none ret; \
- }; \
- \
- template <typename source, typename target> \
- struct match_with \
- { \
- typedef typename find_local<source, target>::ret local_res; \
- typedef typename find_rec<stc_super(source), target>::ret super_res; \
- typedef typename merge2<local_res, super_res>::ret ret; \
- }; \
- \
- } /* end of namespace find_rec_in_supers_ */ \
- \
- template <typename source, typename target> \
- struct find_rec_in_supers \
- { \
- /* Result. */ \
- typedef typename \
- find_rec_in_supers_::match_with<source, target>::ret ret; \
- }; \
- \
- \
- /* ----------------------------------------------------------- find. */ \
- \
- namespace find_ \
- { \
- /* Forward declaration. */ \
- template <typename T> struct match_with; \
- \
- /* FIXME: We'd like to add a static abort here, but we can't, */ \
- /* since stc::abstract is not a free parameter (enabling this */ \
- /* abort statement would prevent any compilation). */ \
- template <> \
- struct match_with<stc::abstract> \
- /* : mlc::abort_<stc::abstract, \
- stc::ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT> */ \
- { \
- }; \
- \
- /* FIXME: We'd like to add a static abort here, but we can't, */ \
- /* since stc::not_delegated_abstract is not a free parameter */ \
- /* (enabling this abort statement would prevent any */ \
- /* compilation). */ \
- template <> \
- struct match_with<stc::not_delegated_abstract> \
- /* : mlc::abort_<stc::not_delegated_abstract, */ \
- /* stc::ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT> */ \
- { \
- }; \
- \
- template <> \
- struct match_with<stc::not_delegated> \
- { \
- typedef stc::not_found ret; \
- }; \
- \
- template <typename T> \
- struct match_with< stc::final<T> > \
- { \
- typedef T ret; \
- }; \
- \
- template <typename T> \
- struct match_with \
- { \
- typedef T ret; \
- }; \
- \
- } /* end of namespace find_ */ \
- \
- \
- /** Find a virtual type. */ \
- template <typename source, typename target> \
- struct find_vtype \
- { \
- typedef typename find_rec<source, target>::ret res; \
- /* Result. */ \
- typedef typename find_::match_with<res>::ret ret; \
- }; \
- \
- \
- /** Find a virtual type, and ensure it is found. */ \
- template <typename from, typename target> \
- struct vtype \
- { \
- typedef typename find_vtype<from, target>::ret res; \
- struct check_ : mlc::assert_< mlc::is_found_<res> > \
- { \
- typedef res ret; \
- }; \
- typedef typename check_::ret ret; \
- }; \
- \
-} /* end of SCOOPED_NAMESPACE */ \
- \
-struct e_n_d___w_i_t_h___s_e_m_i_c_o_l_o_n;
-
-
-/*------------------.
-| Shortcuts macro. |
-`------------------*/
-
-// FIXME: Document all these macros.
-
-# define stc_find_vtype_(Namespace, Source, Target) \
- Namespace::find_vtype<Source, Namespace::typedef_::Target##_type>::ret
-
-# define stc_find_vtype(Namespace, Source, Target) \
- typename stc_find_vtype_(Namespace, Source, Target)
-
-// Dummy alias, for compatibility purpose (deferred virtual types are
-// not currently handled by this version of stc/scoop2.hh).
-# define stc_deferred_vtype(Namespace, From, Target) \
- stc_find_vtype(Namespace, From, Target)
-
-# define stc_vtype_(Namespace, From, Target) \
- Namespace::vtype<From, Namespace::typedef_::Target##_type>::ret
-
-# define stc_vtype(Namespace, From, Target) \
- typename stc_vtype_(Namespace, From, Target)
-
-# define stc_find_deduce_vtype_(Namespace, From, Target1, Target2) \
- Namespace::find_vtype< \
- Namespace::find_vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
-
-# define stc_find_deduce_vtype(Namespace, From, Target1, Target2) \
- typename Namespace::find_vtype< \
- typename Namespace::find_vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
-
-# define stc_deduce_deferred_vtype(Namespace, From, Target1, Target2) \
- stc_find_deduce_vtype(Namespace, From, Target1, Target2)
-
-# define stc_deduce_vtype_(Namespace, From, Target1, Target2) \
- Namespace::vtype< \
- Namespace::vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
-
-# define stc_deduce_vtype(Namespace, From, Target1, Target2) \
- typename Namespace::vtype< \
- typename Namespace::vtype< \
- From, \
- Namespace::typedef_::Target1##_type \
- >::ret, \
- Namespace::typedef_::Target2##_type \
- >::ret
+ /// get_impl
+ template < template <class> class abstraction, typename E >
+ struct get_impl : impl< abstraction, stc_find_type(E, behavior), E >
+ { /* depends upon behavior */ };
-#endif // ! STC_SCOOP_ALT_HH
+} // End of namespace automatic.