https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog from Roland Levillain roland@lrde.epita.fr
New prototype for SCOOP 2 algorithms.
* stc/scoop2.hh: New (prototype). * tests/scoop2.cc: New test. * stc/Makefile.am (nobase_stc_HEADERS): Add scoop2.hh * tests/Makefile.am (check_PROGRAMS): Add scoop2. (scoop2_SOURCES): New.
stc/Makefile.am | 4 stc/scoop2.hh | 689 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/Makefile.am | 7 tests/scoop2.cc | 657 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1355 insertions(+), 2 deletions(-)
Index: tests/Makefile.am --- tests/Makefile.am (revision 717) +++ tests/Makefile.am (working copy) @@ -21,7 +21,10 @@ vtypes \ vtypes-and-exact \ \ - tour + tour \ + \ + scoop2 +
any_SOURCES = any.cc entry_SOURCES = entry.cc @@ -33,6 +36,8 @@
tour_SOURCES = tour.cc
+scoop2_SOURCES = scoop2.cc + # Old tests. EXTRA_DIST = multiple-supers.cc vtypes-multiple-supers.cc
Index: tests/scoop2.cc --- tests/scoop2.cc (revision 0) +++ tests/scoop2.cc (revision 0) @@ -0,0 +1,657 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + + +/// This test focuses on the virtual types system, so the exact type of +/// classes is not propagated here (stc::any is not used). + +/// These examples comes from doc/algorithm.ml. + + +#include <mlc/cmp.hh> +#include <mlc/assert.hh> + +#include <stc/scoop2.hh> + +/* FIXME: To be enabled later, when the contents of stc/scoop2.hh is + enclosed in a macro. */ +#if 0 +// Namespace equipment. +stc_scoop_equipment_for_namespace(my); +#endif + +// FIXME: Check single_vtype, too. + +namespace my +{ + // ------------------------------------------------------------ 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(value_type); + + + + /* ---------------------------------------------------------------- Ex 1. + + ** Virtual type definition + + Ex. + + class A < stc::none = + { + vtype my_type = int; + } + */ + + namespace ex1 + { + // Forward declaration. + struct A; + } + + // Set super type. + template <> struct set_super_typeex1::A { typedef stc::none ret; }; + + /// Virtual types associated to A. + template <> + struct vtypesex1::A + { + typedef int my_type; + }; + + namespace ex1 + { + struct A : public stc::none {}; + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex1::A, my), int) + >::check(); + } + } + + /* ---------------------------------------------------------------- Ex 2. + + ** Virtual type re-definition. + + Ex. + + class A < stc::none = + { + vtype my_type = int; + } + // Valid. + class B < A = + { + vtype my_type = float; + } + // Valid. + class C < A = + { + vtype my_type = int; + } + */ + + namespace ex2 + { + // Forward declarations. + struct A; + struct B; + struct C; + } + + // Set super types. + template <> struct set_super_typeex2::A { typedef stc::none ret; }; + template <> struct set_super_typeex2::B { typedef ex2::A ret; }; + template <> struct set_super_typeex2::C { typedef ex2::B ret; }; + + /// Virtual types associated to A. + template <> + struct vtypesex2::A + { + typedef int my_type; + }; + + /// Virtual types associated to B. + template <> + struct vtypesex2::B + { + typedef float my_type; + }; + + /// Virtual types associated to C. + template <> + struct vtypesex2::C + { + typedef int my_type; + }; + + namespace ex2 + { + struct A : public stc::none {}; + struct B : public A {}; + struct C : public B {}; + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex2::A, my), int) + >::check(); + + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex2::B, my), float) + >::check(); + + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex2::C, my), int) + >::check(); + } + } + + + /* ---------------------------------------------------------------- Ex 3. + + ** Virtual type abstract declaration (i.e., deferred definition). + + Ex.: + + class A < stc::none = + { + // my_type is abstract. + vtype my_type = 0; + } + class B < A = + { + vtype my_type = int; + } + */ + + namespace ex3 + { + // Forward declarations. + struct A; + struct B; + } + + // Set super types. + template <> struct set_super_typeex3::A { typedef stc::none ret; }; + template <> struct set_super_typeex3::B { typedef ex3::A ret; }; + + /// Virtual types associated to A. + template <> + struct vtypesex3::A + { + typedef stc::abstract my_type; + }; + + /// Virtual types associated to B. + template <> + struct vtypesex3::B + { + typedef int my_type; + }; + + namespace ex3 + { + struct A : public stc::none {}; + struct B : public A {}; + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex3::B, my), int) + >::check(); + } + } + + + /* ---------------------------------------------------------------- Ex 4. + + ** Final virtual type + + - A virtual type can be tagged as final. + + Ex.: + + class A < stc::none = + { + final vtype my_type = int; + } + */ + + namespace ex4 + { + // Forward declaration. + struct A; + } + + // Set super type. + template <> struct set_super_typeex4::A { typedef stc::none ret; }; + + /// Virtual types associated to A. + template <> + struct vtypesex4::A + { + typedef stc::final<int> my_type; + }; + + namespace ex4 + { + struct A : public stc::none {}; + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex4::A, my), int) + >::check(); + } + } + + + /* ---------------------------------------------------------------- Ex 5. + + ** General virtual type lookup (i.e., with delegation) + + *** Abstract + + class A < stc::none + { + // my_vtype not defined. + } + + class D < stc::none + { + vtype my_type = 0; + } + + // A + // ^ + // | + // C<>--D + class C < stc::none + { + vtype delegatee_type = D; + } + + type t = C#my_type; + */ + + namespace ex5 + { + // Forward declarations. + struct A; + struct D; + struct C; + } + + // Set super types. + template <> struct set_super_typeex5::A { typedef stc::none ret; }; + template <> struct set_super_typeex5::D { typedef stc::none ret; }; + template <> struct set_super_typeex5::C { typedef ex5::A ret; }; + + /// Virtual types associated to A. + template <> + struct vtypesex5::A + { + }; + + /// Virtual types associated to D. + template <> + struct vtypesex5::D + { + typedef stc::abstract my_type; + }; + + /// Virtual types associated to C. + template <> + struct vtypesex5::C + { + typedef ex5::D delegatee_type; + }; + + namespace ex5 + { + struct A : public stc::none {}; + struct D : public stc::none {}; + struct C : public A {}; + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex5::C, my), stc::not_found) + >::check(); + } + } + + + /* ---------------------------------------------------------------- Ex 6. + + * More examples. + + ** A complex example, with stc::not_delegated. + + A + ^ + | X + B ^ + ^ | + | Y + C<>-� + ^ + | + D + ^ + | + E + + + class A < stc::none | class C < B + { | { + } | vtype delegatee_type = Y; + class B < A | vtype foo = int; + { | vtype baz = not_delegated; + vtype foo = 0; | vtype hop = not_delegated; + } | } + | class D < C + class X < stc::none | { + { | vtype quux = unsigned; + vtype bar = 0; | } + vtype hop = int; | class E < D + } | { + class Y < X | vtype baz = float; + { | } + vtype baz = short; | + vtype bar = char; | + } | + */ + + namespace ex6 + { + // Forward declarations. + struct A; + struct B; + + struct X; + struct Y; + + struct C; + struct D; + struct E; + } + + // Set super types. + template <> struct set_super_typeex6::A { typedef stc::none ret; }; + template <> struct set_super_typeex6::B { typedef ex6::A ret; }; + + template <> struct set_super_typeex6::X { typedef stc::none ret; }; + template <> struct set_super_typeex6::Y { typedef ex6::X ret; }; + + template <> struct set_super_typeex6::C { typedef ex6::B ret; }; + template <> struct set_super_typeex6::D { typedef ex6::C ret; }; + template <> struct set_super_typeex6::E { typedef ex6::D ret; }; + + /// Virtual types associated to A. + template <> + struct vtypesex6::A + { + }; + + /// Virtual types associated to B. + template <> + struct vtypesex6::B + { + typedef stc::abstract foo_type; + }; + + /// Virtual types associated to X. + template <> + struct vtypesex6::X + { + typedef stc::abstract bar_type; + typedef int hop_type; + }; + + /// Virtual types associated to Y. + template <> + struct vtypesex6::Y + { + typedef short baz_type; + typedef char bar_type; + }; + + /// Virtual types associated to C. + template <> + struct vtypesex6::C + { + typedef ex6::Y delegatee_type; + typedef int foo_type; + typedef stc::not_delegated baz_type; + typedef stc::not_delegated hop_type; + }; + + /// Virtual types associated to D. + template <> + struct vtypesex6::D + { + typedef unsigned quux_type; + }; + + /// Virtual types associated to E. + template <> + struct vtypesex6::E + { + typedef float baz_type; + }; + + namespace ex6 + { + struct A : public stc::none {}; + struct B : public A {}; + + struct X : public stc::none {}; + struct Y : public X {}; + + struct C : public B {}; + struct D : public C {}; + struct E : public D {}; + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex6::E, foo), int) + >::check(); + + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex6::E, bar), char) + >::check(); + + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex6::E, baz), float) + >::check(); + + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex6::E, quux), unsigned) + >::check(); + + mlc::assert_< + mlc_eq(stc_find_vtype_(my, my::ex6::E, hop), stc::not_found) + >::check(); + } + } + + + /* ---------------------------------------------------------------- Ex 7. + + *** Olena-like examples. + + class /image_entry/ < stc::none + { + vtype value_type = 0; + } + + class image2d<int> < image_entry + { + vtypes value_type = int; + } + + class /value_morpher/ < image_entry + { + vtype delegatee_type = 0; + vtype value_type = stc::not_delegated; + } + + class value_cast<image2d<int>, float> < value_morpher + { + vtype delegatee_type = image2d<int>; + vtype value_type = float; + } + */ + + namespace ex7 + { + // Forward declarations. + namespace abstract + { + struct image_entry; + struct value_morpher; + } + + template <typename T> struct image2d; + template <typename I, typename T> struct value_cast; + } + + // Set super types. + template <> + struct set_super_typeex7::abstract::image_entry + { + typedef stc::none ret; + }; + template <> + struct set_super_typeex7::abstract::value_morpher + { + typedef ex7::abstract::image_entry ret; + }; + template <typename T> + struct set_super_type< ex7::image2d<T> > + { + typedef ex7::abstract::image_entry ret; + }; + template <typename I, typename T> + struct set_super_type< ex7::value_cast<I, T> > + { + typedef ex7::abstract::value_morpher ret; + }; + + + /// Virtual types associated to abstract::image_entry. + template <> + struct vtypesex7::abstract::image_entry + { + typedef stc::abstract value_type; + }; + + /// Virtual types associated to abstract::value_morpher. + template <> + struct vtypesex7::abstract::value_morpher + { + typedef stc::abstract delegatee_type; + typedef stc::not_delegated value_type; + }; + + /// Virtual types associated to image2d<T>. + template <typename T> + struct vtypes< ex7::image2d<T> > + { + typedef T value_type; + }; + + /// 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; + }; + + + namespace ex7 + { + namespace abstract + { + struct image_entry : public stc::none {}; + struct value_morpher : public image_entry {}; + } + + template <typename T> + struct image2d : public abstract::image_entry {}; + + template <typename I, typename T> + struct value_cast : public abstract::value_morpher {}; + + + void + check() + { + mlc::assert_< + mlc_eq(stc_find_vtype_(my, 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) + >::check(); + } + } + +} // end of namespace my + + +int +main() +{ + my::ex1::check(); + my::ex2::check(); + my::ex3::check(); + my::ex4::check(); + my::ex5::check(); + my::ex6::check(); + my::ex7::check(); +} Index: stc/scoop2.hh --- stc/scoop2.hh (revision 0) +++ stc/scoop2.hh (revision 0) @@ -0,0 +1,689 @@ +// Copyright (C) 2005, 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/* \file stc/vtypes.hh + + \brief Equipment for SCOOP 2 (in particular, virtual types). */ + +#ifndef STC_SCOOP2_HH +# define STC_SCOOP2_HH + +# include <mlc/flags.hh> +# include <mlc/typedef.hh> +# include <mlc/abort.hh> + + +namespace stc +{ + + struct none {}; + struct not_found; + struct abstract; + struct not_delegated; + struct not_delegated_abstract; + template <typename T> struct final; + + namespace ERROR + { + struct IN_find__VIRTUAL_TYPE_IS_ABSTRACT; + + struct IN_find_local__VIRTUAL_TYPE_MULTIPLY_DEFINED; + + 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. + +// FIXME: Hack. +#define SCOOPED_NAMESPACE my + + +// ------------------------------------------------------------ find_local. + +// Highly inspired from Th�o's get_stm! + +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; + }; + + 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; + + + // super_res == stc::not_found. + template <> + struct match_with<stc::abstract, stc::not_found> + { + typedef stc::abstract ret; + }; + template <> + struct match_with<stc::not_found, stc::not_found> + { + typedef stc::not_found ret; + }; + template <typename T> + struct match_with<stc::final<T>, stc::not_found> + { + typedef stc::final<T> ret; + }; + + template <typename T> + struct match_with<T, stc::not_found> + { + typedef T ret; + }; + + + // super_res == stc::abstract. + template <> + struct match_with<stc::not_found, stc::abstract> + { + typedef stc::not_found ret; + }; + + template <> + struct match_with<stc::abstract, stc::abstract> + { + typedef stc::abstract ret; + }; + + template <typename T> + struct match_with<stc::final<T>, stc::abstract> + { + typedef stc::final<T> ret; + }; + + template <typename T> + struct match_with<T, stc::abstract> + { + typedef T ret; + }; + + + // super_res == stc::final<U>. + template <typename U> + struct match_with<stc::abstract, stc::final<U> > : + mlc::abort_<U, stc::ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT> + { + }; + + template <typename U> + struct match_with<stc::not_found, stc::final<U> > + { + typedef stc::final<U> ret; + }; + + template <typename T, typename U> + struct match_with<stc::final<T>, stc::final<U> > : + mlc::abort_<U, stc::ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED_FINAL> + { + }; + + template <typename T, typename U> + struct match_with<T, stc::final<U> > : + mlc::abort_<U, stc::ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED> + { + }; + + + // super_res == U. + template <typename U> + struct match_with<stc::abstract, U> : + mlc::abort_<U, stc::ERROR::IN_merge2__VIRTUAL_TYPE_REDEFINED_ABSTRACT> + { + }; + + template <typename U> + struct match_with<stc::not_found, U> + { + typedef U ret; + }; + + template <typename T, typename U> + struct match_with<stc::final<T>, U> + { + typedef stc::final<T> ret; + }; + + 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. + + // FIXME: Undef these macros after the definition of merge3. + +#define stc_match_0p_with(Local, Super, Deleg, Res) \ + template <> \ + struct match_with< Local, Super, Deleg > \ + { \ + typedef Res ret; \ + } + +#define stc_match_1p_with(T1, Local, Super, Deleg, Res) \ + template <typename T1> \ + struct match_with< Local, Super, Deleg > \ + { \ + typedef Res ret; \ + } + +#define stc_match_2p_with(T1, T2, Local, Super, Deleg, Res) \ + template <typename T1, typename T2> \ + struct match_with< Local, Super, Deleg > \ + { \ + typedef Res ret; \ + } + +#define stc_match_3p_with(T1, T2, T3, Local, Super, Deleg, Res) \ + template <typename T1, typename T2, typename T3> \ + struct match_with< Local, Super, Deleg > \ + { \ + typedef Res ret; \ + } + + // FIXME: Example of use. + // stc_match_with(stc::not_found, stc::not_found, stc::not_found, stc::not_found); + + namespace merge3_ + { + // Forward declaration. + template <typename T, typename U, typename V> struct match_with; + + + // local_res == stc::not_found. + template <> + struct match_with<stc::not_found, stc::not_found, stc::not_found> + { + typedef stc::not_found ret; + }; + + template <> + struct match_with<stc::not_found, stc::not_found, stc::abstract> + { + typedef stc::not_found ret; + }; + + template <typename V> + struct match_with<stc::not_found, stc::not_found, stc::final<V> > + { + typedef stc::final<V> ret; + }; + + template <typename V> + struct match_with<stc::not_found, stc::not_found, V> + { + typedef V ret; + }; + + + template <> + struct match_with<stc::not_found, stc::abstract, stc::not_found> + { + typedef stc::not_found ret; + }; + + template <> + struct match_with<stc::not_found, stc::abstract, stc::abstract> + { + typedef stc::abstract ret; + }; + + template <typename V> + struct match_with<stc::not_found, stc::abstract, stc::final<V> > + { + typedef stc::final<V> ret; + }; + + template <typename V> + struct match_with<stc::not_found, stc::abstract, V> + { + typedef V ret; + }; + + + template <typename U, typename V> + struct match_with<stc::not_found, stc::final<U>, V> + { + typedef stc::final<U> ret; + }; + + template <typename U, typename V> + struct match_with<stc::not_found, U, V> + { + typedef U ret; + }; + + + // local_res == stc::abstract. + template <> + struct match_with<stc::abstract, stc::not_found, stc::not_found> + { + typedef stc::abstract ret; + }; + + template <> + struct match_with<stc::abstract, stc::not_found, stc::abstract> + { + typedef stc::abstract ret; + }; + + template <typename V> + struct match_with<stc::abstract, stc::not_found, stc::final<V> > + { + typedef stc::final<V> ret; + }; + + template <typename V> + struct match_with<stc::abstract, stc::not_found, V > + { + typedef V ret; + }; + + + template <> + struct match_with<stc::abstract, stc::abstract, stc::not_found> + { + typedef stc::abstract ret; + }; + + template <> + struct match_with<stc::abstract, stc::abstract, stc::abstract> + { + typedef stc::abstract ret; + }; + + template <typename V> + struct match_with<stc::abstract, stc::abstract, stc::final<V> > + { + typedef stc::final<V> ret; + }; + + template <typename V> + struct match_with<stc::abstract, stc::abstract, V> + { + typedef V ret; + }; + + + template <typename V> + struct match_with<stc::abstract, stc::not_delegated_abstract, V> + { + typedef stc::not_delegated_abstract ret; + }; + + template <typename V> + struct match_with<stc::abstract, stc::not_delegated, V> + { + typedef stc::not_delegated_abstract ret; + }; + + + template <typename U, typename V> + struct match_with<stc::abstract, stc::final<U>, V> : + mlc::abort_<V, stc::ERROR::IN_merge3__FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT> + { + }; + + template <typename U, typename V> + struct match_with<stc::abstract, U, V> : + mlc::abort_<V, stc::ERROR::IN_merge3__VIRTUAL_TYPE_REDEFINED_ABSTRACT> + { + }; + + + // local_res == stc::not_delegated. + template <typename V> + struct match_with<stc::not_delegated, stc::not_found, V> + { + typedef stc::not_delegated ret; + }; + + template <typename V> + struct match_with<stc::not_delegated, stc::abstract, V> + { + typedef stc::not_delegated_abstract ret; + }; + + template <typename V> + struct match_with<stc::not_delegated, stc::not_delegated_abstract, V> + { + typedef stc::not_delegated_abstract ret; + }; + + + // 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). */ + template <typename U, typename V> + struct match_with<stc::not_delegated_abstract, U, V> : + mlc::abort_<V, stc::ERROR::IN_merge3__LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT> + { + }; + + + // local_res == stc::final<T>. + template <typename T, typename U, typename V> + struct match_with<stc::final<T>, stc::final<U>, V> : + mlc::abort_<V, stc::ERROR::IN_merge3__FINAL_VIRTUAL_TYPE_REDEFINED_FINAL> + { + }; + + template <typename T, typename U, typename V> + struct match_with<stc::final<T>, U, V> + { + typedef stc::final<T> ret; + }; + + + // local_res == T. + template <typename T, typename U, typename V> + struct match_with<T, stc::final<U>, V> : + mlc::abort_<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; + + template <> + struct match_withstc::abstract +/* 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). */ +#if 0 + : mlc::abort_<stc::abstract, + stc::ERROR::IN_find__VIRTUAL_TYPE_IS_ABSTRACT> +#endif + { + }; + + template <> + struct match_withstc::not_delegated_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). */ +#if 0 + : mlc::abort_<stc::not_delegated_abstract, + stc::ERROR::IN_find__VIRTUAL_TYPE_IS_ABSTRACT> +#endif + { + }; + + template <> + struct match_withstc::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_ + + template <typename source, typename target> + struct find + { + typedef typename find_rec<source, target>::ret res; + // Result. + typedef typename find_::match_with<res>::ret ret; + }; + +} /* end of SCOOPED_NAMESPACE */ + + +# define stc_find_vtype_(Namespace, Source, Target) \ + Namespace::find<Source, Namespace::typedef_::Target##_type>::ret + +# define stc_find_vtype(Namespace, Source, Target) \ + typename stc_find_vtype_(Namespace, Source, Target) + +#endif // ! STC_SCOOP2_HH Index: stc/Makefile.am --- stc/Makefile.am (revision 717) +++ stc/Makefile.am (working copy) @@ -9,7 +9,9 @@ scoop.hh \ valist_aggregator.hh \ \ - internal/extract_vtype_from_list.hh + internal/extract_vtype_from_list.hh \ + \ + scoop2.hh
# Old code. EXTRA_DIST = was.scoop.hh