https://svn.lrde.epita.fr/svn/oln/trunk/static
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Rename stc/scoop2.hh as stc/scoop-alt.hh.
Encapsulate the contents of SCOOPED_NAMESPACE in
stc_scoop_equipment_for_namespace.
* stc/scoop2.hh: Rename as...
* stc/scoop-alt.hh: ...this.
Adjust header guards.
(ERROR::IN_find__VIRTUAL_TYPE_IS_ABSTRACT)
(ERROR::IN_find_local__VIRTUAL_TYPE_MULTIPLY_DEFINED)
(ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED_FINAL)
(ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED)
(ERROR::IN_merge2__VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge3__FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge3__VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge3__LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT)
(ERROR::IN_merge3__FINAL_VIRTUAL_TYPE_REDEFINED_FINAL)
(ERROR::IN_merge3__FINAL_VIRTUAL_TYPE_REDEFINED): Rename as...
(ERROR::IN_find_VIRTUAL_TYPE_IS_ABSTRACT)
(ERROR::IN_find_local_VIRTUAL_TYPE_MULTIPLY_DEFINED)
(ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL)
(ERROR::IN_merge2_FINAL_VIRTUAL_TYPE_REDEFINED)
(ERROR::IN_merge2_VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge3_VIRTUAL_TYPE_REDEFINED_ABSTRACT)
(ERROR::IN_merge3_LOCAL_DECLARATION_OF_NOT_DELEGATED_AND_ABSTRACT)
(ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED_FINAL)
(ERROR::IN_merge3_FINAL_VIRTUAL_TYPE_REDEFINED): ...these.
(SCOOPED_NAMESPACE): Remove macro.
(stc_scoop_equipment_for_namespace): New macro.
Encapsulate the contents of SCOOPED_NAMESPACE within this macro.
(stc_match_pair_0p_with, stc_match_pair_1p_with)
(stc_match_pair_2p_with, stc_match_pair_1p_with_error)
(stc_match_pair_2p_with_error)
(stc_match_triple_0p_with, stc_match_triple_1p_with)
(stc_match_triple_2p_with, stc_match_triple_3p_with)
(stc_match_triple_2p_with_error, stc_match_triple_3p_with_error):
Move and rename these macros as..
* stc/internal/match-with.hh (stc_internal_match_pair_0p_with)
(stc_internal_match_pair_1p_with, stc_internal_match_pair_2p_with)
(stc_internal_match_pair_1p_with_error)
(stc_internal_match_pair_2p_with_error)
(stc_internal_match_triple_0p_with)
(stc_internal_match_triple_1p_with)
(stc_internal_match_triple_2p_with)
(stc_internal_match_triple_3p_with)
(stc_internal_match_triple_2p_with_error)
(stc_internal_match_triple_3p_with_error): ...these (new file).
* stc/Makefile (nobase_stc_HEADERS): Remove scoop2.hh.
Add scoop-alt.hh and internal/match-with.hh.
* tests/scoop2.cc: Rename as...
* tests/scoop-alt.cc: ...this.
Adjust.
(stc_scoop_equipment_for_namespace): Invoke it.
* tests/super.cc (my::set_pseudosuper_type<C>): Remove.
(my::vtypes<C>::delegatee_type): New.
* tests/Makefile.am (nobase_stc_HEADERS): Add
internal/match-with.hh.
(scoop2_SOURCES): Remove.
(scoop_alt_SOURCES): New.
stc/Makefile.am | 4
stc/internal/match-with.hh | 128 ++++
stc/scoop-alt.hh | 1199 +++++++++++++++++++++------------------------
tests/Makefile.am | 4
tests/scoop-alt.cc | 7
tests/super.cc | 6
6 files changed, 699 insertions(+), 649 deletions(-)
Index: tests/super.cc
--- tests/super.cc (revision 725)
+++ tests/super.cc (working copy)
@@ -80,11 +80,11 @@
simple test, but it doesn't matter: we are only checking the
super relationship here. */
- /// Link to B (``pseudo'' inheritance).
+ /// Delegation to B (used to be called ``pseudo'' inheritance).
template<>
- struct set_pseudosuper_type<C>
+ struct vtypes<C>
{
- typedef B ret;
+ typedef B delegatee_type;
};
struct C // no inheritance
Index: tests/scoop-alt.cc
--- tests/scoop-alt.cc (revision 724)
+++ tests/scoop-alt.cc (working copy)
@@ -35,14 +35,11 @@
#include <mlc/cmp.hh>
#include <mlc/assert.hh>
-#include <stc/scoop2.hh>
+#include <stc/scoop-alt.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.
Index: tests/Makefile.am
--- tests/Makefile.am (revision 725)
+++ tests/Makefile.am (working copy)
@@ -23,7 +23,7 @@
\
tour \
\
- scoop2
+ scoop-alt
any_SOURCES = any.cc
@@ -36,7 +36,7 @@
tour_SOURCES = tour.cc
-scoop2_SOURCES = scoop2.cc
+scoop_alt_SOURCES = scoop-alt.cc
# Old tests.
EXTRA_DIST = multiple-supers.cc vtypes-multiple-supers.cc
Index: stc/scoop-alt.hh
--- stc/scoop-alt.hh (revision 724)
+++ stc/scoop-alt.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2005, 2006 EPITA Research and Development Laboratory
+// Copyright (C) 2005, 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
@@ -25,23 +25,28 @@
// 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). */
+/* \file stc/scoop-alt.hh
-#ifndef STC_SCOOP2_HH
-# define STC_SCOOP2_HH
+ \brief Alternative equipment for SCOOP 2 (in particular, virtual
+ types). */
+
+
+#ifndef STC_SCOOP_ALT_HH
+# define STC_SCOOP_ALT_HH
# include <mlc/flags.hh>
# include <mlc/typedef.hh>
# include <mlc/abort.hh>
+# include <stc/internal/match-with.hh>
+
namespace stc
{
/* 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 paradigme (see stc/scoop.hh), we
+ 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 {};
@@ -73,20 +78,20 @@
namespace ERROR
{
- struct IN_find__VIRTUAL_TYPE_IS_ABSTRACT;
+ struct IN_find_VIRTUAL_TYPE_IS_ABSTRACT;
- struct IN_find_local__VIRTUAL_TYPE_MULTIPLY_DEFINED;
+ 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;
+ 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
@@ -97,631 +102,551 @@
// Based on doc/algorithm.ml.
-// FIXME: Temp. hack. The contents of SCOOPED_NAMESPACE will be
-// available later as a macro, as in stc/scoop.hh. Currently, it's
-// easier to work without this macro equipment.
-#define SCOOPED_NAMESPACE oln
-
-
-// ------------------------------------------------------------ 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.
-
-// Shortcuts macros.
-#define stc_match_pair_0p_with(Local, Super, Res) \
+#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< Local, Super > \
- { \
- typedef Res ret; \
- }
-
-#define stc_match_pair_1p_with(T1, Local, Super, Res) \
- template < typename T1 > \
- struct match_with< Local, Super > \
- { \
- typedef Res ret; \
- }
-
-#define stc_match_pair_2p_with(T1, T2, Local, Super, Res) \
- template < typename T1, typename T2 > \
- struct match_with< Local, Super > \
- { \
- typedef Res ret; \
- }
-
-// Erroneous cases.
-#define stc_match_pair_1p_with_error(T1, Local, Super, Msg) \
- template < typename T1 > \
- struct match_with< Local, Super > : \
- mlc::abort_< T1, Msg > \
- { \
- }
-
-#define stc_match_pair_2p_with_error(T1, T2, Local, Super, Msg) \
- template < typename T1, typename T2 > \
- struct match_with< Local, Super > : \
- mlc::abort_< T2, Msg > \
+ struct match_with <mlc::not_found, mlc::not_found> \
{ \
- }
-
-
- namespace merge2_
- {
- // Forward declaration.
- template <typename T, typename U> struct match_with;
-
-
- /*------------------------------.
- | local_res == stc::not_found. |
- `------------------------------*/
-
- stc_match_pair_0p_with(stc::not_found, stc::not_found,
- stc::not_found);
-
- stc_match_pair_0p_with(stc::not_found, stc::abstract,
- stc::not_found);
-
- stc_match_pair_1p_with(U,
- stc::not_found, stc::final<U>,
- stc::final<U>);
-
- stc_match_pair_1p_with(U,
- stc::not_found, U,
- U);
-
-
- /*-----------------------------.
- | local_res == stc::abstract. |
- `-----------------------------*/
-
- stc_match_pair_0p_with(stc::abstract, stc::not_found,
- stc::abstract);
-
- stc_match_pair_0p_with(stc::abstract, stc::abstract,
- stc::abstract);
-
- stc_match_pair_1p_with_error(U,
- stc::abstract, stc::final<U>,
- stc::ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT);
-
- stc_match_pair_1p_with_error(U,
- stc::abstract, U,
- stc::ERROR::IN_merge2__VIRTUAL_TYPE_REDEFINED_ABSTRACT);
-
-
- /*-----------------------------.
- | local_res == stc::final<T>. |
- `-----------------------------*/
-
- stc_match_pair_1p_with(T,
- stc::final<T>, stc::not_found,
- stc::final<T>);
-
- stc_match_pair_1p_with(T,
- stc::final<T>, stc::abstract,
- stc::final<T>);
-
- stc_match_pair_2p_with_error(T, U,
- stc::final<T>, stc::final<U>,
- stc::ERROR::IN_merge2__FINAL_VIRTUAL_TYPE_REDEFINED_FINAL);
-
- stc_match_pair_2p_with(T, U,
- stc::final<T>, U,
- stc::final<T>);
-
-
- /*-----------------.
- | local_res == T. |
- `-----------------*/
-
- stc_match_pair_1p_with(T,
- T, stc::not_found,
- T);
-
- stc_match_pair_1p_with(T,
- T, stc::abstract,
- T);
-
- stc_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_
-
-#undef stc_match_pair_2p_with_error
-#undef stc_match_pair_1p_with_error
-#undef stc_match_pair_2p_with
-#undef stc_match_pair_1p_with
-#undef stc_match_pair_0p_with
-
- template <typename local_res, typename super_res>
- struct merge2
- {
- // Result.
- typedef typename merge2_::match_with<local_res, super_res>::ret ret;
- };
-
-
- // -------------------------------------------------------------- merge3.
-
-// Shortcuts macros.
-#define stc_match_triple_0p_with(Local, Super, Deleg, Res) \
+ 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< Local, Super, Deleg > \
- { \
- typedef Res ret; \
- }
-
-#define stc_match_triple_1p_with(T1, Local, Super, Deleg, Res) \
- template < typename T1 > \
- struct match_with< Local, Super, Deleg > \
- { \
- typedef Res ret; \
- }
-
-#define stc_match_triple_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_triple_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; \
- }
-
-// Erroneous cases.
-#define stc_match_triple_2p_with_error(T1, T2, Local, Super, Deleg, Msg) \
- template < typename T1, typename T2 > \
- struct match_with< Local, Super, Deleg > : \
- mlc::abort_< T2, Msg > \
+ 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> */ \
{ \
- }
-
-#define stc_match_triple_3p_with_error(T1, T2, T3, Local, Super, Deleg, Msg) \
- template < typename T1, typename T2, typename T3 > \
- struct match_with< Local, Super, Deleg > : \
- mlc::abort_< T3, Msg > \
+ }; \
+ \
+ template <> \
+ struct match_with<stc::not_delegated> \
{ \
- }
-
-
- 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_match_triple_0p_with(stc::not_found, stc::not_found, stc::not_found,
- stc::not_found);
-
- stc_match_triple_0p_with(stc::not_found, stc::not_found, stc::abstract,
- stc::not_found);
-
- stc_match_triple_1p_with(V,
- stc::not_found, stc::not_found, stc::final<V>,
- stc::final<V>);
-
- stc_match_triple_1p_with(V,
- stc::not_found, stc::not_found, V,
- V);
-
- // super_res == stc::abstract.
- stc_match_triple_0p_with(stc::not_found, stc::abstract, stc::not_found,
- stc::not_found);
-
- stc_match_triple_0p_with(stc::not_found, stc::abstract, stc::abstract,
- stc::abstract);
-
- stc_match_triple_1p_with(V,
- stc::not_found, stc::abstract, stc::final<V>,
- stc::final<V>);
-
- stc_match_triple_1p_with(V,
- stc::not_found, stc::abstract, V,
- V);
-
- // super_res is a concrete type.
- stc_match_triple_2p_with(U, V,
- stc::not_found, stc::final<U>, V,
- stc::final<U>);
-
- stc_match_triple_2p_with(U, V,
- stc::not_found, U, V,
- U);
-
-
- /*-----------------------------.
- | local_res == stc::abstract. |
- `-----------------------------*/
-
- // super_res == stc::not_found.
- stc_match_triple_0p_with(stc::abstract, stc::not_found, stc::not_found,
- stc::abstract);
-
- stc_match_triple_0p_with(stc::abstract, stc::not_found, stc::abstract,
- stc::abstract);
-
- stc_match_triple_1p_with(V,
- stc::abstract, stc::not_found, stc::final<V>,
- stc::final<V>);
-
- stc_match_triple_1p_with(V,
- stc::abstract, stc::not_found, V,
- V);
-
-
- // super_res == stc::abstract.
- stc_match_triple_0p_with(stc::abstract, stc::abstract, stc::not_found,
- stc::abstract);
-
- stc_match_triple_0p_with(stc::abstract, stc::abstract, stc::abstract,
- stc::abstract);
-
- stc_match_triple_1p_with(V,
- stc::abstract, stc::abstract, stc::final<V>,
- stc::final<V>);
-
- stc_match_triple_1p_with(V,
- stc::abstract, stc::abstract, V,
- V);
-
-
- // super_res == stc::not_delegated_abstract.
- stc_match_triple_1p_with(V,
- stc::abstract, stc::not_delegated_abstract, V,
- stc::not_delegated_abstract);
-
- stc_match_triple_1p_with(V,
- stc::abstract, stc::not_delegated, V,
- stc::not_delegated_abstract);
-
-
- // super_res is a concrete type.
- stc_match_triple_2p_with_error(U, V,
- stc::abstract, stc::final<U>, V,
- stc::ERROR::IN_merge3__FINAL_VIRTUAL_TYPE_REDEFINED_ABSTRACT);
-
- stc_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_match_triple_1p_with(V,
- stc::not_delegated, stc::not_found, V,
- stc::not_delegated);
-
- stc_match_triple_1p_with(V,
- stc::not_delegated, stc::abstract, V,
- stc::not_delegated_abstract);
-
- stc_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_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_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_match_triple_3p_with(T, U, V,
- stc::final<T>, U, V,
- stc::final<T>);
-
-
- /*-----------------.
- | local_res == T. |
- `-----------------*/
-
- stc_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_
-
-
-#undef stc_match_triple_3p_with_error
-#undef stc_match_triple_2p_with_error
-#undef stc_match_triple_3p_with
-#undef stc_match_triple_2p_with
-#undef stc_match_triple_1p_with
-#undef stc_match_triple_0p_with
-
-
- 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_
-
-
- /// 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 */
-
+ 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.
@@ -782,4 +707,4 @@
::ret
-#endif // ! STC_SCOOP2_HH
+#endif // ! STC_SCOOP_ALT_HH
Index: stc/Makefile.am
--- stc/Makefile.am (revision 725)
+++ stc/Makefile.am (working copy)
@@ -7,11 +7,11 @@
exact.hh \
find_exact.hh \
scoop.hh \
+ scoop-alt.hh \
valist_aggregator.hh \
\
internal/extract_vtype_from_list.hh \
- \
- scoop2.hh
+ internal/match-with.hh
# Old code.
EXTRA_DIST = was.scoop.hh
Index: stc/internal/match-with.hh
--- stc/internal/match-with.hh (revision 0)
+++ stc/internal/match-with.hh (revision 0)
@@ -0,0 +1,128 @@
+// Copyright (C) 2005, 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
+// 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/match-with.hh
+ \brief Internal helpers for stc/scoop-alt.hh.
+
+ This file contains helpers that mimic a ``match-with'' (pattern
+ matching) construct from many functional languages. */
+
+
+#ifndef STC_INTERNAL_MATCH_WITH_HH
+# define STC_INTERNAL_MATCH_WITH_HH
+
+/*-----------------.
+| merge2 helpers. |
+`-----------------*/
+
+/* Shortcuts macros. */
+#define stc_internal_match_pair_0p_with(Local, Super, Res) \
+ template <> \
+ struct match_with< Local, Super > \
+ { \
+ typedef Res ret; \
+ }
+
+#define stc_internal_match_pair_1p_with(T1, Local, Super, Res) \
+ template < typename T1 > \
+ struct match_with< Local, Super > \
+ { \
+ typedef Res ret; \
+ }
+
+#define stc_internal_match_pair_2p_with(T1, T2, Local, Super, Res) \
+ template < typename T1, typename T2 > \
+ struct match_with< Local, Super > \
+ { \
+ typedef Res ret; \
+ }
+
+/* Erroneous cases. */
+#define stc_internal_match_pair_1p_with_error(T1, Local, Super, Msg) \
+ template < typename T1 > \
+ struct match_with< Local, Super > : \
+ mlc::abort_< T1, Msg > \
+ { \
+ }
+
+#define stc_internal_match_pair_2p_with_error(T1, T2, Local, Super, Msg) \
+ template < typename T1, typename T2 > \
+ struct match_with< Local, Super > : \
+ mlc::abort_< T2, Msg > \
+ { \
+ }
+
+/*-----------------.
+| merge3 helpers. |
+`-----------------*/
+
+/* Shortcuts macros. */
+#define stc_internal_match_triple_0p_with(Local, Super, Deleg, Res) \
+ template <> \
+ struct match_with< Local, Super, Deleg > \
+ { \
+ typedef Res ret; \
+ }
+
+#define stc_internal_match_triple_1p_with(T1, Local, Super, Deleg, Res) \
+ template < typename T1 > \
+ struct match_with< Local, Super, Deleg > \
+ { \
+ typedef Res ret; \
+ }
+
+#define stc_internal_match_triple_2p_with(T1, T2, Local, Super, Deleg, Res) \
+ template < typename T1, typename T2 > \
+ struct match_with< Local, Super, Deleg > \
+ { \
+ typedef Res ret; \
+ }
+
+#define stc_internal_match_triple_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; \
+ }
+
+/* Erroneous cases. */
+#define stc_internal_match_triple_2p_with_error(T1, T2, Local, Super, Deleg, Msg) \
+ template < typename T1, typename T2 > \
+ struct match_with< Local, Super, Deleg > : \
+ mlc::abort_< T2, Msg > \
+ { \
+ }
+
+#define stc_internal_match_triple_3p_with_error(T1, T2, T3, Local, Super, Deleg, Msg) \
+ template < typename T1, typename T2, typename T3 > \
+ struct match_with< Local, Super, Deleg > : \
+ mlc::abort_< T3, Msg > \
+ { \
+ }
+
+#endif // ! STC_INTERNAL_MATCH_WITH_HH