878: Update SCOOP 2 alternative implementation.

https://svn.lrde.epita.fr/svn/oln/trunk/static Index: ChangeLog from Roland Levillain <roland@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.
participants (1)
-
Roland Levillain