2006-11-30 Thierry GERAUD <theo(a)tegucigalpa.lrde.epita.fr>
* stc/scoop.hh (stc_scoop_equipment_for_namespace): Rewrite.
Index: stc/scoop.hh
===================================================================
--- stc/scoop.hh (revision 711)
+++ stc/scoop.hh (working copy)
@@ -1,325 +1,835 @@
-// 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: notably, Virtual types (also known as
- ``properties'') mechanism.
-
- Based on Theo's presentation from January 2006 (olena-06-jan.pdf). */
-
-#ifndef STC_SCOOP_HH
-# define STC_SCOOP_HH
-
-# include <mlc/flags.hh>
-# include <mlc/typedef.hh>
-# include <mlc/ret.hh>
-
-# include <mlc/assert.hh>
-# include <mlc/abort.hh>
-
-# include <mlc/bool.hh>
-
-# include <mlc/cmp.hh>
-# include <mlc/if.hh>
-# include <mlc/is_a.hh>
-
-
-namespace stc
-{
-
- /// Error messages raised by static assertions/abortions.
- namespace ERROR
- {
-
- /// Errors from check_type_of_ and check_exact_type_of_.
- /// \{
- struct VIRTUAL_TYPE_NOT_FOUND;
- /// \}
-
- } // end of namespace stc::ERROR
-
-} // end of namespace stc
-
-
-
-# define stc_internal_get_typedef(Type, TypedefName) \
- typename TypedefName::template from_< Type >::ret
-
-
-# define stc_internal_get_super(Type) \
- typename typedef_::super_type::template from_< Type >::ret
-
-
-
-
-
-
-# define stc_scoop_equipment_for_namespace(SCOOPED_NAMESPACE) \
- \
-namespace SCOOPED_NAMESPACE \
-{ \
- \
- template <typename from_type> \
- struct set_super_type \
- { \
- typedef mlc::none ret; \
- }; \
- \
- template <typename type> \
- struct set_pseudosuper_type \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- template <typename from_type> \
- struct vtypes \
- { \
- }; \
- \
- template <typename from_type, typename type> \
- struct single_vtype \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- \
- namespace internal \
- { \
- \
- /* retrieve_from_single_vtype */ \
- \
- template <typename from_type, typename type> \
- struct retrieve_from_single_vtype; \
- \
- template <typename res, typename super, typename type> \
- struct helper_retrieve_from_single_vtype \
- { \
- typedef res ret; \
- }; \
- \
- template <typename super, typename type> \
- struct helper_retrieve_from_single_vtype < mlc::not_found, super, type > \
- { \
- typedef typename retrieve_from_single_vtype<super, type>::ret ret; \
- }; \
- \
- template <typename type> \
- struct helper_retrieve_from_single_vtype < mlc::not_found, mlc::none, type > \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- template <typename type> \
- struct helper_retrieve_from_single_vtype < mlc::not_found, mlc::not_found, type
> \
- { \
- }; \
- \
- template <typename from_type, typename type> \
- struct retrieve_from_single_vtype \
- { \
- typedef SCOOPED_NAMESPACE::single_vtype<from_type, type> decl; \
- typedef typename decl::ret res; \
- typedef typename set_super_type<from_type>::ret super; \
- typedef typename helper_retrieve_from_single_vtype< res, super, type >::ret
ret; \
- }; \
- \
- /* vtypes */ \
- \
- template <typename from_type, typename type> \
- struct retrieve_from_vtypes; \
- \
- template <typename res, typename super, typename type> \
- struct helper_retrieve_from_vtypes \
- { \
- typedef res ret; \
- }; \
- \
- template <typename super, typename type> \
- struct helper_retrieve_from_vtypes < mlc::not_found, super, type > \
- { \
- typedef typename retrieve_from_vtypes<super, type>::ret ret; \
- }; \
- \
- template <typename type> \
- struct helper_retrieve_from_vtypes < mlc::not_found, mlc::none, type > \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- template <typename type> \
- struct helper_retrieve_from_vtypes < mlc::not_found, mlc::not_found, type > \
- { \
- }; \
- \
- template <typename from_type, typename type> \
- struct retrieve_from_vtypes \
- { \
- typedef SCOOPED_NAMESPACE::vtypes<from_type> decl; \
- typedef stc_internal_get_typedef(decl, type) res; \
- typedef typename set_super_type<from_type>::ret super; \
- typedef typename helper_retrieve_from_vtypes< res, super, type >::ret ret; \
- }; \
- \
- /* pseudo super */ \
- \
- template <typename from_type> \
- struct retrieve_pseudosuper; \
- \
- template <typename res, typename super> \
- struct helper_retrieve_pseudosuper \
- { \
- typedef res ret; \
- }; \
- \
- template <typename super> \
- struct helper_retrieve_pseudosuper < mlc::not_found, super > \
- { \
- typedef typename retrieve_pseudosuper<super>::ret ret; \
- }; \
- \
- template <> \
- struct helper_retrieve_pseudosuper < mlc::not_found, mlc::none > \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- template <> \
- struct helper_retrieve_pseudosuper < mlc::not_found, mlc::not_found > \
- { \
- }; \
- \
- template <typename from_type> \
- struct retrieve_pseudosuper \
- { \
- typedef typename set_pseudosuper_type<from_type>::ret res; \
- typedef typename set_super_type<from_type>::ret super; \
- typedef typename helper_retrieve_pseudosuper< res, super >::ret ret; \
- }; \
- \
- /* scoop_vtype_of */ \
- \
- template <typename from_type, typename type> \
- struct step_from_vtypes; /* fwd decl of main entry */ \
- \
- /* step 3 <=> delegation */ \
- \
- template <typename from_type, typename type> \
- struct helper_step_from_delegation \
- { \
- /* REC */ \
- typedef typename step_from_vtypes<from_type, type>::ret ret; \
- }; \
- \
- template <typename type> \
- struct helper_step_from_delegation < mlc::not_found, type > \
- { \
- typedef mlc::not_found ret; \
- }; \
- \
- template <typename from_type, typename type> \
- struct step_from_delegation /* step 3 entry */ \
- { \
- typedef typename retrieve_pseudosuper<from_type>::ret pseudo_type; \
- typedef typename helper_step_from_delegation<pseudo_type, type>::ret ret; \
- }; \
- \
- /* step 2 <=> single_vtype */ \
- \
- template <typename res, typename from_type, typename type> \
- struct helper_step_from_single_vtype \
- { \
- typedef res ret; /* found! */ \
- }; \
- \
- template <typename from_type, typename type> \
- struct helper_step_from_single_vtype <mlc::not_found, /* => step 3 */ \
- from_type, type> \
- { \
- typedef typename step_from_delegation<from_type, type>::ret ret; \
- }; \
- \
- template <typename from_type, typename type> \
- struct helper_step_from_single_vtype <mlc::undefined, /* => step 3 */ \
- from_type, type> \
- { \
- typedef typename step_from_delegation<from_type, type>::ret ret; \
- }; \
- \
- template <typename from_type, typename type> \
- struct step_from_single_vtype /* step 2 entry */ \
- { \
- typedef typename retrieve_from_single_vtype<from_type, type>::ret res; \
- typedef typename helper_step_from_single_vtype< res, from_type, type>::ret
ret; \
- }; \
- \
- /* step 1 <=> vtypes */ \
- \
- template <typename res, typename from_type, typename type> \
- struct helper_step_from_vtypes \
- { \
- typedef res ret; /* found! */ \
- }; \
- \
- template <typename from_type, typename type> \
- struct helper_step_from_vtypes <mlc::not_found, /* => step 2 */ \
- from_type, type> \
- { \
- typedef typename step_from_single_vtype<from_type, type>::ret ret; \
- }; \
- \
- template <typename from_type, typename type> \
- struct helper_step_from_vtypes <mlc::undefined, /* => step 2 */ \
- from_type, type> \
- { \
- typedef typename step_from_single_vtype<from_type, type>::ret ret; \
- }; \
- \
- template <typename from_type, typename type> \
- struct step_from_vtypes /* main entry (so step 1 entry) */ \
- { \
- typedef typename retrieve_from_vtypes<from_type, type>::ret res; \
- typedef typename helper_step_from_vtypes< res, from_type, type>::ret ret; \
- }; \
- \
- } /* end of namespace SCOOPED_NAMESPACE ::internal */ \
- \
- \
- template <typename from_type, typename type> \
- struct direct_type_of_ \
- { \
- typedef typename internal::step_from_vtypes<from_type, type>::ret ret; \
- }; \
- \
- \
-} /* end of namespace SCOOPED_NAMESPACE */ \
- \
-struct e_n_d__w_i_t_h___s_e_m_i_c_o_l_o_n
-
-
-
-#endif // ! STC_SCOOP_HH
+// 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: notably, Virtual types (also known as
+ ``properties'') mechanism.
+
+ Based on Theo's presentation from January 2006 (olena-06-jan.pdf). */
+
+#ifndef STC_SCOOP_HH
+# define STC_SCOOP_HH
+
+# include <mlc/flags.hh>
+# include <mlc/typedef.hh>
+# include <mlc/ret.hh>
+# include <mlc/assert.hh>
+# include <mlc/abort.hh>
+# include <mlc/bool.hh>
+# include <mlc/pair.hh>
+# include <mlc/cmp.hh>
+# include <mlc/if.hh>
+# include <mlc/is_a.hh>
+
+
+namespace stc
+{
+
+ struct not_delegated;
+
+ struct abstract;
+
+ template <typename T>
+ struct final;
+
+} // end of namespace stc
+
+
+
+#define stc_super(T) typename set_super_type< T >::ret
+#define stc_stm(From, Target) typename get_stm< From , Target >::ret
+
+
+# define stc_scoop_equipment_for_namespace(SCOOPED_NAMESPACE) \
+ \
+ \
+namespace SCOOPED_NAMESPACE \
+{ \
+ \
+ mlc_decl_typedef(delegatee_type); \
+ \
+ \
+ template <typename from_type> \
+ struct set_super_type \
+ { \
+ typedef mlc::none ret; \
+ /* FIXME: nothing here! \
+ * \
+ * mlc::none is not a default value \
+ * so that the client should define stoppers \
+ */ \
+ }; \
+ \
+ template <typename from_type> \
+ struct vtypes \
+ { \
+ }; \
+ \
+ template <typename from_type, typename type> \
+ struct single_vtype \
+ { \
+ typedef mlc::not_found ret; \
+ }; \
+ \
+ \
+ \
+ namespace ERROR \
+ { \
+ \
+ template < typename first_definition, \
+ typename re_definition, \
+ typename target > \
+ struct final_vtype_redefined_; \
+ \
+ \
+ template < typename first_definition, \
+ typename declaration, \
+ typename target > \
+ struct vtype_declared_but_already_set_; \
+ \
+ \
+ template < typename from, \
+ typename target > \
+ struct vtype_not_found; \
+ \
+ \
+ template < typename curr, \
+ typename target, \
+ typename stm > \
+ struct wrong_final_stm_; \
+ \
+ \
+ template < typename target, \
+ typename declaration, \
+ typename from > \
+ struct vtype_declared_but_not_defined; \
+ \
+ \
+ template <typename T> \
+ struct _declaration_is_in_; \
+ \
+ template <typename T> \
+ struct _definition_is_looked_up_from_; \
+ \
+ \
+ template <typename T> \
+ struct _for_vtype_; \
+ \
+ \
+ struct no_delegatee_declared_; \
+ \
+ \
+ } /* end of namespace SCOOPED_NAMESPACE::ERROR */ \
+ \
+ \
+ \
+ namespace internal \
+ { \
+ \
+ \
+ /* \
+ * Forward declarations. \
+ */ \
+ \
+ \
+ template <typename from, typename target> \
+ struct get_stm; \
+ \
+ template <typename res1, typename res2> \
+ struct helper_get_stm; \
+ \
+ template <typename from, typename target> \
+ struct first_stm; \
+ \
+ template <typename curr, typename target, typename stm> \
+ struct helper_first_stm; \
+ \
+ \
+ template <typename from, typename target, typename curr = from> \
+ struct superior_find; \
+ \
+ template <typename from, typename target, typename curr, typename stm> \
+ struct helper_superior_find; \
+ \
+ template <typename from, typename target> \
+ struct delegator_find; \
+ \
+ template <typename from, typename target, typename delegatee> \
+ struct helper_delegator_find; \
+ \
+ template <typename from, typename target> \
+ struct find; \
+ \
+ template <typename from, typename target, typename where, typename res> \
+ struct helper_find; \
+ \
+ \
+ \
+ template <typename from, typename target> \
+ struct check; \
+ \
+ template <typename curr, typename target, typename stm> \
+ struct helper_check; \
+ \
+ \
+ \
+ /* get_stm(from, target) \
+ * \
+ * Returns the statement for class 'from' corresponding to
'target'. \
+ * This statement is either defined in 'vtypes' or in
'single_vtype'. \
+ * \
+ * This routine is local; it does not recourse on superior classes. \
+ * \
+ */ \
+ \
+ template <typename res1> \
+ struct helper_get_stm <res1, mlc::not_found> \
+ { \
+ typedef res1 ret; \
+ }; \
+ \
+ template <typename res2> \
+ struct helper_get_stm <mlc::not_found, res2> \
+ { \
+ typedef res2 ret; \
+ }; \
+ \
+ template <> \
+ struct helper_get_stm <mlc::not_found, mlc::not_found> \
+ { \
+ typedef mlc::not_found ret; \
+ }; \
+ \
+ template <typename res1, typename res2> \
+ struct helper_get_stm \
+ { \
+ /* error */ \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct get_stm \
+ { \
+ typedef SCOOPED_NAMESPACE::vtypes<from> decl1; \
+ typedef typename target::template from_<decl1>::ret res1; \
+ \
+ typedef SCOOPED_NAMESPACE::single_vtype<from, target> decl2; \
+ typedef typename decl2::ret ret2; \
+ \
+ typedef typename helper_get_stm<res1, ret2>::ret ret; \
+ }; \
+ \
+ \
+ \
+ \
+ /* \
+ * check_no_final_inherited \
+ * \
+ * FIXME: ... \
+ */ \
+ \
+ template < typename orig, typename curr, typename target, \
+ typename stm = typename get_stm<curr, target>::ret > \
+ struct check_no_final_inherited \
+ \
+ : mlc::assert_< mlc_is_not_a(stm, stc::final), \
+ ERROR::final_vtype_redefined_< orig, \
+ mlc::pair_<curr, stm>, \
+ target > \
+ >, \
+ /* rec */ check_no_final_inherited<orig, stc_super(curr), target> \
+ { \
+ }; \
+ \
+ template <typename orig, typename target, typename stm> \
+ struct check_no_final_inherited <orig, /* if curr == */ mlc::none, target,
stm> \
+ { \
+ }; \
+ \
+ \
+ /* \
+ * check_no_stm_inherited \
+ * \
+ * FIXME: ... \
+ */ \
+ \
+ template < typename orig, typename curr, typename target, \
+ typename stm = typename get_stm<curr, target>::ret > \
+ struct check_no_stm_inherited \
+ \
+ : mlc::assert_< mlc::is_not_found_<stm>, \
+ ERROR::vtype_declared_but_already_set_< orig, \
+ mlc::pair_<curr, stm>, \
+ target > \
+ >, \
+ /* rec */ check_no_stm_inherited<orig, stc_super(curr), target> \
+ { \
+ }; \
+ \
+ template <typename orig, typename target, typename stm> \
+ struct check_no_stm_inherited <orig, /* if curr == */ mlc::none, target,
stm> \
+ { \
+ }; \
+ \
+ \
+ /* \
+ * check_delegatee_inherited \
+ */ \
+ \
+ template <typename curr, typename target> \
+ struct check_delegatee_inherited \
+ : mlc::assert_< mlc::is_found_< typename first_stm<curr, \
+ typedef_::delegatee_type>::ret::second_elt >, \
+ ERROR::no_delegatee_declared_ > \
+ { \
+ }; \
+ \
+ \
+ /* \
+ * check_final_stm \
+ */ \
+ \
+ template <typename curr, typename target, typename stm> \
+ struct check_final_stm \
+ {}; \
+ \
+ template <typename curr, typename target> \
+ struct check_final_stm < curr, target, stc::abstract > \
+ : mlc::abort_< ERROR::wrong_final_stm_<curr, target,
stc::final<stc::abstract> > > \
+ {}; \
+ \
+ template <typename curr, typename target, typename T> \
+ struct check_final_stm < curr, target, stc::final<T> > \
+ : mlc::abort_< ERROR::wrong_final_stm_<curr, target,
stc::final<stc::final<T> > > > \
+ {}; \
+ \
+ template <typename curr, typename target> \
+ struct check_final_stm < curr, target, stc::not_delegated > \
+ : mlc::abort_< ERROR::wrong_final_stm_<curr, target,
stc::final<stc::not_delegated> > > \
+ {}; \
+ \
+ template <typename curr, typename target> \
+ struct check_final_stm < curr, target, mlc::not_found > \
+ : mlc::abort_< ERROR::wrong_final_stm_<curr, target,
stc::final<mlc::not_found> > > \
+ {}; \
+ \
+ \
+ \
+ \
+ /* \
+ * check(from, target) \
+ * \
+ * pseudo-code: \
+ * \
+ * check(from, target) \
+ * { \
+ * if (from == mlc::none) // stop because no more class \
+ * return done; \
+ * else \
+ * return helper_check(from, target, get_stm(from, target)); \
+ * } \
+ */ \
+ \
+ struct dummy {}; \
+ \
+ template <typename target> \
+ struct check < /* if from == */ mlc::none, target > \
+ { \
+ typedef dummy ret; \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct check /* otherwise */ \
+ { \
+ typedef typename helper_check< from, target, \
+ stc_stm(from, target) >::ret ret; \
+ }; \
+ \
+ \
+ \
+ \
+ /* \
+ * pseudo-code: \
+ * \
+ * helper_check(curr, target, stm) \
+ * { \
+ * super = super(curr); \
+ * \
+ * if (stm == stc::abstract) { \
+ * check_no_stm_inherited(curr, super, target); \
+ * return check(super, target); \
+ * } \
+ * if (stm == stc::final<T>) { \
+ * check_final_stm(T); \
+ * check_no_final_inherited((curr, T), super, target); \
+ * return check(super, target); \
+ * } \
+ * if (stm == stc::not_delegated) { \
+ * check_delegatee_inherited(curr); \
+ * check_no_final_inherited((curr, stc::not_delegated), super, target); \
+ * return check(super, target); \
+ * } \
+ * if (stm == mlc::not_found) { \
+ * return check(super, target); \
+ * } \
+ * // otherwise, non-final stm: \
+ * if (stm == T) { \
+ * check_no_final_inherited((curr, T), super, target); \
+ * return check(super, target); \
+ * } \
+ * } \
+ * \
+ */ \
+ \
+ template <typename curr, typename target> \
+ struct helper_check < curr, target, \
+ /* if stm == */ stc::abstract > \
+ : check_no_stm_inherited< mlc::pair_<curr, stc::abstract >, \
+ stc_super(curr), \
+ target > \
+ { \
+ typedef typename check<stc_super(curr), target>::ret ret; \
+ }; \
+ \
+ template <typename curr, typename target, typename T> \
+ struct helper_check < curr, target, \
+ /* if stm == */ stc::final<T> > \
+ : check_no_final_inherited< mlc::pair_<curr, stc::final<T> >, \
+ stc_super(curr), \
+ target > \
+ { \
+ /* FIXME: \
+ check_final_stm(T); \
+ */ \
+ typedef typename check<stc_super(curr), target>::ret ret; \
+ }; \
+ \
+ template <typename curr, typename target> \
+ struct helper_check < curr, target, \
+ /* if stm == */ stc::not_delegated > \
+ : check_no_final_inherited< mlc::pair_<curr, stc::not_delegated>, \
+ stc_super(curr), \
+ target > \
+ { \
+ /* FIXME: \
+ check_delegatee_inherited(curr); \
+ */ \
+ typedef typename check<stc_super(curr), target>::ret ret; \
+ }; \
+ \
+ template <typename curr, typename target> \
+ struct helper_check < curr, target, \
+ /* if stm == */ mlc::not_found > \
+ { \
+ typedef typename check<stc_super(curr), target>::ret ret; \
+ }; \
+ \
+ template <typename curr, typename target, typename stm> \
+ struct helper_check /* otherwise, non-final stm */ \
+ : check_no_final_inherited< mlc::pair_<curr, stm>, \
+ stc_super(curr), \
+ target > \
+ { \
+ typedef typename check<stc_super(curr), target>::ret ret; \
+ }; \
+ \
+ \
+ \
+ \
+ /* \
+ * first_stm(from, target) \
+ * \
+ * returns a pair (Where, Value) with Value being: \
+ * - stc::abstract \
+ * - stc::not_delegated \
+ * - mlc::not_found \
+ * - a type T \
+ * and Where being the class where the stm is found. \
+ * \
+ * \
+ * helper_first_stm(curr, target, stm) \
+ * { \
+ * if (stm == mlc::not_found) \
+ * return first_stm(super(curr), target); \
+ * else if (stm == stc::final<T>) \
+ * return pair(curr, T); \
+ * else \
+ * return pair(curr, stm); \
+ * } \
+ * \
+ * first_stm(from, target) \
+ * { \
+ * if (from == mlc::none) \
+ * return pair(mlc::none, mlc::not_found); \
+ * else \
+ * return helper_first_stm(from, target, \
+ * get_stm(from, target)); \
+ * } \
+ * \
+ */ \
+ \
+ template <typename curr, typename target> \
+ struct helper_first_stm < curr, target, \
+ /* if stm == */ mlc::not_found > \
+ { \
+ typedef typename first_stm<stc_super(curr), target>::ret ret; \
+ }; \
+ \
+ template <typename curr, typename target, typename T> \
+ struct helper_first_stm < curr, target, \
+ /* if stm == */ stc::final<T> > \
+ { \
+ typedef mlc::pair_<curr, T> ret; \
+ }; \
+ \
+ template <typename curr, typename target, typename stm> \
+ struct helper_first_stm /* otherwise */ \
+ { \
+ typedef mlc::pair_<curr, stm> ret; \
+ }; \
+ \
+ template <typename target> \
+ struct first_stm < /* if from == */ mlc::none, target > \
+ { \
+ typedef mlc::pair_<mlc::none, mlc::not_found> ret; \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct first_stm /* otherwise */ \
+ { \
+ typedef typename helper_first_stm<from, target, \
+ stc_stm(from, target)>::ret ret; \
+ }; \
+ \
+ \
+ \
+ /* \
+ * superior_find(from, target) \
+ * \
+ * returns: \
+ * either mlc::not_found \
+ * or a type T \
+ * behavior: \
+ * - the stm stc::not_delegated is ignored \
+ * - error when stc::abstract is reached \
+ * \
+ * helper_superior_find(from, target, curr, stm) \
+ * { \
+ * if (stm == stc::abstract) \
+ * error("<target> declared in <curr> but not defined at
<from>"); \
+ * else if (stm == mlc::not_found or \
+ * stm == stc::not_delegated) \
+ * return superior_find(from, target, super(curr)); \
+ * else if (stm == stc::final<T>) \
+ * return T; \
+ * else \
+ * return stm; \
+ * } \
+ * \
+ * superior_find(from, target, curr = from) \
+ * { \
+ * if (curr == mlc::none) \
+ * return mlc::not_found; \
+ * else \
+ * return helper_superior_find(from, target, curr, \
+ * get_stm(curr, target)); \
+ * } \
+ */ \
+ \
+ template <typename from, typename target, typename curr> \
+ struct helper_superior_find < from, target, curr, \
+ /* if stm == */ stc::abstract > \
+ { \
+ /* FIXME: error("<target> declared in <curr> but not defined at
<from>"); */ \
+ }; \
+ \
+ template <typename from, typename target, typename curr> \
+ struct helper_superior_find < from, target, curr, \
+ /* if stm == */ mlc::not_found > \
+ { \
+ typedef typename superior_find< from, target, \
+ stc_super(curr) >::ret ret; \
+ }; \
+ \
+ template <typename from, typename target, typename curr> \
+ struct helper_superior_find < from, target, curr, \
+ /* if stm == */ stc::not_delegated > \
+ { \
+ typedef typename superior_find< from, target, \
+ stc_super(curr) >::ret ret; \
+ }; \
+ \
+ template <typename from, typename target, typename curr, typename T> \
+ struct helper_superior_find < from, target, curr, \
+ /* if stm == */ stc::final<T> > \
+ { \
+ typedef T ret; \
+ }; \
+ \
+ template <typename from, typename target, typename curr, typename stm> \
+ struct helper_superior_find /* otherwise */ \
+ { \
+ typedef stm ret; \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct superior_find < from, target, /* if curr == */ mlc::none > \
+ { \
+ typedef mlc::not_found ret; \
+ }; \
+ \
+ template <typename from, typename target, typename curr> \
+ struct superior_find /* otherwise */ \
+ { \
+ typedef typename helper_superior_find<from, target, curr, \
+ stc_stm(curr, target)>::ret ret; \
+ }; \
+ \
+ \
+ \
+ /* \
+ * delegator_find(from, target) \
+ * \
+ * \
+ * delegator_find(from, target) \
+ * { \
+ * precondition(target != delegatee_type); \
+ * delegatee = superior_find(from, delegatee_type); \
+ * if (delegatee == mlc::not_found) \
+ * return mlc::not_found; \
+ * else \
+ * return find(delegatee, target); \
+ * } \
+ */ \
+ \
+ template <typename from, typename target> \
+ struct helper_delegator_find < from, target, \
+ /* if delegatee == */ mlc::not_found > \
+ { \
+ typedef mlc::not_found ret; \
+ }; \
+ \
+ template <typename from, typename target, typename delegatee> \
+ struct helper_delegator_find /* otherwise */ \
+ { \
+ typedef typename find<delegatee, target>::ret ret; \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct delegator_find \
+ { \
+ typedef typename superior_find<from, typedef_::delegatee_type>::ret
delegatee; \
+ typedef typename helper_delegator_find<from, target, delegatee>::ret
ret; \
+ }; \
+ \
+ \
+ \
+ /* \
+ * helper_find(from, target, where, res) \
+ * \
+ * \
+ * \
+ */ \
+ \
+ template <typename from, typename target, typename where> \
+ struct helper_find < from, target, where, \
+ /* if res == */ mlc::not_found > \
+ { \
+ typedef typename delegator_find<from, target>::ret ret; \
+ }; \
+ \
+ template <typename from, typename target, typename where> \
+ struct helper_find < from, target, where, \
+ /* if res == */ stc::abstract > \
+ { \
+ typedef typename delegator_find<from, target>::ret res_d; \
+ struct check_ \
+ : mlc::assert_< mlc::is_found_<res_d>, \
+ ERROR::vtype_declared_but_not_defined \
+ < ERROR::_for_vtype_<target>, \
+ ERROR::_declaration_is_in_<where>, \
+ ERROR::_definition_is_looked_up_from_<from> > > \
+ /* FIXME: error("<target> declared in <where> but not defined at
<from>"); */ \
+ { \
+ typedef res_d ret; \
+ }; \
+ typedef typename check_::ret ret; \
+ }; \
+ \
+ template <typename from, typename target, typename where> \
+ struct helper_find < from, target, where, \
+ /* if res == */ stc::not_delegated > \
+ { \
+ typedef typename superior_find<from, target>::ret ret; \
+ }; \
+ \
+ template <typename from, typename target, typename where, typename res> \
+ struct helper_find /* otherwise */ \
+ { \
+ typedef res ret; \
+ }; \
+ \
+ \
+ \
+ /* \
+ * find(from, target) \
+ * \
+ * FIXME: ... \
+ * \
+ * find(from, target) \
+ * { \
+ * if (target == delegatee_type) \
+ * return superior_find(from, delegatee_type); \
+ * else \
+ * return helper_find(from, target); \
+ * } \
+ */ \
+ \
+ template <typename from> \
+ struct find <from, /* if target == */ typedef_::delegatee_type > \
+ { \
+ typedef typename superior_find<from, typedef_::delegatee_type>::ret ret; \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct find /* otherwise */ \
+ { \
+ typedef typename first_stm<from, target>::ret stm; \
+ typedef mlc_elt(stm, 1) where; \
+ typedef mlc_elt(stm, 2) res; \
+ typedef typename helper_find<from, target, \
+ where, res>::ret ret; \
+ }; \
+ \
+ \
+ } /* end of SCOOPED_NAMESPACE::internal */ \
+ \
+ \
+ /* \
+ * find_vtype(from, target) \
+ * \
+ * FIXME:... \
+ * \
+ */ \
+ \
+ template <typename from, typename target> \
+ struct deferred_vtype \
+ { \
+ typedef typename internal::find<from, target>::ret ret; \
+ }; \
+ \
+ template <typename from, typename target> \
+ struct find_vtype \
+ { \
+ typedef typename internal::find<from, target>::ret ret; \
+ typedef typename internal::check<from, target>::ret chk; \
+ }; \
+ \
+ 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;
+
+
+
+# define stc_find_vtype_(Namespace, From, Target) \
+ Namespace::find_vtype<From, Namespace::typedef_::Target##_type>::ret
+
+# define stc_find_vtype(Namespace, From, Target) \
+ typename stc_find_vtype_(Namespace, From, Target)
+
+
+
+# define stc_deferred_vtype(Namespace, From, Target) \
+ typename Namespace::deferred_vtype<From,
Namespace::typedef_::Target##_type>::ret
+
+
+
+# define stc_vtype_(Namespace, From, Target) \
+ Namespace::vtype<From, Namespace::typedef_::Target##_type>::ret
+
+# define stc_vtype(Namespace, From, Target) \
+ typename stc_vtype_(Namespace, From, Target)
+
+
+
+# define stc_find_deduce_vtype_(Namespace, From, Target1, Target2) \
+ Namespace::find_vtype< Namespace::find_vtype<From, \
+ Namespace::typedef_::Target1##_type>::ret, \
+ Namespace::typedef_::Target2##_type>::ret
+
+# define stc_find_deduce_vtype(Namespace, From, Target) \
+ typename \
+ Namespace::find_vtype< typename \
+ Namespace::find_vtype<From, \
+ Namespace::typedef_::Target1##_type>::ret, \
+ Namespace::typedef_::Target2##_type>::ret
+
+
+
+# define stc_deduce_deferred_vtype(Namespace, From, Target1, Target2) \
+ typename \
+ Namespace::deferred_vtype< typename \
+ Namespace::deferred_vtype<From, \
+ Namespace::typedef_::Target1##_type>::ret, \
+ Namespace::typedef_::Target2##_type>::ret \
+
+
+
+# define stc_deduce_vtype_(Namespace, From, Target1, Target2) \
+ Namespace::vtype< Namespace::vtype<From, \
+ Namespace::typedef_::Target1##_type>::ret, \
+ Namespace::typedef_::Target2##_type>::ret
+
+# define stc_deduce_vtype(Namespace, From, Target1, Target2) \
+ typename \
+ Namespace::vtype< typename \
+ Namespace::vtype<From, \
+ Namespace::typedef_::Target1##_type>::ret, \
+ Namespace::typedef_::Target2##_type>::ret
+
+
+
+
+
+// # define stc_vtype_is_found_(Namespace, From, Target)
+// mlc::is_found_< Namespace::find_vtype<From,
Namespace::typedef_::Target##_type>::ret >
+
+
+#endif // ! STC_SCOOP_HH