Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
03 Mar '06
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
New sub-project ('extended'; 'xtd' for short) and update.
* extended: New sub-project.
* extended/xtd: New directory.
* extended/tests: New directory.
* extended/tests/Makefile.am: New.
* extended/Makefile.am: New.
* configure.ac: Update.
* Makefile.am: Update.
Makefile.am | 2 +-
configure.ac | 4 +++-
extended/Makefile.am | 3 +++
extended/tests/Makefile.am | 4 ++++
4 files changed, 11 insertions(+), 2 deletions(-)
Index: extended/tests/Makefile.am
--- extended/tests/Makefile.am (revision 0)
+++ extended/tests/Makefile.am (revision 0)
@@ -0,0 +1,4 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+mlcdir = $(includedir)/xtd
+nobase_mlc_HEADERS = \
Index: extended/Makefile.am
--- extended/Makefile.am (revision 0)
+++ extended/Makefile.am (revision 0)
@@ -0,0 +1,3 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+SUBDIRS = xtd tests
Index: configure.ac
--- configure.ac (revision 417)
+++ configure.ac (working copy)
@@ -39,7 +39,7 @@
# Students should create their test suite in tests/. Add the needed
# configure options here.
-AC_CONFIG_FILES([metalic/tests/Makefile])
+AC_CONFIG_FILES([metalic/tests/Makefile extended/tests/Makefile])
## --------------- ##
@@ -54,6 +54,8 @@
Makefile
metalic/Makefile
metalic/mlc/Makefile
+ extended/Makefile
+ extended/xtd/Makefile
])
# Checks for library functions.
Index: Makefile.am
--- Makefile.am (revision 417)
+++ Makefile.am (working copy)
@@ -1,3 +1,3 @@
## Process this file through Automake to produce Makefile.in -*- Makefile -*-
-SUBDIRS = build-aux metalic
+SUBDIRS = build-aux metalic extended
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Update Makefiles and switch file.
* tests/Makefile.am: Update.
* mlc/switch.hh: Replace obsolete contents by inclusion of case.hh.
* mlc/Makefile.am: Update.
mlc/Makefile.am | 2
mlc/switch.hh | 223 ------------------------------------------------------
tests/Makefile.am | 6 +
3 files changed, 9 insertions(+), 222 deletions(-)
Index: tests/Makefile.am
--- tests/Makefile.am (revision 416)
+++ tests/Makefile.am (working copy)
@@ -8,14 +8,20 @@
# when oln.m4 is available in the distribution.
check_PROGRAMS = \
+ case \
if \
is_a \
properties \
+ ret \
+ switch \
typedef
+case_SOURCES = case.cc
if_SOURCES = if.cc
is_a_SOURCES = is_a.cc
properties_SOURCES = properties.cc
+ret_SOURCES = ret.cc
+switch_SOURCES = switch.cc
typedef_SOURCES = typedef.cc
TESTS = $(check_PROGRAMS)
Index: mlc/switch.hh
--- mlc/switch.hh (revision 416)
+++ mlc/switch.hh (working copy)
@@ -28,229 +28,8 @@
#ifndef METALIC_SWITCH_HH
# define METALIC_SWITCH_HH
-# include <mlc/bool.hh>
-# include <mlc/typedef.hh>
-# include <mlc/is_a.hh>
-# include <mlc/implies.hh>
-# include <mlc/comma.hh>
-# include <mlc/cmp.hh>
-# include <mlc/if.hh>
-
-namespace mlc
-{
-
- // FIXME: doc
-
- namespace internal
- {
- struct case_true {};
- struct case_false {};
-
- } // end of namespace mlc::internal
-
-
- template <typename bexpr>
- struct where_ : public mlc_if_( typename bexpr::eval,
- internal::case_true,
- internal::case_false )
- {
- };
-
-
-
- // FIXME: doc
-
- template <typename context,
- typename data,
- unsigned i>
- struct case_ : public undefined
- {
- };
-
-
- template <typename context,
- typename data>
- struct case_ <context, data, 0>;
-
-
- template <typename context,
- typename data>
- struct default_case_ : public undefined
- {
- };
-
-
- namespace ERROR
- {
- struct A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_;
- struct A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_;
- struct SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA;
- struct RESULT_IS_NOT_FOUND_IN_default_case_;
- template <unsigned i> struct RESULT_IS_NOT_FOUND_IN_case_;
-
- } // end of namespace mlc::ERROR
-
-
- namespace internal
- {
-
- template <typename context, typename data, unsigned i,
- bool the_ith_case_derives_from_true,
- bool the_ith_case_derives_from_false>
- struct handle_case_;
-
-
-
- // impossible situation
-
- template <typename context, typename data, unsigned i>
- struct handle_case_ <context, data, i,
- 1, 1>;
-
-
-
- // default case
-
- template <typename context, typename data>
- struct handle_default_case_
-
- : private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
- undefined),
- mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
- where_) >,
- ERROR::A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_ >,
-
- private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
- undefined),
- neq_<mlc_ret(mlc_comma_1(default_case_<context, data>)),
- not_found> >,
- ERROR::RESULT_IS_NOT_FOUND_IN_default_case_ >
-
- {
- typedef default_case_<context, data> current_t;
- typedef typename mlc::if_<mlc_is_a(current_t, undefined),
- none,
- current_t>::ret ret;
- };
-
-
-
- // there is no more user-defined cases
- // so go to the default case (the last case handled here)
-
- template <typename context, typename data, unsigned i>
- struct handle_case_ <context, data, i,
- 0, 0>
-
- : private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
- undefined),
- mlc_is_a(mlc_comma_2(case_<context, data, i>),
- where_) >,
- ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >
-
- {
- typedef handle_default_case_<context, data> last_t;
- typedef mlc_ret(last_t) ret;
- };
-
-
- // current case is the one
-
- template <typename context, typename data, unsigned i>
- struct handle_case_ <context, data, i,
- 1, 0>
-
- : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
- where_),
- mlc_is_a(mlc_comma_2(case_<context, data, i>),
- undefined) >,
- ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >,
-
- private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
- undefined),
- neq_<mlc_ret(mlc_comma_2(case_<context, data, i>)),
- not_found> >,
- ERROR::RESULT_IS_NOT_FOUND_IN_case_<i> >
-
- {
- typedef case_<context, data, i> ret;
- };
-
-
-
- // current case is not the one
- // so go to the next case
-
- template <typename context, typename data, unsigned i>
- struct handle_case_ <context, data, i,
- 0, 1>
-
- : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
- where_),
- mlc_is_a(mlc_comma_2(case_<context, data, i>),
- undefined) >,
- ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
-
- {
- typedef handle_case_ < context, data, i+1,
- mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
- internal::case_true)::value,
- mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
- internal::case_false)::value > next_t;
- typedef mlc_ret(next_t) ret;
- };
-
-
-
- // case_
-
- template <typename context, typename data>
- struct case_
- {
- typedef internal::handle_case_ < context, data, 1,
- mlc_is_a(mlc_comma_2(case_<context, data, 1>),
- internal::case_true)::value,
- mlc_is_a(mlc_comma_2(case_<context, data, 1>),
- internal::case_false)::value > handle_t;
- typedef mlc_ret(handle_t) ret;
- };
-
-
- } // end of namespace mlc::internal
-
-
-
- // FIXME: doc
-
- template <typename context, typename data>
- struct case_
- : private assert_< neq_< mlc_comma_1(typename internal::case_<context, data>::ret),
- none >,
- ERROR::SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA >
- {
- typedef typename internal::case_<context, data>::ret ret;
- };
-
-
- // FIXME: doc
-
- template <typename context, typename data>
- struct switch_
- : private assert_< neq_< mlc_comma_1(typename internal::case_<context, data>::ret),
- none >,
- ERROR::SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA >,
-
- private assert_< neq_< mlc_ret(),
- not_found >,
- ERROR::SWITCH_
- {
- typedef typename internal::case_<context, data>::ret case_t;
- typedef mlc_ret(case_t) ret;
- };
-
-
-} // end of namespace mlc
+# include <mlc/case.hh>
#endif // ! METALIC_SWITCH_HH
Index: mlc/Makefile.am
--- mlc/Makefile.am (revision 416)
+++ mlc/Makefile.am (working copy)
@@ -3,6 +3,7 @@
mlcdir = $(includedir)/mlc
nobase_mlc_HEADERS = \
bool.hh \
+ case.hh \
cmp.hh \
comma.hh \
elt.hh \
@@ -13,6 +14,7 @@
logic.hh \
pair.hh \
properties.hh \
+ ret.hh \
to_string.hh \
type.hh \
typedef.hh \
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Add meta switch-case; disambiguate typedef_.
* tests/case.cc: New file.
* tests/switch.cc (where_): Precise name.
* tests/ret.cc: New file.
* mlc/bool.hh (assert): Remove is_true to avoid cryptic error
message such as "is_true" inaccessible.
* mlc/flags.hh (found): New class.
* mlc/typedef.hh (result2): New inner class to disambiguate between
"typedef is found but its value is not_found" and "typedef is not
found".
(mlc_ret, mlc_decl_typedef(ret)): Move to...
* mlc/ret.hh: ...this new file.
* mlc/switch.hh: Change that makes this file soon obsolete.
* mlc/case.hh: New file.
mlc/bool.hh | 6 -
mlc/case.hh | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mlc/flags.hh | 9 +
mlc/ret.hh | 63 +++++++++++++
mlc/switch.hh | 66 ++++++-------
mlc/typedef.hh | 40 +++++---
tests/case.cc | 65 +++++++++++++
tests/ret.cc | 17 +++
tests/switch.cc | 36 ++++---
9 files changed, 503 insertions(+), 66 deletions(-)
Index: tests/case.cc
--- tests/case.cc (revision 0)
+++ tests/case.cc (revision 0)
@@ -0,0 +1,65 @@
+#include <mlc/is_a.hh>
+#include <mlc/case.hh>
+
+
+struct test;
+
+
+mlc_case_equipment_for_namespace(client);
+
+
+namespace client
+{
+
+ template <class T>
+ struct case_ <test, T, 1> : public mlc::where_< mlc_is_a(T, short) >
+ {
+ };
+
+ template <class T>
+ struct case_ <test, T, 2> : public mlc::where_< mlc_is_a(T, int) >
+ {
+ };
+
+
+ // ok
+
+ template <class T>
+ struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) >
+ {
+ };
+
+
+// // ko
+
+// template <class T>
+// struct case_ <test, T, 0> : public mlc::where_< mlc_is_a(T, char) >
+// {
+// };
+
+// template <class T>
+// struct case_ <test, T, 3>
+// {
+// };
+
+// template <class T>
+// struct default_case_ <test, T> : public mlc::where_< mlc::true_ >
+// {
+// };
+
+
+} // end of namespace client
+
+
+template <class T>
+void print()
+{
+ int tmp;
+}
+
+
+
+int main()
+{
+ print< client::case_<test, char>::ret >();
+}
Index: tests/switch.cc
--- tests/switch.cc (revision 414)
+++ tests/switch.cc (working copy)
@@ -1,45 +1,55 @@
#include <mlc/is_a.hh>
-#include <mlc/switch.hh>
+#include <mlc/case.hh>
struct test;
-namespace mlc
+mlc_case_equipment_for_namespace(client);
+
+
+namespace client
{
template <class T>
- struct case_ <test, T, 1> : public where_< mlc_is_a(T, short) >
+ struct case_ <test, T, 1> : public mlc::where_< mlc_is_a(T, short) >
{
typedef float ret;
};
template <class T>
- struct case_ <test, T, 2> : public where_< mlc_is_a(T, int) >
+ struct case_ <test, T, 2> : public mlc::where_< mlc_is_a(T, int) >
{
typedef double ret;
};
-
// // ok
+ template <class T>
+ struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) >
+ {
+ typedef int ret;
+ };
+
+// // or:
+
// template <class T>
-// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) >
// {
-// typedef int ret;
+// typedef mlc::not_found ret;
// };
// // ko
// template <class T>
-// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// struct case_ <test, T, 0> : public mlc::where_< mlc_is_a(T, char) >
// {
-// typedef not_found ret;
+// typedef int ret;
// };
// template <class T>
-// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) >
// {
// };
@@ -50,7 +60,7 @@
// };
// template <class T>
-// struct default_case_ <test, T> : public where_< mlc::true_ >
+// struct default_case_ <test, T> : public mlc::where_< mlc::true_ >
// {
// typedef int ret;
// };
@@ -61,7 +71,7 @@
// };
-} // end of namespace mlc
+} // end of namespace client
template <class T>
@@ -74,5 +84,5 @@
int main()
{
- print< mlc::switch_<test, char>::ret >();
+ print< client::switch_<test, char>::ret >();
}
Index: tests/ret.cc
--- tests/ret.cc (revision 0)
+++ tests/ret.cc (revision 0)
@@ -0,0 +1,17 @@
+# include <iostream>
+# include <mlc/typedef.hh>
+
+struct yes
+{
+ typedef mlc::dummy ret;
+};
+
+struct no
+{
+};
+
+int main()
+{
+ std::cout << mlc::ret_found_in_<yes>::value << std::endl;
+ std::cout << mlc::ret_found_in_<no>::value << std::endl;
+}
Index: mlc/ret.hh
--- mlc/ret.hh (revision 0)
+++ mlc/ret.hh (revision 0)
@@ -0,0 +1,63 @@
+// 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, 59 Temple Place - Suite 330, 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.
+
+#ifndef METALIC_RET_HH
+# define METALIC_RET_HH
+
+# include <mlc/typedef.hh>
+
+
+
+/*! \FIXME: what's the correct comment flag here?
+**
+** Since we often rely on having a typedef named "ret" in types, we offer
+** a default equipment for this particular typedef. FIXME: doc
+*/
+
+mlc_decl_typedef(ret);
+
+# define mlc_ret(Type) typename typedef_::ret::from_<Type>::ret
+
+
+// test code
+
+# define mlc_ret2(Type) typename typedef_::ret::from_<Type>::ret2
+
+
+namespace mlc
+{
+
+ template <typename T>
+ struct ret_found_in_
+ : public mlc::eq_< typename typedef_::ret::from_<T>::ret2::first_elt,
+ mlc::found >
+ {};
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_RET_HH
Index: mlc/bool.hh
--- mlc/bool.hh (revision 414)
+++ mlc/bool.hh (working copy)
@@ -276,9 +276,8 @@
template <typename bexpr, typename err = no_error_message>
struct assert_ :
- private virtual internal::check_<bexpr, typename bexpr::is_true>
+ public virtual internal::check_<bexpr, typename bexpr::is_true>
{
- typedef dummy is_true;
protected:
assert_() {}
};
@@ -339,6 +338,9 @@
** each expression is true. 3) using "virtual" allow to encompass
** the multiple base class problem.
**
+ ** Limitation: no error message can be provided with this present
+ ** version of multiple_assert_ so prefer using several assert_.
+ **
** \see assert_<bexpr, err>
*/
Index: mlc/flags.hh
--- mlc/flags.hh (revision 414)
+++ mlc/flags.hh (working copy)
@@ -151,6 +151,15 @@
struct not_found : public abstract::flag {};
+ /*! \class mlc::found
+ **
+ ** The class corresponding to "not mlc::not_found".
+ **
+ ** \see mlc::not_found
+ */
+ struct found : public abstract::flag {};
+
+
/*! \class mlc::undefined
**
** Flag class to state that a type is undefined, that is, declared
Index: mlc/typedef.hh
--- mlc/typedef.hh (revision 414)
+++ mlc/typedef.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2005 EPITA Research and Development Laboratory
+// 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
@@ -30,6 +30,8 @@
# include <mlc/flags.hh>
# include <mlc/bool.hh>
+# include <mlc/pair.hh>
+# include <mlc/cmp.hh>
/*! \macro mlc_decl_typedef(TypedefName)
@@ -149,7 +151,7 @@
template <class T> \
static no selector(...); \
\
- template <class T, bool found> \
+ template <class T, bool found_> \
struct result; \
\
template <class T> \
@@ -162,6 +164,21 @@
typedef mlc::not_found ret; \
}; \
\
+ template <class T, bool found_> \
+ struct result2; \
+ \
+ template <class T> \
+ struct result2 <T, true> { \
+ typedef mlc::pair_<mlc::found, \
+ typename T::TypedefName> ret; \
+ }; \
+ \
+ template <class T> \
+ struct result2 <T, false> { \
+ typedef mlc::pair_<mlc::not_found, \
+ mlc::dummy> ret; \
+ }; \
+ \
}; \
\
} \
@@ -181,6 +198,10 @@
typedef \
typename helper_::result<T, found_>::ret \
ret; \
+ \
+ typedef \
+ typename helper_::result2<T, found_>::ret \
+ ret2; \
}; \
\
template <class T, bool b> \
@@ -205,7 +226,7 @@
\
} \
\
-struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n \
/*! \macro mlc_typedef(Type, TypedefName)
@@ -246,17 +267,4 @@
typedef_::TypedefName::from_onlyif_<Type, mlc_bool(Bexpr)>::ret
-
-/*! \FIXME: what's the correct comment flag here?
-**
-** Since we often rely on having a typedef named "ret" in types, we offer
-** a default equipment for this particular typedef. FIXME: doc
-*/
-
-mlc_decl_typedef(ret);
-
-# define mlc_ret(Type) typename typedef_::ret::from_<Type>::ret
-
-
-
#endif // ! METALIC_TYPEDEF_HH
Index: mlc/switch.hh
--- mlc/switch.hh (revision 414)
+++ mlc/switch.hh (working copy)
@@ -57,21 +57,6 @@
{
};
-// template <typename bexpr>
-// struct where_ : public where_<typename bexpr::eval>
-// {
-// };
-
-// template <>
-// struct where_<true_>
-// {
-// };
-
-// template <>
-// struct where_<false_>
-// {
-// };
-
// FIXME: doc
@@ -98,8 +83,8 @@
namespace ERROR
{
- struct A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_;
- struct A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_;
+ struct A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_;
+ struct A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_;
struct SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA;
struct RESULT_IS_NOT_FOUND_IN_default_case_;
template <unsigned i> struct RESULT_IS_NOT_FOUND_IN_case_;
@@ -134,7 +119,7 @@
undefined),
mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
where_) >,
- ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >,
+ ERROR::A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_ >,
private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
undefined),
@@ -146,8 +131,7 @@
typedef default_case_<context, data> current_t;
typedef typename mlc::if_<mlc_is_a(current_t, undefined),
none,
- current_t>::ret case_type;
- typedef mlc_ret(current_t) ret;
+ current_t>::ret ret;
};
@@ -163,12 +147,11 @@
undefined),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_) >,
- ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >
{
typedef handle_default_case_<context, data> last_t;
- typedef typename last_t::case_type case_type;
- typedef typename last_t::ret ret;
+ typedef mlc_ret(last_t) ret;
};
@@ -191,8 +174,7 @@
ERROR::RESULT_IS_NOT_FOUND_IN_case_<i> >
{
- typedef case_<context, data, i> case_type;
- typedef mlc_ret(case_type) ret;
+ typedef case_<context, data, i> ret;
};
@@ -216,24 +198,22 @@
internal::case_true)::value,
mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
internal::case_false)::value > next_t;
- typedef typename next_t::case_type case_type;
- typedef typename next_t::ret ret;
+ typedef mlc_ret(next_t) ret;
};
- // switch_
+ // case_
template <typename context, typename data>
- struct switch_
+ struct case_
{
typedef internal::handle_case_ < context, data, 1,
mlc_is_a(mlc_comma_2(case_<context, data, 1>),
internal::case_true)::value,
mlc_is_a(mlc_comma_2(case_<context, data, 1>),
internal::case_false)::value > handle_t;
- typedef typename handle_t::case_type case_type;
- typedef typename handle_t::ret ret;
+ typedef mlc_ret(handle_t) ret;
};
@@ -244,13 +224,29 @@
// FIXME: doc
template <typename context, typename data>
- struct switch_
- : private assert_< neq_< mlc_comma_1(typename internal::switch_<context, data>::case_type),
+ struct case_
+ : private assert_< neq_< mlc_comma_1(typename internal::case_<context, data>::ret),
none >,
ERROR::SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA >
{
- typedef typename internal::switch_<context, data>::case_type case_type;
- typedef typename internal::switch_<context, data>::ret ret;
+ typedef typename internal::case_<context, data>::ret ret;
+ };
+
+
+ // FIXME: doc
+
+ template <typename context, typename data>
+ struct switch_
+ : private assert_< neq_< mlc_comma_1(typename internal::case_<context, data>::ret),
+ none >,
+ ERROR::SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA >,
+
+ private assert_< neq_< mlc_ret(),
+ not_found >,
+ ERROR::SWITCH_
+ {
+ typedef typename internal::case_<context, data>::ret case_t;
+ typedef mlc_ret(case_t) ret;
};
Index: mlc/case.hh
--- mlc/case.hh (revision 0)
+++ mlc/case.hh (revision 0)
@@ -0,0 +1,267 @@
+// 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, 59 Temple Place - Suite 330, 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.
+
+#ifndef METALIC_CASE_HH
+# define METALIC_CASE_HH
+
+# include <mlc/bool.hh>
+# include <mlc/ret.hh>
+# include <mlc/is_a.hh>
+# include <mlc/implies.hh>
+# include <mlc/comma.hh>
+# include <mlc/cmp.hh>
+# include <mlc/if.hh>
+
+
+// FIXME: doc this file!
+
+
+namespace mlc
+{
+
+ struct case_selected {};
+ struct case_not_selected {};
+
+
+ namespace internal
+ {
+ struct a_simple_case;
+ struct a_switch_case;
+
+ const unsigned unknown_case_id = 10000U;
+ }
+
+
+ namespace ERROR
+ {
+ struct A_case_STATEMENT_SHOULD_NOT_START_AT_INDEX_0_BUT_1;
+ struct A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_;
+ struct A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_;
+ struct NO_case_STATEMENT_CAN_BE_SELECTED;
+ struct A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret;
+ struct A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret;
+ }
+
+
+ template <typename bexpr>
+ struct where_ : public mlc_if_( typename bexpr::eval,
+ case_selected,
+ case_not_selected )
+ {
+ };
+
+
+} // end of namespace mlc
+
+
+
+
+/// \def mlc_case_equipment_for_namespace(NAMESPACE)
+
+# define mlc_case_equipment_for_namespace(NAMESPACE) \
+ \
+namespace NAMESPACE \
+{ \
+ \
+ template <typename context, \
+ typename data, \
+ unsigned i = mlc::internal::unknown_case_id> \
+ struct case_ : public mlc::undefined \
+ { \
+ }; \
+ \
+ \
+ template <typename context, typename data> \
+ struct case_ <context, data, 0> : public mlc::undefined \
+ { \
+ typedef mlc::locked ret; \
+ }; \
+ \
+ \
+ template <typename context, \
+ typename data> \
+ struct default_case_ : public mlc::undefined \
+ { \
+ }; \
+ \
+ \
+ namespace internal \
+ { \
+ \
+ template <typename use, \
+ typename context, typename data, unsigned i, \
+ bool the_ith_case_derives_from_true, \
+ bool the_ith_case_derives_from_false> \
+ struct handle_case_; \
+ \
+ \
+ template <typename use, \
+ typename context, typename data, unsigned i> \
+ struct handle_case_ <use, context, data, i, 1, 1>; \
+ \
+ \
+ template <typename use, typename context, typename data> \
+ struct handle_default_case_ \
+ \
+ : private mlc::assert_< mlc::implies_< mlc_is_not_a(mlc_comma_1(NAMESPACE::default_case_<context, data>), \
+ mlc::undefined), \
+ mlc_is_not_a(mlc_comma_1(NAMESPACE::default_case_<context, data>), \
+ mlc::where_) >, \
+ mlc::ERROR::A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_ >, \
+ \
+ private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \
+ mlc_is_not_a(mlc_comma_1(NAMESPACE::default_case_<context, data>), \
+ mlc::undefined) >, \
+ mlc::ret_found_in_< NAMESPACE::default_case_<context, data> > >, \
+ mlc::ERROR::A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \
+ { \
+ typedef NAMESPACE::default_case_<context, data> case_t; \
+ typedef typename mlc::if_<mlc_is_a(case_t, mlc::undefined), \
+ mlc::none, \
+ case_t>::ret ret; \
+ }; \
+ \
+ \
+ template <typename use, typename context, typename data, unsigned i> \
+ struct handle_case_ <use, context, data, i, 0, 0> \
+ \
+ : private mlc::assert_< mlc::implies_< mlc_is_not_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::undefined), \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::where_) >, \
+ mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ > \
+ { \
+ typedef handle_default_case_<use, context, data> handle_t; \
+ typedef typename handle_t::ret ret; \
+ }; \
+ \
+ \
+ \
+ template <typename use, \
+ typename context, typename data, unsigned i> \
+ struct handle_case_ <use, context, data, i, 1, 0> \
+ \
+ : private mlc::assert_< mlc::or_< mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::where_), \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::undefined) >, \
+ mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >, \
+ \
+ private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \
+ mlc_is_not_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::undefined) >, \
+ mlc::ret_found_in_< NAMESPACE::case_<context, data, i> > >, \
+ mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \
+ { \
+ typedef NAMESPACE::case_<context, data, i> ret; \
+ }; \
+ \
+ \
+ \
+ template <typename use, \
+ typename context, typename data, unsigned i> \
+ struct handle_case_ <use, context, data, i, 0, 1> \
+ \
+ : private mlc::assert_< mlc::or_< mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::where_), \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::undefined) >, \
+ mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >, \
+ \
+ private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \
+ mlc_is_not_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \
+ mlc::undefined) >, \
+ mlc::ret_found_in_< NAMESPACE::case_<context, data, i> > >, \
+ mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \
+ { \
+ typedef handle_case_ < \
+ use, \
+ context, data, i+1, \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i+1>), \
+ mlc::case_selected)::value, \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i+1>), \
+ mlc::case_not_selected)::value > next_t; \
+ typedef typename next_t::ret ret; \
+ }; \
+ \
+ \
+ \
+ template <typename use, typename context, typename data> \
+ struct select_case_ \
+ \
+ : private mlc::assert_< mlc::eq_< mlc_ret(mlc_comma_2(NAMESPACE::case_<context, data, 0>)), \
+ mlc::locked >, \
+ mlc::ERROR::A_case_STATEMENT_SHOULD_NOT_START_AT_INDEX_0_BUT_1 > \
+ { \
+ typedef handle_case_ < \
+ use, \
+ context, data, 1, \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, 1>), \
+ mlc::case_selected)::value, \
+ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, 1>), \
+ mlc::case_not_selected)::value > handle_t; \
+ typedef typename handle_t::ret ret; \
+ }; \
+ \
+ \
+ } \
+ \
+ \
+ template <typename context, typename data> \
+ struct case_ <context, data, mlc::internal::unknown_case_id> \
+ \
+ : private mlc::assert_< mlc::neq_< mlc_comma_2(typename NAMESPACE::internal::select_case_<mlc::internal::a_simple_case, \
+ context, data>::ret), \
+ mlc::none >, \
+ mlc::ERROR::NO_case_STATEMENT_CAN_BE_SELECTED > \
+ \
+ { \
+ typedef typename NAMESPACE::internal::select_case_<mlc::internal::a_simple_case, context, data>::ret ret; \
+ }; \
+ \
+ \
+ template <typename context, typename data> \
+ struct switch_ \
+ \
+ : private mlc::assert_< mlc::neq_< mlc_comma_2(typename NAMESPACE::internal::select_case_<mlc::internal::a_switch_case, \
+ context, data>::ret), \
+ mlc::none >, \
+ mlc::ERROR::NO_case_STATEMENT_CAN_BE_SELECTED > \
+ \
+ { \
+ typedef typename NAMESPACE::internal::select_case_<mlc::internal::a_switch_case, context, data>::ret case_t; \
+ typedef typename case_t::ret ret; \
+ }; \
+ \
+ \
+} \
+ \
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n \
+
+
+
+#endif // ! METALIC_CASE_HH
1
0
Re: [Olena-patches] 414: Revamp the virtual types (aka properties) system.
by Thierry GERAUD 28 Feb '06
by Thierry GERAUD 28 Feb '06
28 Feb '06
Roland Levillain wrote:
> There are still things to be improved, but at least we have (almost)
> all the desired functionality. The missing features that I can see
> ...
> +# define mlc_super_(T) \
> + set_super_type<T>::ret
do we really need to distinguish between set_super and get_super?
2
3
There are still things to be improved, but at least we have (almost)
all the desired functionality. The missing features that I can see
are:
- handling multiple inheritance (both declaration of super classes and
recursive retrieval of vtypes);
- using exact() in typeof_ to fetch vtypes from the exact static type
(needs mlc::any).
I'll try to factor this code (some incriminated sections have been
tagged as such).
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Revamp the virtual types (aka properties) system.
No longer use the C++'s inheritance mechanism to ``pack'' the
internal vtypes of a class. Rely on a metacode algorithm to
recursively look for vtypes in internal and external vtypes
instead, using both the super link and a ``pseudosuper'' link to
visit the upper classes. The set/get classes have been replaced
by a single class (in fact, by two classes, one for internal
vtypes, the other for external vtypes). The pseudosuper link is
used to inherit (or fetch) the vtypes from a given class, without
needing to inherit from this class.
* metalic/mlc/properties.hh (mlc_equip_namespace_with_properties):
Rewrite this macro.
(set_types, set_ext_types): Rename as...
(vtypes, ext_vtypes): ...this.
(get_types, get_ext_type): Remove.
* metalic/tests/properties.cc: Update the test.
Check for new cases (external vtype, pseudo inheritance of
vtypes).
(rec_get_vtype, rec_get_ext_vtype): New.
This class holds the algorithm for the recursive retrieval of
internal/external vtypes.
(typeof_): Adjust.
mlc/properties.hh | 281 +++++++++++++++++++++++++++++++++++-----------------
tests/properties.cc | 95 ++++++++++++-----
2 files changed, 261 insertions(+), 115 deletions(-)
Index: metalic/tests/properties.cc
--- metalic/tests/properties.cc (revision 413)
+++ metalic/tests/properties.cc (working copy)
@@ -14,22 +14,23 @@
namespace my
{
- /*----------------------.
- | Namespace equipment. |
- `----------------------*/
-
- mlc_equip_namespace_with_properties();
-
-
/*-----------.
| Typedefs. |
`-----------*/
- mlc_decl_typedef(ptr_type);
mlc_decl_typedef(foo_type);
mlc_decl_typedef(bar_type);
mlc_decl_typedef(baz_type);
mlc_decl_typedef(quux_type);
+ mlc_decl_typedef(yin_type);
+ mlc_decl_typedef(zorg_type);
+
+
+ /*----------------------.
+ | Namespace equipment. |
+ `----------------------*/
+
+ mlc_equip_namespace_with_properties();
/*-----------.
@@ -43,7 +44,6 @@
}
-
/*----.
| A. |
`----*/
@@ -51,10 +51,9 @@
// Forward declaration.
struct A;
- // FIXME: Rename as set_types<> when mlc/properties.hh is updated.
- // Associated types.
+ /// Types associated to my::A.
template<>
- struct set_types<category::my_cat, my::A>
+ struct vtypes<category::my_cat, my::A>
{
typedef int foo_type;
typedef float bar_type;
@@ -80,47 +79,93 @@
// Warning, this sugar might me remove from properties.hh.
mlc_set_super(B, A);
- /// \brief Redefined types associated to \a B.
- ///
- /// Keeping the inheritance is absolutely capital here (i.e., when
- /// you redefine an associated type with redefine_types).
+ /// Types associated to my::B.
template<>
- struct redefine_types<category::my_cat, B> :
- mlc_super_types_(category::my_cat, B)
+ struct vtypes<category::my_cat, B>
{
+ // (foo is left untouched.)
+
// A type redefined here.
typedef double bar_type;
// A type defined here (but declared abstract in the super class).
typedef char baz_type;
+ // A type defined only here (and not in the super class).
+ typedef long quux_type;
};
- /// \brief New types associated to \a B.
+ /// An external type associated to my::B.
template<>
- struct set_types<category::my_cat, B>
+ struct ext_vtype<category::my_cat, B, typedef_::yin_type>
{
- // A type defined only here (and not in the super class).
- typedef long quux_type;
+ typedef unsigned long ret;
};
- struct B : public mlc_super(B)
+ struct B : public mlc_super_(B)
{
// Aliases.
typedef my_type_of_(B, foo) foo_type;
typedef my_type_of_(B, bar) bar_type;
typedef my_type_of_(B, baz) baz_type;
typedef my_type_of_(B, quux) quux_type;
+ typedef my_type_of_(B, yin) yin_type;
};
+
+
+ /*---.
+ | C. |
+ `---*/
+
+ // Forward declaration.
+ struct C;
+
+ // C do not derive from B, but we want its vtypes to ``inherit''
+ // from B's vtypes (see the specilization
+ // vtypes<category::my_cat, C>.
+
+ /// Types associated to my::C.
+ template<>
+ struct vtypes<category::my_cat, C>
+ {
+ // FIXME: Having this link here is not elegant when you consider
+ // ext_vtype<>: this means that even if you have only a vtype
+ // declared as ext_vtype, you'll still have to define a
+ // corresponding vtypes<>, at least to define the pseudosuper
+ // class. What about externalizing this information, maybe with
+ // set_pseudosuper_type<>, and a macro set_pseudosuper() as sugar?
+
+ /// Link to B (``pseudo'' inheritance).
+ typedef B pseudosuper_type;
+
+ // A type defined only here (and not in the super class).
+ typedef double zorg_type;
+ };
+
+ struct C // no inheritance
+ {
+ // Aliases.
+ typedef my_type_of_(C, foo) foo_type;
+ typedef my_type_of_(C, quux) quux_type;
+ typedef my_type_of_(C, zorg) zorg_type;
+ };
+
}
+
int
main()
{
- // Check associated types.
+ // Check types associated to A.
mlc_eq(my::A::foo_type, int)::ensure ();
mlc_eq(my::A::bar_type, float)::ensure ();
- // Check associated types.
+ // Check types associated to B.
mlc_neq(my::B::bar_type, my::A::bar_type)::ensure ();
mlc_eq(my::B::baz_type, char)::ensure ();
mlc_eq(my::B::quux_type, long)::ensure ();
+ mlc_eq(my::B::yin_type, unsigned long)::ensure ();
+
+ // Check types associated to C.
+ mlc_eq(my::C::foo_type, int)::ensure ();
+ mlc_eq(my::C::quux_type, long)::ensure ();
+ mlc_eq(my::C::zorg_type, double)::ensure ();
}
Index: metalic/mlc/properties.hh
--- metalic/mlc/properties.hh (revision 413)
+++ metalic/mlc/properties.hh (working copy)
@@ -52,9 +52,21 @@
// FIXME: Add support for hierarchies with several super classes.
# define mlc_equip_namespace_with_properties() \
\
- /* ------------------------- */ \
- /* Inheritance declaration. */ \
- /* ------------------------- */ \
+ /* ----------------------- */ \
+ /* Typedefs declarations. */ \
+ /* ----------------------- */ \
+ \
+ /* FIXME: Should we use the `ret' typdef defined in the global */ \
+ /* namespace instead ? (see at the end mlc/typedef.hh). */ \
+ mlc_decl_typedef(ret); \
+ \
+ /* Declare the ``uplink'' typedef (access to a pseudosuper class). */ \
+ mlc_decl_typedef(pseudosuper_type); \
+ \
+ \
+ /* ------------- */ \
+ /* Inheritance. */ \
+ /* ------------- */ \
\
template <typename type> \
struct set_super_type \
@@ -63,58 +75,36 @@
}; \
\
\
- /* ---------------------------------------- */ \
- /* ``Internal'' associated types facility. */ \
- /* ---------------------------------------- */ \
+ /* --------------- */ \
+ /* Virtual types. */ \
+ /* --------------- */ \
\
- /** Fwd decl. */ \
- namespace internal { \
- template <typename category, typename from_type> struct get_types; \
- } \
- \
- /** Specialize this class to set ``internal'' associated types. */ \
+ /** \brief Internal virtual types associated to \a from_type. */ \
+ /** */ \
+ /** Specialize this class for the desired \a from_type. */ \
template <typename category, typename from_type> \
- struct set_types \
+ struct vtypes \
{ \
}; \
\
- /** \brief Specialize this class to redefine ``internal'' */ \
- /** associated types. */ \
- /** */ \
- /** Notice the inheritance relation, which enable the automatic */ \
- /** retrieval of the types associated to the super class of \a */ \
- /** from_type. */ \
- template <typename category, typename from_type> \
- struct redefine_types : public mlc_super_types(category, from_type) \
+ /** End of the recursive construction of any vtypes hierarchy. */ \
+ template <typename category> \
+ struct vtypes<category, mlc::none> \
{ \
}; \
\
- \
- /* ----------------------------------------- */ \
- /* ``External'' associated types machinery. */ \
- /* ----------------------------------------- */ \
- \
- /** Fwd decl. */ \
- namespace internal { \
- template <typename category, typename from_type, typename typedef_type> \
- struct get_ext_type; \
- } \
- \
- /** Specialize this class to set an ``external'' associated type. */ \
+ /** \brief An external virtual type associated to \a from_type. */ \
+ /** */ \
+ /** Specialize this class for the desired \a from_type. */ \
template <typename category, typename from_type, typename typedef_type> \
- struct set_ext_type \
+ struct ext_vtype \
{ \
}; \
\
- /** \brief Specialize this class to redefine an ``external'' */ \
- /** associated type. */ \
- /** */ \
- /** Notice the inheritance relation, which enable the automatic */ \
- /** retrieval of the types associated to the super class of \a */ \
- /** from_type. */ \
- template <typename category, typename from_type, typename typedef_type> \
- struct redefine_ext_type : \
- public mlc_super_ext_type(category, from_type, typedef_type) \
+ /** End of the recursive construction of any ext_vtype<> */ \
+ /** hierarchy. */ \
+ template <typename category, typename typedef_type> \
+ struct ext_vtype<category, mlc::none, typedef_type> \
{ \
}; \
\
@@ -128,34 +118,162 @@
/** retrieval mechanism). */ \
namespace internal \
{ \
- template <typename category, typename from_type> \
- struct get_types : \
- public set_types<category, from_type>, \
- public redefine_types<category, from_type> \
+ /* ------------------------------------------ */ \
+ /* Recursive retrieval of an internal vtype. */ \
+ /* ------------------------------------------ */ \
+ \
+ /* FIXME: Do a basic scheme of the algorithm in pseudo-code. */ \
+ \
+ /* FIXME: Check for mlc::undefined? */ \
+ \
+ /* FIXME: The presence of `vtypes' is the only thing that makes */ \
+ /* this code different from the retrieval within an external */ \
+ /* vtype. How can we factor this? */ \
+ template <typename category, typename from_type, typename typedef_type> \
+ struct rec_get_vtype \
{ \
+ /** Set of vtypes associated with FROM_TYPE. */ \
+ typedef vtypes<category, from_type> types; \
+ /** Typedef in the current vtypes (maybe mlc::not_found). */ \
+ typedef mlc_internal_get_typedef(types, typedef_type) type; \
+ \
+ /** Implicit parent (i.e. super), if any. */ \
+ typedef mlc_super(from_type) super; \
+ /** Pseudosuper class, if any. */ \
+ typedef mlc_internal_get_typedef(types, typedef_::pseudosuper_type) \
+ pseudosuper; \
+ \
+ typedef typename \
+ mlc::if_< \
+ mlc::neq_< type, mlc::not_found >, \
+ /* then */ \
+ /* return it */ \
+ /* (the typedef has been found in the vtypes */ \
+ /* associated to FROM_TYPE) */ \
+ type, \
+ /* else */ \
+ /* check if the vtype of the `super' of FROM_TYPE */ \
+ /* has the typedef */ \
+ typename \
+ mlc::if_< mlc::neq_< typename rec_get_vtype< category, \
+ super, \
+ typedef_type >::ret, \
+ mlc::not_found >, \
+ /* then */ \
+ /* return it */ \
+ typename rec_get_vtype< category, \
+ super, \
+ typedef_type >::ret, \
+ /* else */ \
+ /* check if the FROM_TYPE has a decl_parent */ \
+ /* and try to retrieve the typedef from it. */ \
+ typename rec_get_vtype< category, \
+ pseudosuper, \
+ typedef_type >::ret >::ret >::ret \
+ ret; \
}; \
\
- /** End of the recursive construction of any get_types<> hierarchy. */ \
- template <typename category> \
- struct get_types<category, mlc::none> \
+ /** Ends of the recursive retrieval (mlc::none is at the end of the */ \
+ /** transitive closure of every `super' relation). */ \
+ /** \{ */ \
+ /** Case where \a from_type = mlc::none (end of a recursive */ \
+ /** retrieval following `super' types). */ \
+ template <typename category, typename typedef_type> \
+ struct rec_get_vtype<category, mlc::none, typedef_type> \
+ { \
+ typedef mlc::not_found ret; \
+ }; \
+ /** Case where \a from_type = mlc::not_found (end of a recursive */ \
+ /** retrieval following `super' types). */ \
+ template <typename category, typename typedef_type> \
+ struct rec_get_vtype<category, mlc::not_found, typedef_type> \
{ \
+ typedef mlc::not_found ret; \
}; \
+ /** \} */ \
+ \
+ /* ------------------------------------------ */ \
+ /* Recursive retrieval of an external vtype. */ \
+ /* ------------------------------------------ */ \
+ \
+ /* FIXME: Merge this with rec_get_vtype. */ \
\
template <typename category, typename from_type, typename typedef_type> \
- struct get_ext_type : \
- public set_ext_type<category, from_type, typedef_type>, \
- public redefine_ext_type<category, from_type, typedef_type> \
+ struct rec_get_ext_vtype \
{ \
+ /** Set of vtypes associated with FROM_TYPE. */ \
+ typedef ext_vtype<category, from_type, typedef_type> ext_type; \
+ /** Typedef in the current vtypes (maybe mlc::not_found). */ \
+ typedef mlc_internal_get_typedef(ext_type, typedef_::ret) type; \
+ \
+ /** Implicit parent (i.e. super), if any. */ \
+ typedef mlc_super(from_type) super; \
+ /** Pseudosuper class, if any. */ \
+ /* FIXME: Looking for this information is not elegant. Have a */ \
+ /* look at metalic/tests/properties.cc for a better suggestion. */ \
+ typedef vtypes<category, from_type> types; \
+ typedef mlc_internal_get_typedef(types, typedef_::pseudosuper_type) \
+ pseudosuper; \
+ \
+ typedef typename \
+ mlc::if_< \
+ mlc::neq_< type, mlc::not_found >, \
+ /* then */ \
+ /* return it */ \
+ /* (the typedef has been found in the vtypes */ \
+ /* associated to FROM_TYPE) */ \
+ type, \
+ /* else */ \
+ /* check if the vtype of the `super' of FROM_TYPE */ \
+ /* has the typedef */ \
+ typename \
+ mlc::if_< mlc::neq_< typename rec_get_ext_vtype< category, \
+ super, \
+ typedef_type >::ret, \
+ mlc::not_found >, \
+ /* then */ \
+ /* return it */ \
+ typename rec_get_ext_vtype< category, \
+ super, \
+ typedef_type >::ret, \
+ /* else */ \
+ /* check if the FROM_TYPE has a decl_parent */ \
+ /* and try to retrieve the typedef from it. */ \
+ typename rec_get_ext_vtype< category, \
+ pseudosuper, \
+ typedef_type >::ret>::ret>::ret \
+ ret; \
}; \
\
- /** End of the recursive construction of any get_ext_type<> */ \
- /** hierarchy. */ \
+ /** Ends of the recursive retrieval (mlc::none is at the end of the */ \
+ /** transitive closure of every `super' relation). */ \
+ /** \{ */ \
+ /** Case where \a from_type = mlc::none (end of a recursive */ \
+ /** retrieval following `super' types). */ \
+ template <typename category, typename typedef_type> \
+ struct rec_get_ext_vtype<category, mlc::none, typedef_type> \
+ { \
+ typedef mlc::not_found ret; \
+ }; \
+ /** Case where \a from_type = mlc::not_found (end of a recursive */ \
+ /** retrieval following `super' types). */ \
template <typename category, typename typedef_type> \
- struct get_ext_type<category, mlc::none, typedef_type> \
+ struct rec_get_ext_vtype<category, mlc::not_found, typedef_type> \
{ \
+ typedef mlc::not_found ret; \
}; \
+ /** \} */ \
+ \
+ /* ------------------------------------- */ \
+ /* External/internal typedef selection. */ \
+ /* ------------------------------------- */ \
\
- /** Typedef selector. */ \
+ /** \brief Typedef selector. */ \
+ /** */ \
+ /** A virtual type is considered valid if and only if it has been */ \
+ /** found as an internal vtype or (exclusive) as an external vtype. */ \
+ /** Other cases (no definition or a double definition) are invalid. */ \
+ /** */ \
/** \{ */ \
/** Fwd decl. */ \
template <bool external_typedef_p, bool internal_typedef_p, \
@@ -196,26 +314,21 @@
} /** End of namespace internal. */ \
\
\
- /** FIXME: Don't query from_type directly, but */ \
- /** exact_type(from_type) instead */ \
+ /* FIXME: Don't query from_type directly, but exact_type(from_type) */ \
+ /* instead. We need mlc::any for this. */ \
template <typename category, typename from_type, typename typedef_type> \
struct typeof_ \
{ \
- typedef internal::get_types<category, from_type> types; \
- /* FIXME: Add a check in typeof_ to ensure that get_ext_type */ \
- /* derives from get_ext_type<none> */ \
- typedef \
- internal::get_ext_type<category, from_type, typedef_type> ext_type; \
- /* FIXME: Add a check in typeof_ to ensure that get_ext_type */ \
- /* derives from get_ext_type<none> */ \
- \
- /** Look for the typedef as an external type. */ \
- typedef \
- mlc_internal_get_typedef(ext_type, typedef_::ret) external_typedef; \
- /** Look for the typedef in internal types. */ \
- typedef \
- mlc_internal_get_typedef(types, typedef_type) internal_typedef; \
+ /* Look for the typedef as an external type. */ \
+ typedef typename \
+ internal::rec_get_ext_vtype<category, from_type, typedef_type>::ret \
+ external_typedef; \
+ /* Look for the typedef in internal types. */ \
+ typedef typename \
+ internal::rec_get_vtype<category, from_type, typedef_type>::ret \
+ internal_typedef; \
\
+ /* Did we found the virtual type? */ \
static const bool found_external_p = \
mlc::is_found<external_typedef>::value; \
static const bool found_internal_p = \
@@ -243,25 +356,13 @@
typedef Super ret; \
}
-/// \def Get the immediate base class of T
+/// \def Get the immediate base class of T (version with typename).
# define mlc_super(T) \
- set_super_type<T>::ret
+ typename set_super_type<T>::ret
-// FIXME: Doc.
-# define mlc_super_types(Category, FromType) \
- internal::get_types<Category, typename mlc_super(FromType)>
-
-// FIXME: Doc.
-# define mlc_super_types_(Category, FromType) \
- internal::get_types<Category, mlc_super(FromType)>
-
-// FIXME: Doc.
-# define mlc_super_ext_type(Category, FromType, Typedef) \
- internal::get_ext_type<Category, typename mlc_super(FromType), Typedef>
-
-// FIXME: Doc.
-# define mlc_super_ext_type_(Category, FromType, Typedef) \
- internal::get_ext_type<Category, mlc_super(FromType), Typedef>
+/// \def Get the immediate base class of T (version without typename).
+# define mlc_super_(T) \
+ set_super_type<T>::ret
/// Get the property \a Typedef from \a FromType (version with typename).
#define mlc_typeof(Category, FromType, Typedef) \
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Enhance error handling in mlc::switch_.
* tests/switch.cc: New file.
* mlc/switch.hh (case_true, case_false): New classes.
(case_type): New typedef in classes.
(case_, switch_): Modify error handling.
mlc/switch.hh | 107 +++++++++++++++++++++++++++++++++++++++++++++++---------
tests/switch.cc | 78 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 168 insertions(+), 17 deletions(-)
Index: tests/switch.cc
--- tests/switch.cc (revision 0)
+++ tests/switch.cc (revision 0)
@@ -0,0 +1,78 @@
+#include <mlc/is_a.hh>
+#include <mlc/switch.hh>
+
+
+struct test;
+
+
+namespace mlc
+{
+
+ template <class T>
+ struct case_ <test, T, 1> : public where_< mlc_is_a(T, short) >
+ {
+ typedef float ret;
+ };
+
+ template <class T>
+ struct case_ <test, T, 2> : public where_< mlc_is_a(T, int) >
+ {
+ typedef double ret;
+ };
+
+
+// // ok
+
+// template <class T>
+// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// {
+// typedef int ret;
+// };
+
+
+// // ko
+
+// template <class T>
+// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// {
+// typedef not_found ret;
+// };
+
+// template <class T>
+// struct case_ <test, T, 3> : public where_< mlc_is_a(T, char) >
+// {
+// };
+
+// template <class T>
+// struct case_ <test, T, 3>
+// {
+// typedef int ret;
+// };
+
+// template <class T>
+// struct default_case_ <test, T> : public where_< mlc::true_ >
+// {
+// typedef int ret;
+// };
+
+// template <class T>
+// struct default_case_ <test, T>
+// {
+// };
+
+
+} // end of namespace mlc
+
+
+template <class T>
+void print()
+{
+ int tmp;
+}
+
+
+
+int main()
+{
+ print< mlc::switch_<test, char>::ret >();
+}
Index: mlc/switch.hh
--- mlc/switch.hh (revision 412)
+++ mlc/switch.hh (working copy)
@@ -34,6 +34,7 @@
# include <mlc/implies.hh>
# include <mlc/comma.hh>
# include <mlc/cmp.hh>
+# include <mlc/if.hh>
namespace mlc
@@ -41,11 +42,36 @@
// FIXME: doc
+ namespace internal
+ {
+ struct case_true {};
+ struct case_false {};
+
+ } // end of namespace mlc::internal
+
+
template <typename bexpr>
- struct where_ : public bexpr::eval
+ struct where_ : public mlc_if_( typename bexpr::eval,
+ internal::case_true,
+ internal::case_false )
{
};
+// template <typename bexpr>
+// struct where_ : public where_<typename bexpr::eval>
+// {
+// };
+
+// template <>
+// struct where_<true_>
+// {
+// };
+
+// template <>
+// struct where_<false_>
+// {
+// };
+
// FIXME: doc
@@ -57,6 +83,7 @@
{
};
+
template <typename context,
typename data>
struct case_ <context, data, 0>;
@@ -73,7 +100,9 @@
{
struct A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_;
struct A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_;
- struct RESULT_NOT_FOUND;
+ struct SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA;
+ struct RESULT_IS_NOT_FOUND_IN_default_case_;
+ template <unsigned i> struct RESULT_IS_NOT_FOUND_IN_case_;
} // end of namespace mlc::ERROR
@@ -87,81 +116,124 @@
struct handle_case_;
+
// impossible situation
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
1, 1>;
+
+
+ // default case
+
template <typename context, typename data>
struct handle_default_case_
+
: private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
undefined),
mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
where_) >,
- ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >
+ ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >,
+
+ private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
+ undefined),
+ neq_<mlc_ret(mlc_comma_1(default_case_<context, data>)),
+ not_found> >,
+ ERROR::RESULT_IS_NOT_FOUND_IN_default_case_ >
+
{
- typedef mlc_ret( mlc_comma_1(default_case_<context, data>) ) ret;
+ typedef default_case_<context, data> current_t;
+ typedef typename mlc::if_<mlc_is_a(current_t, undefined),
+ none,
+ current_t>::ret case_type;
+ typedef mlc_ret(current_t) ret;
};
+
+
// there is no more user-defined cases
- // so go to the default case
+ // so go to the default case (the last case handled here)
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
0, 0>
+
: private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
undefined),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_) >,
ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+
{
- typedef mlc_ret( mlc_comma_1(handle_default_case_<context, data>) ) ret;
+ typedef handle_default_case_<context, data> last_t;
+ typedef typename last_t::case_type case_type;
+ typedef typename last_t::ret ret;
};
// current case is the one
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
1, 0>
+
: private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
undefined) >,
- ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >,
+
+ private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
+ undefined),
+ neq_<mlc_ret(mlc_comma_2(case_<context, data, i>)),
+ not_found> >,
+ ERROR::RESULT_IS_NOT_FOUND_IN_case_<i> >
+
{
- typedef mlc_ret( mlc_comma_2(case_<context, data, i>) ) ret;
+ typedef case_<context, data, i> case_type;
+ typedef mlc_ret(case_type) ret;
};
+
// current case is not the one
// so go to the next case
+
template <typename context, typename data, unsigned i>
struct handle_case_ <context, data, i,
0, 1>
+
: private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
where_),
mlc_is_a(mlc_comma_2(case_<context, data, i>),
undefined) >,
ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+
{
typedef handle_case_ < context, data, i+1,
mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
- true_)::value,
+ internal::case_true)::value,
mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
- false_)::value > next_t;
+ internal::case_false)::value > next_t;
+ typedef typename next_t::case_type case_type;
typedef typename next_t::ret ret;
};
+
// switch_
+
template <typename context, typename data>
struct switch_
{
- typedef typename internal::handle_case_ < context, data, 1,
+ typedef internal::handle_case_ < context, data, 1,
mlc_is_a(mlc_comma_2(case_<context, data, 1>),
- true_)::value,
+ internal::case_true)::value,
mlc_is_a(mlc_comma_2(case_<context, data, 1>),
- false_)::value
- >::ret ret;
+ internal::case_false)::value > handle_t;
+ typedef typename handle_t::case_type case_type;
+ typedef typename handle_t::ret ret;
};
@@ -173,10 +245,11 @@
template <typename context, typename data>
struct switch_
- : private assert_< neq_<typename internal::switch_<context, data>::ret,
- not_found>,
- ERROR::RESULT_NOT_FOUND >
+ : private assert_< neq_< mlc_comma_1(typename internal::switch_<context, data>::case_type),
+ none >,
+ ERROR::SWITCH_DOES_NOT_HAVE_A_CASE_FOR_YOUR_DATA >
{
+ typedef typename internal::switch_<context, data>::case_type case_type;
typedef typename internal::switch_<context, data>::ret ret;
};
1
0
17 Feb '06
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Modify mlc::assert_ to handle explicit error messages; also.
* mlc/elt.hh: Fix bug.
* mlc/pair.hh: Add explicit error messages.
* mlc/valist.hh: Likewise.
* mlc/bool.hh (ASSERTION_FAILED_, AN_ASSERTION_FAILED_): Remove
so that error messages are more concise.
(iff_, mlc_iff): Rename as...
(type_iff_, mlc_type_iff): ...these.
(assert_): Update.
* mlc/switch.hh: New.
* mlc/is_a.hh (internal::is_a): Move and rename as...
(is_a_): ...this so error messages are shortern.
* mlc/cmp.hh: Pretty print.
bool.hh | 85 ++++++++++------------------
cmp.hh | 0
elt.hh | 4 -
is_a.hh | 67 ++++++++++++----------
pair.hh | 12 +++
switch.hh | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
valist.hh | 16 ++++-
7 files changed, 281 insertions(+), 90 deletions(-)
Index: mlc/elt.hh
--- mlc/elt.hh (revision 411)
+++ mlc/elt.hh (working copy)
@@ -29,9 +29,9 @@
# define METALIC_ELT_HH
-# define mlc_elt(Type, Ith) typename Type::template elt<I>::ret
+# define mlc_elt(Type, Index) typename Type::template elt<Index>::ret
-# define mlc_elt_(Type, Ith) Type::template elt<I>::ret
+# define mlc_elt_(Type, Index) Type::template elt<Index>::ret
Index: mlc/pair.hh
--- mlc/pair.hh (revision 411)
+++ mlc/pair.hh (working copy)
@@ -46,6 +46,15 @@
} // end of namespace mlc::internal
+
+ namespace ERROR
+ {
+ struct PAIR_ELT_INDEX_SHOULD_BE_1_OR_2;
+
+ } // end of namespace mlc::ERROR
+
+
+
/*! \class mlc::pair_<E1, E2>
**
** This class is FIXME */
@@ -60,7 +69,8 @@
template <unsigned i>
struct elt : private assert_< or_< uint_equal_<i, 1>,
- uint_equal_<i, 2> > >,
+ uint_equal_<i, 2> >,
+ ERROR::PAIR_ELT_INDEX_SHOULD_BE_1_OR_2 >,
public internal::pair_elt_<E1, E2, i>
{
};
Index: mlc/bool.hh
--- mlc/bool.hh (revision 411)
+++ mlc/bool.hh (working copy)
@@ -42,12 +42,12 @@
-/*! \def mlc_iff(Type, BExpr)
+/*! \def mlc_type_iff(Type, BExpr)
**
** FIXME: doc
*/
-# define mlc_iff(Type, BExpr) typename mlc::iff_<Type, BExpr>::ret
-# define mlc_iff_(Type, BExpr) mlc::iff_<Type, BExpr>::ret
+# define mlc_type_iff(Type, BExpr) typename mlc::type_iff_<Type, BExpr>::ret
+# define mlc_type_iff_(Type, BExpr) mlc::type_iff_<Type, BExpr>::ret
@@ -196,41 +196,6 @@
{
};
-
- // FIXME: doc
-
- template <typename bexpr, typename err>
- struct ASSERTION_FAILED_ :
- private virtual check_<bexpr, typename bexpr::is_true>
- {
- };
-
-
- // FIXME: doc
-
- template <typename bexpr1,
- typename bexpr2,
- typename bexpr3,
- typename bexpr4,
- typename bexpr5,
- typename bexpr6,
- typename bexpr7,
- typename bexpr8,
- typename bexpr9>
- struct AN_ASSERTION_FAILED_ :
- private virtual check_item_<1, bexpr1, typename bexpr1::is_true>,
- private virtual check_item_<2, bexpr2, typename bexpr2::is_true>,
- private virtual check_item_<3, bexpr3, typename bexpr3::is_true>,
- private virtual check_item_<4, bexpr4, typename bexpr4::is_true>,
- private virtual check_item_<5, bexpr5, typename bexpr5::is_true>,
- private virtual check_item_<6, bexpr6, typename bexpr6::is_true>,
- private virtual check_item_<7, bexpr7, typename bexpr7::is_true>,
- private virtual check_item_<8, bexpr8, typename bexpr8::is_true>,
- private virtual check_item_<9, bexpr9, typename bexpr9::is_true>
- {
- };
-
-
} // end of namespace mlc::internal
@@ -310,27 +275,40 @@
*/
template <typename bexpr, typename err = no_error_message>
- struct assert_ : public internal::ASSERTION_FAILED_<bexpr, err>
+ struct assert_ :
+ private virtual internal::check_<bexpr, typename bexpr::is_true>
{
- static void run() {}
+ typedef dummy is_true;
protected:
assert_() {}
};
- /*! \class mlc::iff_<T, bexpr>
+ /*! \class mlc::type_iff_<T, bexpr>
**
** FIXME: doc
- ** T iff bexpr
+ ** returns type T iff bexpr
*/
template <typename T, typename bexpr>
- struct iff_ :
+ struct type_iff_ :
private assert_<bexpr>
{
typedef T ret;
};
+ /*! \class mlc::literal_<T>
+ **
+ ** FIXME: doc
+ */
+
+ template <typename T>
+ struct literal_
+ {
+ typedef T ret;
+ };
+
+
/*! \class mlc::multiple_assert_<bexpr1..>
**
** FIXME: this doc is partially obsolete!
@@ -373,23 +351,22 @@
typename bexpr7 = no_bexpr,
typename bexpr8 = no_bexpr,
typename bexpr9 = no_bexpr>
- struct multiple_assert_ : public internal::AN_ASSERTION_FAILED_<bexpr1,
- bexpr2,
- bexpr3,
- bexpr4,
- bexpr5,
- bexpr6,
- bexpr7,
- bexpr8,
- bexpr9>
+ struct multiple_assert_ :
+ private virtual internal::check_item_<1, bexpr1, typename bexpr1::is_true>,
+ private virtual internal::check_item_<2, bexpr2, typename bexpr2::is_true>,
+ private virtual internal::check_item_<3, bexpr3, typename bexpr3::is_true>,
+ private virtual internal::check_item_<4, bexpr4, typename bexpr4::is_true>,
+ private virtual internal::check_item_<5, bexpr5, typename bexpr5::is_true>,
+ private virtual internal::check_item_<6, bexpr6, typename bexpr6::is_true>,
+ private virtual internal::check_item_<7, bexpr7, typename bexpr7::is_true>,
+ private virtual internal::check_item_<8, bexpr8, typename bexpr8::is_true>,
+ private virtual internal::check_item_<9, bexpr9, typename bexpr9::is_true>
{
- static void run() {}
protected:
multiple_assert_() {}
};
-
/*! \class mlc::bool_<true>
**
** Specialization of mlc::bool_<b> for b set to true. This type
Index: mlc/switch.hh
--- mlc/switch.hh (revision 0)
+++ mlc/switch.hh (revision 0)
@@ -0,0 +1,187 @@
+// 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, 59 Temple Place - Suite 330, 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.
+
+#ifndef METALIC_SWITCH_HH
+# define METALIC_SWITCH_HH
+
+# include <mlc/bool.hh>
+# include <mlc/typedef.hh>
+# include <mlc/is_a.hh>
+# include <mlc/implies.hh>
+# include <mlc/comma.hh>
+# include <mlc/cmp.hh>
+
+
+namespace mlc
+{
+
+ // FIXME: doc
+
+ template <typename bexpr>
+ struct where_ : public bexpr::eval
+ {
+ };
+
+
+
+ // FIXME: doc
+
+ template <typename context,
+ typename data,
+ unsigned i>
+ struct case_ : public undefined
+ {
+ };
+
+ template <typename context,
+ typename data>
+ struct case_ <context, data, 0>;
+
+
+ template <typename context,
+ typename data>
+ struct default_case_ : public undefined
+ {
+ };
+
+
+ namespace ERROR
+ {
+ struct A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_;
+ struct A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_;
+ struct RESULT_NOT_FOUND;
+
+ } // end of namespace mlc::ERROR
+
+
+ namespace internal
+ {
+
+ template <typename context, typename data, unsigned i,
+ bool the_ith_case_derives_from_true,
+ bool the_ith_case_derives_from_false>
+ struct handle_case_;
+
+
+ // impossible situation
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 1, 1>;
+
+ template <typename context, typename data>
+ struct handle_default_case_
+ : private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
+ undefined),
+ mlc_is_not_a(mlc_comma_1(default_case_<context, data>),
+ where_) >,
+ ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ >
+ {
+ typedef mlc_ret( mlc_comma_1(default_case_<context, data>) ) ret;
+ };
+
+ // there is no more user-defined cases
+ // so go to the default case
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 0, 0>
+ : private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>),
+ undefined),
+ mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ where_) >,
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ {
+ typedef mlc_ret( mlc_comma_1(handle_default_case_<context, data>) ) ret;
+ };
+
+
+ // current case is the one
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 1, 0>
+ : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ where_),
+ mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ undefined) >,
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ {
+ typedef mlc_ret( mlc_comma_2(case_<context, data, i>) ) ret;
+ };
+
+
+ // current case is not the one
+ // so go to the next case
+ template <typename context, typename data, unsigned i>
+ struct handle_case_ <context, data, i,
+ 0, 1>
+ : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ where_),
+ mlc_is_a(mlc_comma_2(case_<context, data, i>),
+ undefined) >,
+ ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ >
+ {
+ typedef handle_case_ < context, data, i+1,
+ mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
+ true_)::value,
+ mlc_is_a(mlc_comma_2(case_<context, data, i+1>),
+ false_)::value > next_t;
+ typedef typename next_t::ret ret;
+ };
+
+
+ // switch_
+ template <typename context, typename data>
+ struct switch_
+ {
+ typedef typename internal::handle_case_ < context, data, 1,
+ mlc_is_a(mlc_comma_2(case_<context, data, 1>),
+ true_)::value,
+ mlc_is_a(mlc_comma_2(case_<context, data, 1>),
+ false_)::value
+ >::ret ret;
+ };
+
+
+ } // end of namespace mlc::internal
+
+
+
+ // FIXME: doc
+
+ template <typename context, typename data>
+ struct switch_
+ : private assert_< neq_<typename internal::switch_<context, data>::ret,
+ not_found>,
+ ERROR::RESULT_NOT_FOUND >
+ {
+ typedef typename internal::switch_<context, data>::ret ret;
+ };
+
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_SWITCH_HH
Index: mlc/valist.hh
--- mlc/valist.hh (revision 411)
+++ mlc/valist.hh (working copy)
@@ -46,7 +46,6 @@
# define mlc_internal_valist_elt_spe(I) \
template < mlc_internal_valist_decl_params_ > \
struct valist_elt_ < mlc_internal_valist_params_, I > \
- : private assert_< neq_<E##I, internal::valist_none> > \
{ \
typedef E##I ret; \
}
@@ -74,6 +73,15 @@
**
** This class is FIXME */
+
+ namespace ERROR
+ {
+ struct VALIST_ELT_INDEX_SHOULD_BE_1_OR_GREATER;
+ struct VALIST_ELT_INDEX_IS_GREATER_THAN_LIST_SIZE;
+
+ } // end of namespace mlc::ERROR
+
+
template < typename E1 = internal::valist_none,
typename E2 = internal::valist_none,
typename E3 = internal::valist_none,
@@ -89,8 +97,10 @@
valist_<mlc_internal_valist_params_> >::value;
template <unsigned i>
- struct elt : private multiple_assert_< uint_greater_or_equal_<i, 1>,
- uint_less_or_equal_<i, size_value> >,
+ struct elt : private assert_< uint_greater_or_equal_<i, 1>,
+ ERROR::VALIST_ELT_INDEX_SHOULD_BE_1_OR_GREATER >,
+ private assert_< uint_less_or_equal_<i, size_value>,
+ ERROR::VALIST_ELT_INDEX_IS_GREATER_THAN_LIST_SIZE >,
public internal::valist_elt_<mlc_internal_valist_params_, i>
{
};
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 411)
+++ mlc/is_a.hh (working copy)
@@ -34,7 +34,7 @@
// private macro so do _not_ use it
# define mlc_internal_is_a_result_ \
-sizeof(helper<T,U>::select((T*)helper<T,U>::makeT())) == sizeof(yes_)
+sizeof(helper<T,U>::select((T*)helper<T,U>::makeT())) == sizeof(internal::yes_)
namespace mlc
@@ -81,25 +81,27 @@
typedef char yes_;
struct no_ { char dummy[2]; };
+ } // end of namespace mlc::internal
+
- // dev note : below, is_a<T,id> is a better factorization
+ // dev note : below, is_a_<T,id> is a better factorization
// but g++ 2.95.4 has some trouble with it
template<unsigned id>
- struct is_a;
+ struct is_a_;
// class_
template<>
- struct is_a< form::class_ >
+ struct is_a_< form::class_ >
{
- typedef is_a< form::class_ > self;
+ typedef is_a_< form::class_ > self;
template<class T, class U>
struct helper
{
- static yes_ select(U*);
- static no_ select(...);
+ static internal::yes_ select(U*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -113,16 +115,16 @@
// template_l_class_r_class_
template<>
- struct is_a< form::template_l_class_r_class_ >
+ struct is_a_< form::template_l_class_r_class_ >
{
- typedef is_a< form::template_l_class_r_class_ > self;
+ typedef is_a_< form::template_l_class_r_class_ > self;
template<class T, template < class > class U>
struct helper
{
template<class V>
- static yes_ select(U<V>*);
- static no_ select(...);
+ static internal::yes_ select(U<V>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -136,16 +138,16 @@
// template_l_class_class_r_class_
template<>
- struct is_a< form::template_l_class_class_r_class_ >
+ struct is_a_< form::template_l_class_class_r_class_ >
{
- typedef is_a< form::template_l_class_class_r_class_ > self;
+ typedef is_a_< form::template_l_class_class_r_class_ > self;
template<class T, template < class,class > class U>
struct helper
{
template<class V, class W>
- static yes_ select(U<V,W>*);
- static no_ select(...);
+ static internal::yes_ select(U<V,W>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -158,16 +160,16 @@
// template_l_template_l_class_r_class_r_class_
template<>
- struct is_a< form::template_l_template_l_class_r_class_r_class_ >
+ struct is_a_< form::template_l_template_l_class_r_class_r_class_ >
{
- typedef is_a< form::template_l_template_l_class_r_class_r_class_ > self;
+ typedef is_a_< form::template_l_template_l_class_r_class_r_class_ > self;
template<class T, template < template < class > class > class U>
struct helper
{
template<template<class> class V>
- static yes_ select(U<V>*);
- static no_ select(...);
+ static internal::yes_ select(U<V>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -180,16 +182,16 @@
// template_l_template_l_class_class_r_class_r_class_
template<>
- struct is_a< form::template_l_template_l_class_class_r_class_r_class_ >
+ struct is_a_< form::template_l_template_l_class_class_r_class_r_class_ >
{
- typedef is_a< form::template_l_template_l_class_class_r_class_r_class_ > self;
+ typedef is_a_< form::template_l_template_l_class_class_r_class_r_class_ > self;
template<class T, template < template < class,class > class > class U>
struct helper
{
template<template<class,class> class V>
- static yes_ select(U<V>*);
- static no_ select(...);
+ static internal::yes_ select(U<V>*);
+ static internal::no_ select(...);
static T* makeT();
};
@@ -199,7 +201,6 @@
{};
};
- } // end of namespace mlc::internal
} // end of namespace mlc
@@ -237,19 +238,25 @@
*/
# define mlc_is_a(T, U) \
-mlc::wrap_<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > >
+mlc::wrap_< typename mlc::is_a_<sizeof(mlc::form::of<U >())>::ret<T,U > >
+# define mlc_is_a_(T, U) \
+mlc::is_a_< sizeof(mlc::form::of<U >())>::ret<T,U >
-/*! \def mlc_is_a_(T, U)
+
+/*! \def mlc_is_not_a(T, U)
**
-** Macro equivalent as mlc_is_a(T, U) for use in a non templated
-** context. The result is a Boolean expression type.
+** Macro equivalent as "not mlc_is_a(T, U)". The result is a Boolean
+** expression type.
**
** \see mlc_is_a(T, U)
*/
-# define mlc_is_a_(T, U) \
-mlc::wrap_<mlc::internal::is_a< sizeof(mlc::form::of<U >())>::ret<T,U > >
+# define mlc_is_not_a(T, U) \
+mlc::not_< typename mlc::is_a_<sizeof(mlc::form::of<U >())>::ret<T,U > >
+
+# define mlc_is_not_a_(T, U) \
+mlc::not_< mlc::is_a_< sizeof(mlc::form::of<U >())>::ret<T,U > >
#endif // ! METALIC_IS_A_HH
Index: mlc/cmp.hh
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
Sorry for the ugly diff (damn macros !). Reading the new
mlc/properties.hh is probably easier.
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Switch to the new properties system.
* mlc/properties.hh: Switch to the new properties system.
* tests/properties.cc: Adjust test.
mlc/properties.hh | 307 ++++++++++++++++++++++++++++------------------------
tests/properties.cc | 72 +++---------
2 files changed, 189 insertions(+), 190 deletions(-)
Index: tests/properties.cc
--- tests/properties.cc (revision 409)
+++ tests/properties.cc (working copy)
@@ -1,7 +1,4 @@
-#include <ostream>
-
#include <mlc/properties.hh>
-#include <mlc/to_string.hh>
#include <mlc/cmp.hh>
@@ -11,6 +8,9 @@
// browse mlc/properties.hh so as to make a list of the features to be
// checked.
+// Helper macro.
+#define my_type_of_(FromType, Typedef) \
+ mlc_typeof_(my::category::my_cat, FromType, Typedef)
namespace my
{
@@ -42,46 +42,8 @@
struct my_cat;
}
- template <>
- struct set_default_props < category::my_cat >
- {
- typedef mlc::undefined ptr_type;
- };
-
- /* FIXME: In the current version of SCOOP 2, this ``packing'' is no
- longer done at this stage, but thanks to the `get_types'
- mechanism. */
- /// Retrieval of any image type properties (FIXME: say 'packing').
- template <typename T>
- struct get_props < category::my_cat, T >
- {
- typedef char ptr_type;
-
- // FIXME: Same remark as in the above FIXME: this echo() method
- // should be place lower in the prop/type hierarchy.
- static void echo(std::ostream& ostr)
- {
- ostr << "props_of( oln::category::point, "
- << mlc_to_string(T) << " ) =" << std::endl
- << "{" << std::endl
- << "\t ptr_type = " << mlc_to_string(ptr_type) << std::endl
- << "}" << std::endl;
- }
-
- static void ensure()
- {
- mlc::is_ok< ptr_type >::ensure();
- }
- };
-
-}
-// Helper macro.
-#define my_type_of_(FromType, Alias) \
- mlc_type_of_(my, my::category::my_cat, FromType, Alias)
-namespace my
-{
/*----.
| A. |
`----*/
@@ -92,7 +54,7 @@
// FIXME: Rename as set_types<> when mlc/properties.hh is updated.
// Associated types.
template<>
- struct set_props<category::my_cat, my::A>
+ struct set_types<category::my_cat, my::A>
{
typedef int foo_type;
typedef float bar_type;
@@ -115,28 +77,32 @@
// Forward declaration.
struct B;
- // FIXME: Is there any `set_super_type(T)'' sugar available?
- template<>
- struct set_super_type<my::B>
- {
- typedef A ret;
- };
+ // Warning, this sugar might me remove from properties.hh.
+ mlc_set_super(B, A);
+ /// \brief Redefined types associated to \a B.
+ ///
+ /// Keeping the inheritance is absolutely capital here (i.e., when
+ /// you redefine an associated type with redefine_types).
template<>
- struct set_props<category::my_cat, B>
+ struct redefine_types<category::my_cat, B> :
+ mlc_super_types_(category::my_cat, B)
{
- // Note: foo_type is untouched here.
-
// A type redefined here.
typedef double bar_type;
// A type defined here (but declared abstract in the super class).
typedef char baz_type;
+ };
+
+ /// \brief New types associated to \a B.
+ template<>
+ struct set_types<category::my_cat, B>
+ {
// A type defined only here (and not in the super class).
typedef long quux_type;
};
- // FIXME: Is there any `set_super_type(T)'' sugar available?
- struct B : public internal::get_super_type<B>
+ struct B : public mlc_super(B)
{
// Aliases.
typedef my_type_of_(B, foo) foo_type;
Index: mlc/properties.hh
--- mlc/properties.hh (revision 409)
+++ mlc/properties.hh (working copy)
@@ -25,6 +25,11 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
+// \file mlc/properties.hh
+// \brief Property mechanism.
+//
+// From Theo's presentation (olena-06-jan.pdf).
+
#ifndef METALIC_PROPERTIES_HH
# define METALIC_PROPERTIES_HH
@@ -34,209 +39,237 @@
# include <mlc/cmp.hh>
# include <mlc/if.hh>
# include <mlc/is_a.hh>
-# include <mlc/implies.hh>
-// Note: TypedefName must be of the form `typedef_::foo'.
-# define mlc_internal_get_typedef_(Type, TypedefName) \
- typename TypedefName::template from_< Type >::ret
+/*------------.
+| Equipment. |
+`------------*/
+
+// Note: TypedefName *must* be of the form `typedef_::foo'.
+# define mlc_internal_get_typedef(Type, TypedefName) \
+ typename TypedefName::template from_< Type >::ret
+// FIXME: Add support for hierarchies with several super classes.
# define mlc_equip_namespace_with_properties() \
\
- template <template <typename> class abstraction> \
- struct is_a \
- { \
- template <typename E> \
- struct instantiated_with \
- { \
- typedef abstraction<E> ret; \
- }; \
- }; \
+ /* ------------------------- */ \
+ /* Inheritance declaration. */ \
+ /* ------------------------- */ \
\
- template <typename type, unsigned i = 0> \
+ template <typename type> \
struct set_super_type \
{ \
typedef mlc::none ret; \
}; \
\
- template <typename type, unsigned i = 0> \
- struct set_category \
- { \
- typedef mlc::none ret; \
- }; \
\
- template <typename category> \
- struct set_default_props \
+ /* ---------------------------------------- */ \
+ /* ``Internal'' associated types facility. */ \
+ /* ---------------------------------------- */ \
+ \
+ /** Fwd decl. */ \
+ namespace internal { \
+ template <typename category, typename from_type> struct get_types; \
+ } \
+ \
+ /** Specialize this class to set ``internal'' associated types. */ \
+ template <typename category, typename from_type> \
+ struct set_types \
{ \
}; \
\
- template <typename category, typename type> \
- struct set_props \
+ /** \brief Specialize this class to redefine ``internal'' */ \
+ /** associated types. */ \
+ /** */ \
+ /** Notice the inheritance relation, which enable the automatic */ \
+ /** retrieval of the types associated to the super class of \a */ \
+ /** from_type. */ \
+ template <typename category, typename from_type> \
+ struct redefine_types : public mlc_super_types(category, from_type) \
{ \
}; \
\
- template <typename category, typename type> \
- struct get_props \
+ \
+ /* ----------------------------------------- */ \
+ /* ``External'' associated types machinery. */ \
+ /* ----------------------------------------- */ \
+ \
+ /** Fwd decl. */ \
+ namespace internal { \
+ template <typename category, typename from_type, typename typedef_type> \
+ struct get_ext_type; \
+ } \
+ \
+ /** Specialize this class to set an ``external'' associated type. */ \
+ template <typename category, typename from_type, typename typedef_type> \
+ struct set_ext_type \
{ \
}; \
\
+ /** \brief Specialize this class to redefine an ``external'' */ \
+ /** associated type. */ \
+ /** */ \
+ /** Notice the inheritance relation, which enable the automatic */ \
+ /** retrieval of the types associated to the super class of \a */ \
+ /** from_type. */ \
template <typename category, typename from_type, typename typedef_type> \
- struct set_type \
+ struct redefine_ext_type : \
+ public mlc_super_ext_type(category, from_type, typedef_type) \
{ \
}; \
\
- namespace internal \
- { \
\
- template <typename type, unsigned i = 0> \
- struct get_super_type : public set_super_type <type, i> \
- { \
- }; \
+ /* -------------------- */ \
+ /* Internal machinery. */ \
+ /* -------------------- */ \
\
- template <typename type, unsigned i = 0> \
- struct get_category : public set_category <type, i> \
+ /** The classes enclosed in this namespace must not be specialized */ \
+ /** by the user (they are part of the automatic associated types */ \
+ /** retrieval mechanism). */ \
+ namespace internal \
+ { \
+ template <typename category, typename from_type> \
+ struct get_types : \
+ public set_types<category, from_type>, \
+ public redefine_types<category, from_type> \
{ \
}; \
\
+ /** End of the recursive construction of any get_types<> hierarchy. */ \
template <typename category> \
- struct get_default_props : public set_default_props <category> \
+ struct get_types<category, mlc::none> \
{ \
}; \
\
- template <typename category, typename type> \
- struct get_props : public set_props <category, type> \
+ template <typename category, typename from_type, typename typedef_type> \
+ struct get_ext_type : \
+ public set_ext_type<category, from_type, typedef_type>, \
+ public redefine_ext_type<category, from_type, typedef_type> \
{ \
}; \
\
- template <typename category, typename from_type, typename typedef_type> \
- struct get_type : public set_type <category, from_type, typedef_type> \
- { \
- ~get_type() \
+ /** End of the recursive construction of any get_ext_type<> */ \
+ /** hierarchy. */ \
+ template <typename category, typename typedef_type> \
+ struct get_ext_type<category, mlc::none, typedef_type> \
{ \
- typedef set_type <category, from_type, typedef_type> super_type; \
- typedef mlc_internal_get_typedef_(get_default_props<category>, \
- typedef_type) prop_type; \
- \
- mlc::implies_< mlc::neq_< mlc_ret(super_type), \
- mlc::not_found >, \
- mlc::eq_< prop_type, \
- mlc::not_found > >::ensure(); \
- } \
}; \
\
+ /** Typedef selector. */ \
+ /** \{ */ \
+ /** Fwd decl. */ \
+ template <bool external_typedef_p, bool internal_typedef_p, \
+ typename external_typedef, typename internal_typedef> \
+ struct select_typedef; \
\
- template <typename category, typename from_type, typename typedef_type> \
- struct f_rec_get_prop \
+ /** The typedef is found in both an external and an internal */ \
+ /** type definitions: error. */ \
+ template <typename external_typedef, typename internal_typedef> \
+ struct select_typedef<true, true, external_typedef, internal_typedef> \
{ \
- typedef get_props<category, from_type> props; \
- typedef mlc_internal_get_typedef_(props, typedef_type) prop; \
- \
- typedef typename \
- mlc::if_< mlc::neq_< prop, mlc::not_found >, \
- prop, \
- typename f_rec_get_prop< category, \
- typename get_super_type<from_type, 0>::ret, \
- typedef_type >::ret \
- >::ret ret; \
+ /* No ret member. */ \
}; \
\
- template <typename category, typename typedef_type> \
- struct f_rec_get_prop <category, mlc::none, typedef_type> \
- { \
- typedef mlc_internal_get_typedef_(get_default_props<category>, \
- typedef_type) ret; \
- ~f_rec_get_prop() \
+ /** The typedef is found neither in an external nor in an */ \
+ /** internal type definition: error. */ \
+ template <typename external_typedef, typename internal_typedef> \
+ struct select_typedef<false, false, external_typedef, internal_typedef> \
{ \
- mlc::and_< mlc::neq_< ret, mlc::not_found >, \
- mlc::neq_< ret, mlc::undefined > >::ensure(); \
- } \
+ /* No ret member. */ \
}; \
\
- \
- template <typename category, typename from_type, typename typedef_type> \
- struct f_rec_get_type \
+ /** The typedef is found in an extternal definition only: good. */ \
+ template <typename external_typedef, typename internal_typedef> \
+ struct select_typedef<true, false, external_typedef, internal_typedef> \
{ \
- typedef get_type<category, from_type, typedef_type> client_type; \
- typedef mlc_ret(client_type) type; \
- \
- typedef typename \
- mlc::if_< mlc::neq_< type, mlc::not_found >, \
- type, \
- typename f_rec_get_type< category, \
- typename get_super_type<from_type, 0>::ret, \
- typedef_type >::ret \
- >::ret ret; \
+ typedef external_typedef ret; \
}; \
\
- template <typename category, typename typedef_type> \
- struct f_rec_get_type <category, mlc::none, typedef_type> \
+ /** The typedef is found in an internal definition only: good. */ \
+ template <typename external_typedef, typename internal_typedef> \
+ struct select_typedef<false, true, external_typedef, internal_typedef> \
{ \
- typedef mlc::not_found ret; \
+ typedef internal_typedef ret; \
}; \
+ /** \} */ \
\
+ } /** End of namespace internal. */ \
+ \
+ \
+ /** FIXME: Don't query from_type directly, but */ \
+ /** exact_type(from_type) instead */ \
template <typename category, typename from_type, typename typedef_type> \
- struct f_get_type \
+ struct typeof_ \
{ \
+ typedef internal::get_types<category, from_type> types; \
+ /* FIXME: Add a check in typeof_ to ensure that get_ext_type */ \
+ /* derives from get_ext_type<none> */ \
typedef \
- mlc_internal_get_typedef_(get_default_props<category>, typedef_type) \
- default_prop; \
+ internal::get_ext_type<category, from_type, typedef_type> ext_type; \
+ /* FIXME: Add a check in typeof_ to ensure that get_ext_type */ \
+ /* derives from get_ext_type<none> */ \
\
+ /** Look for the typedef as an external type. */ \
typedef \
- typename f_rec_get_prop<category, from_type, typedef_type>::ret \
- prop; \
- \
+ mlc_internal_get_typedef(ext_type, typedef_::ret) external_typedef; \
+ /** Look for the typedef in internal types. */ \
typedef \
- typename f_rec_get_type<category, from_type, typedef_type>::ret \
- type; \
+ mlc_internal_get_typedef(types, typedef_type) internal_typedef; \
\
- ~f_get_type() \
- { \
- mlc::implies_< mlc::is_found<default_prop>, \
- mlc::is_not_found<type> >::ensure(); \
- mlc::xor_< mlc::is_found<prop>, \
- mlc::is_found<type> >::ensure(); \
- } \
+ static const bool found_external_p = \
+ mlc::is_found<external_typedef>::value; \
+ static const bool found_internal_p = \
+ mlc::is_found<internal_typedef>::value; \
\
- typedef typename mlc::if_< mlc::is_ok<prop>, \
- prop, \
- typename mlc::if_< mlc::is_ok<type>, \
- type, \
- mlc::not_ok \
- > ::ret \
- > ::ret ret; \
+ typedef typename \
+ internal::select_typedef<found_external_p, found_internal_p, \
+ external_typedef, internal_typedef>::ret ret; \
}; \
\
- } \
- \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
-
-# define mlc_type_of_(Namespace, Category, FromType, Alias) \
- Namespace::internal::f_get_type<Category, \
- FromType, \
- Namespace::typedef_::Alias##_type>::ret
-
-# define mlc_type_2_of_(Namespace, Category, FromType,_2, Alias) \
- Namespace::internal::f_get_type<Category, \
- FromType,_2, \
- Namespace::typedef_::Alias##_type>::ret
-
-
-# define mlc_type_of(Namespace, Category, FromType, Alias) \
- typename mlc_type_of_(Namespace, Category, FromType, Alias)
-
-# define mlc_type_2_of(Namespace, Category, FromType,_2, Alias) \
- typename mlc_type_2_of_(Namespace, Category, FromType,_2, Alias)
-
-
-
-// FIXME: TODO-list
-//
-// f_get_type lance d'une part f_rec_get_prop et d'autre part f_rec_get_type
-// fusion des résultats: si 2 not_found err, si 1 ok + 1 not_found -> ok
-//
-// f_rec_get_prop et f_rec_get_type examine plusieurs super (i=0,1,2)
+/*---------.
+| Macros. |
+`---------*/
+
+/* FIXME: I don't know this macro will be really usable; what if T is
+ a template class? */
+// mlc_set_super_type(T, S) to declare the immediate base class S of T
+# define mlc_set_super(Type, Super) \
+ template <> \
+ struct set_super_type<Type> \
+ { \
+ typedef Super ret; \
+ }
+
+/// \def Get the immediate base class of T
+# define mlc_super(T) \
+ set_super_type<T>::ret
+
+// FIXME: Doc.
+# define mlc_super_types(Category, FromType) \
+ internal::get_types<Category, typename mlc_super(FromType)>
+
+// FIXME: Doc.
+# define mlc_super_types_(Category, FromType) \
+ internal::get_types<Category, mlc_super(FromType)>
+
+// FIXME: Doc.
+# define mlc_super_ext_type(Category, FromType, Typedef) \
+ internal::get_ext_type<Category, typename mlc_super(FromType), Typedef>
+
+// FIXME: Doc.
+# define mlc_super_ext_type_(Category, FromType, Typedef) \
+ internal::get_ext_type<Category, mlc_super(FromType), Typedef>
+
+/// Get the property \a Typedef from \a FromType (version with typename).
+#define mlc_typeof(Category, FromType, Typedef) \
+ typename typeof_<Category, FromType, typedef_:: Typedef##_type >::ret
+
+/// Get the property \a Typedef from \a FromType (version without typename).
+#define mlc_typeof_(Category, FromType, Typedef) \
+ typeof_<Category, FromType, typedef_:: Typedef##_type >::ret
#endif // ! METALIC_PROPERTIES_HH
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
This is just for testing purpose (namely, to see if the new typedef
facility works with the old properties). I'm currently working on the
new implementation of mlc/properties.hh, described in Théo's
presentation from January 2006.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add the old properties system.
* tests/properties.cc, mlc/to_string.hh: New files.
* mlc/properties.hh: New test.
mlc/properties.hh | 53 +++++++----------
tests/properties.cc | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 184 insertions(+), 29 deletions(-)
Index: tests/properties.cc
--- tests/properties.cc (revision 0)
+++ tests/properties.cc (revision 0)
@@ -0,0 +1,160 @@
+#include <ostream>
+
+#include <mlc/properties.hh>
+#include <mlc/to_string.hh>
+#include <mlc/cmp.hh>
+
+
+// FIXME: Split this test into several smaller tests? For instance,
+// we have to test inheritance, properties/associated types,
+// ``external properties'', etc. The best approach is probably to
+// browse mlc/properties.hh so as to make a list of the features to be
+// checked.
+
+
+namespace my
+{
+ /*----------------------.
+ | Namespace equipment. |
+ `----------------------*/
+
+ mlc_equip_namespace_with_properties();
+
+
+ /*-----------.
+ | Typedefs. |
+ `-----------*/
+
+ mlc_decl_typedef(ptr_type);
+ mlc_decl_typedef(foo_type);
+ mlc_decl_typedef(bar_type);
+ mlc_decl_typedef(baz_type);
+ mlc_decl_typedef(quux_type);
+
+
+ /*-----------.
+ | Category. |
+ `-----------*/
+
+ // We only use one category here.
+ namespace category
+ {
+ struct my_cat;
+ }
+
+ template <>
+ struct set_default_props < category::my_cat >
+ {
+ typedef mlc::undefined ptr_type;
+ };
+
+ /* FIXME: In the current version of SCOOP 2, this ``packing'' is no
+ longer done at this stage, but thanks to the `get_types'
+ mechanism. */
+ /// Retrieval of any image type properties (FIXME: say 'packing').
+ template <typename T>
+ struct get_props < category::my_cat, T >
+ {
+ typedef char ptr_type;
+
+ // FIXME: Same remark as in the above FIXME: this echo() method
+ // should be place lower in the prop/type hierarchy.
+ static void echo(std::ostream& ostr)
+ {
+ ostr << "props_of( oln::category::point, "
+ << mlc_to_string(T) << " ) =" << std::endl
+ << "{" << std::endl
+ << "\t ptr_type = " << mlc_to_string(ptr_type) << std::endl
+ << "}" << std::endl;
+ }
+
+ static void ensure()
+ {
+ mlc::is_ok< ptr_type >::ensure();
+ }
+ };
+
+}
+
+// Helper macro.
+#define my_type_of_(FromType, Alias) \
+ mlc_type_of_(my, my::category::my_cat, FromType, Alias)
+
+namespace my
+{
+ /*----.
+ | A. |
+ `----*/
+
+ // Forward declaration.
+ struct A;
+
+ // FIXME: Rename as set_types<> when mlc/properties.hh is updated.
+ // Associated types.
+ template<>
+ struct set_props<category::my_cat, my::A>
+ {
+ typedef int foo_type;
+ typedef float bar_type;
+ typedef mlc::undefined baz_type;
+ };
+
+ class A
+ {
+ // Aliases.
+ typedef my_type_of_(A, foo) foo_type;
+ typedef my_type_of_(A, bar) bar_type;
+ typedef my_type_of_(A, baz) baz_type;
+ };
+
+
+ /*------------.
+ | B ---|> A. |
+ `------------*/
+
+ // Forward declaration.
+ struct B;
+
+ // FIXME: Is there any `set_super_type(T)'' sugar available?
+ template<>
+ struct set_super_type<my::B>
+ {
+ typedef A ret;
+ };
+
+ template<>
+ struct set_props<category::my_cat, B>
+ {
+ // Note: foo_type is untouched here.
+
+ // A type redefined here.
+ typedef double bar_type;
+ // A type defined here (but declared abstract in the super class).
+ typedef char baz_type;
+ // A type defined only here (and not in the super class).
+ typedef long quux_type;
+ };
+
+ // FIXME: Is there any `set_super_type(T)'' sugar available?
+ class B : public internal::get_super_type<B>
+ {
+ // Aliases.
+ typedef my_type_of_(B, foo) foo_type;
+ typedef my_type_of_(B, bar) bar_type;
+ typedef my_type_of_(B, baz) baz_type;
+ typedef my_type_of_(B, quux) quux_type;
+ };
+}
+
+int
+main()
+{
+ // Check associated types.
+ mlc_eq(my::A::foo_type, int)::ensure ();
+ mlc_eq(my::A::bar_type, float)::ensure ();
+
+ // Check associated types.
+ mlc_neq(my::B::bar_type, my::A::bar_type)::ensure ();
+ mlc_eq(my::B::baz_type, char)::ensure ();
+ mlc_eq(my::B::quux_type, long)::ensure ();
+}
Index: mlc/properties.hh
--- mlc/properties.hh (revision 0)
+++ mlc/properties.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2005 EPITA Research and Development Laboratory
+// 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
@@ -28,26 +28,21 @@
#ifndef METALIC_PROPERTIES_HH
# define METALIC_PROPERTIES_HH
-# include <mlc/types.hh>
+# include <mlc/flags.hh>
# include <mlc/typedef.hh>
# include <mlc/bool.hh>
-# include <mlc/implies.hh>
# include <mlc/cmp.hh>
# include <mlc/if.hh>
# include <mlc/is_a.hh>
+# include <mlc/implies.hh>
-
-// this is an internal macro
-# define mlc_internal_get_typedef_(FromType, TypedefType) \
- typename internal::get_typedef <FromType, TypedefType> ::ret
-
+// Note: TypedefName must be of the form `typedef_::foo'.
+# define mlc_internal_get_typedef_(Type, TypedefName) \
+ typename TypedefName::template from_< Type >::ret
# define mlc_equip_namespace_with_properties() \
\
- mlc_equip_namespace_with_typedef(); \
- mlc_decl_typedef(ret); \
- \
template <template <typename> class abstraction> \
struct is_a \
{ \
@@ -61,13 +56,13 @@
template <typename type, unsigned i = 0> \
struct set_super_type \
{ \
- typedef mlc::no_type ret; \
+ typedef mlc::none ret; \
}; \
\
template <typename type, unsigned i = 0> \
struct set_category \
{ \
- typedef mlc::no_type ret; \
+ typedef mlc::none ret; \
}; \
\
template <typename category> \
@@ -122,10 +117,10 @@
typedef mlc_internal_get_typedef_(get_default_props<category>, \
typedef_type) prop_type; \
\
- mlc::implies< mlc::neq< mlc_typedef_of(super_type, ret), \
- mlc::internal::not_found >, \
- mlc::eq< prop_type, \
- mlc::internal::not_found > >::ensure(); \
+ mlc::implies_< mlc::neq_< mlc_ret(super_type), \
+ mlc::not_found >, \
+ mlc::eq_< prop_type, \
+ mlc::not_found > >::ensure(); \
} \
}; \
\
@@ -137,7 +132,7 @@
typedef mlc_internal_get_typedef_(props, typedef_type) prop; \
\
typedef typename \
- mlc::if_< mlc::neq< prop, mlc::internal::not_found >, \
+ mlc::if_< mlc::neq_< prop, mlc::not_found >, \
prop, \
typename f_rec_get_prop< category, \
typename get_super_type<from_type, 0>::ret, \
@@ -146,14 +141,14 @@
}; \
\
template <typename category, typename typedef_type> \
- struct f_rec_get_prop <category, mlc::no_type, typedef_type> \
+ struct f_rec_get_prop <category, mlc::none, typedef_type> \
{ \
typedef mlc_internal_get_typedef_(get_default_props<category>, \
typedef_type) ret; \
~f_rec_get_prop() \
{ \
- mlc::and_< mlc::neq< ret, mlc::internal::not_found >, \
- mlc::neq< ret, mlc::undefined_type > >::ensure(); \
+ mlc::and_< mlc::neq_< ret, mlc::not_found >, \
+ mlc::neq_< ret, mlc::undefined > >::ensure(); \
} \
}; \
\
@@ -162,10 +157,10 @@
struct f_rec_get_type \
{ \
typedef get_type<category, from_type, typedef_type> client_type; \
- typedef mlc_typedef_of(client_type, ret) type; \
+ typedef mlc_ret(client_type) type; \
\
typedef typename \
- mlc::if_< mlc::neq< type, mlc::internal::not_found >, \
+ mlc::if_< mlc::neq_< type, mlc::not_found >, \
type, \
typename f_rec_get_type< category, \
typename get_super_type<from_type, 0>::ret, \
@@ -174,9 +169,9 @@
}; \
\
template <typename category, typename typedef_type> \
- struct f_rec_get_type <category, mlc::no_type, typedef_type> \
+ struct f_rec_get_type <category, mlc::none, typedef_type> \
{ \
- typedef mlc::internal::not_found ret; \
+ typedef mlc::not_found ret; \
}; \
\
template <typename category, typename from_type, typename typedef_type> \
@@ -196,7 +191,7 @@
\
~f_get_type() \
{ \
- mlc::implies< mlc::is_found<default_prop>, \
+ mlc::implies_< mlc::is_found<default_prop>, \
mlc::is_not_found<type> >::ensure(); \
mlc::xor_< mlc::is_found<prop>, \
mlc::is_found<type> >::ensure(); \
@@ -206,7 +201,7 @@
prop, \
typename mlc::if_< mlc::is_ok<type>, \
type, \
- mlc::internal::not_ok \
+ mlc::not_ok \
> ::ret \
> ::ret ret; \
}; \
@@ -220,12 +215,12 @@
# define mlc_type_of_(Namespace, Category, FromType, Alias) \
Namespace::internal::f_get_type<Category, \
FromType, \
- Namespace::internal::typedef_::Alias##_type>::ret
+ Namespace::typedef_::Alias##_type>::ret
# define mlc_type_2_of_(Namespace, Category, FromType,_2, Alias) \
Namespace::internal::f_get_type<Category, \
FromType,_2, \
- Namespace::internal::typedef_::Alias##_type>::ret
+ Namespace::typedef_::Alias##_type>::ret
# define mlc_type_of(Namespace, Category, FromType, Alias) \
1
0
(This message was sent to the olena-patches list but did not appear in
the lrde.olena.patches newsgroup, so I'm posting it again. Sorry for
the duplicate message in olena-patches.)
https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix mlc::is_ok definition.
* mlc/cmp.hh (mlc::is_ok): Add missing template declarator.
cmp.hh | 1 +
1 file changed, 1 insertion(+)
Index: mlc/cmp.hh
--- mlc/cmp.hh (revision 401)
+++ mlc/cmp.hh (working copy)
@@ -106,6 +106,7 @@
/// Check whether a type is a sound (supposedly before using it).
+ template <typename T>
struct is_ok : public ands_< neq_<T, not_found>,
neq_<T, not_ok>,
neq_<T, undefined > >
1
0