https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog
from Roland Levillain <roland(a)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_type<ex1::A> { typedef stc::none ret; };
+
+ /// Virtual types associated to A.
+ template <>
+ struct vtypes<ex1::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_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; };
+
+ /// Virtual types associated to A.
+ template <>
+ struct vtypes<ex2::A>
+ {
+ typedef int my_type;
+ };
+
+ /// Virtual types associated to B.
+ template <>
+ struct vtypes<ex2::B>
+ {
+ typedef float my_type;
+ };
+
+ /// Virtual types associated to C.
+ template <>
+ struct vtypes<ex2::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_type<ex3::A> { typedef stc::none ret; };
+ template <> struct set_super_type<ex3::B> { typedef ex3::A ret; };
+
+ /// Virtual types associated to A.
+ template <>
+ struct vtypes<ex3::A>
+ {
+ typedef stc::abstract my_type;
+ };
+
+ /// Virtual types associated to B.
+ template <>
+ struct vtypes<ex3::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_type<ex4::A> { typedef stc::none ret; };
+
+ /// Virtual types associated to A.
+ template <>
+ struct vtypes<ex4::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_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; };
+
+ /// Virtual types associated to A.
+ template <>
+ struct vtypes<ex5::A>
+ {
+ };
+
+ /// Virtual types associated to D.
+ template <>
+ struct vtypes<ex5::D>
+ {
+ typedef stc::abstract my_type;
+ };
+
+ /// Virtual types associated to C.
+ template <>
+ struct vtypes<ex5::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_type<ex6::A> { typedef stc::none ret; };
+ template <> struct set_super_type<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 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; };
+
+ /// Virtual types associated to A.
+ template <>
+ struct vtypes<ex6::A>
+ {
+ };
+
+ /// Virtual types associated to B.
+ template <>
+ struct vtypes<ex6::B>
+ {
+ typedef stc::abstract foo_type;
+ };
+
+ /// Virtual types associated to X.
+ template <>
+ struct vtypes<ex6::X>
+ {
+ typedef stc::abstract bar_type;
+ typedef int hop_type;
+ };
+
+ /// Virtual types associated to Y.
+ template <>
+ struct vtypes<ex6::Y>
+ {
+ typedef short baz_type;
+ typedef char bar_type;
+ };
+
+ /// 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;
+ };
+
+ /// Virtual types associated to D.
+ template <>
+ struct vtypes<ex6::D>
+ {
+ typedef unsigned quux_type;
+ };
+
+ /// Virtual types associated to E.
+ template <>
+ struct vtypes<ex6::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_type<ex7::abstract::image_entry>
+ {
+ typedef stc::none ret;
+ };
+ template <>
+ struct set_super_type<ex7::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 vtypes<ex7::abstract::image_entry>
+ {
+ typedef stc::abstract value_type;
+ };
+
+ /// 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;
+ };
+
+ /// 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_with<stc::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_with<stc::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_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_
+
+ 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