https://svn.lrde.epita.fr/svn/oln/trunk/metalic
Index: ChangeLog
from Thierry Geraud <theo(a)lrde.epita.fr>
Disambiguate Boolean value types and Boolean expression types.
* tests/ret.cc: Update.
* mlc/ret.hh: Fix missing include.
The Boolean value classes are re-written and internal::value_ is
removed; this class was too ambiguous since precise types, e.g.,
int_<i>, are provided and it was weirdly located in the value class
hierarchy.
* mlc/bool.hh (bool_<true>, bool_<false>): Merge those
specializations into the single and once for all written class
bool_<b>.
(bool_<true>::is_true): Remove since this mark is now factored
in the base class bexpr_is_<b>.
(bool_<b>): Add inheritance so that a Boolean value can be
considered as a Boolean expression type.
(internal::value_<bool, b>): Remove this specialization since
the class internal::value_ is also removed.
(logic.hh): Remove inclusion.
(mlc_bool): Move to...
The Boolean expression types are now handled by special classes.
Yet mlc::true_ and mlc::false_ remain expression types in addition
of value types.
* mlc/bexpr.hh: ...this file. This macro only applies on Boolean
expression types.
(bexpr_): Remove this obsolete wrapper.
(bexpr_is_<b>): New base class with its couple of specializations
which act as a replacement for bool_<b> for expression types.
(internal::bool_of_): Replace the meta-code for mlc_bool.
Those changes induce a lot of updates described below.
* mlc/pair.hh: Update includes.
* mlc/logic.hh: Update. Instead of deriving from bool_<b>
Boolean expression types now derive from bexpr_is_<b>.
(and_list_, or_list_): Comment to postpone updating while keeping
code compile.
* mlc/implies.hh: Update inheritance.
* mlc/if.hh: Update includes and add assertion.
* mlc/assert.hh: Update includes.
* mlc/valist.hh: Likewise.
* mlc/wrap.hh: Remove obsolete code.
* mlc/is_a.hh: Update inheritance.
(bexpr_): Replace by wrap_.
* mlc/case.hh: Update. Now use mlc_bool instead of ::value.
* mlc/cmp.hh: Update inheritance.
(eq_::ensure): Remove this obsolete feature.
* mlc/value.hh: Move sub-classes of value to...
* mlc/int.hh, mlc/char.hh: ...these new files.
* mlc/values.hh: New file that includes the whole value types material.
mlc/assert.hh | 7
mlc/bexpr.hh | 139 ++++++++++++++++++-
mlc/bool.hh | 168 ++---------------------
mlc/case.hh | 33 ++--
mlc/char.hh | 51 +++++++
mlc/cmp.hh | 20 +-
mlc/if.hh | 9 -
mlc/implies.hh | 6
mlc/int.hh | 88 ++++++++++++
mlc/is_a.hh | 13 -
mlc/logic.hh | 403 ++++++++++++++++++++++++++++-----------------------------
mlc/pair.hh | 3
mlc/ret.hh | 1
mlc/valist.hh | 2
mlc/value.hh | 133 ++----------------
mlc/values.hh | 49 ++++++
mlc/wrap.hh | 55 -------
tests/ret.cc | 4
18 files changed, 610 insertions(+), 574 deletions(-)
Index: tests/ret.cc
--- tests/ret.cc (revision 428)
+++ tests/ret.cc (working copy)
@@ -12,6 +12,6 @@
int main()
{
- std::cout << mlc::ret_found_in_<yes>::value << std::endl;
- std::cout << mlc::ret_found_in_<no>::value << std::endl;
+ std::cout << mlc_bool( mlc::ret_found_in_<yes> ) << std::endl;
+ std::cout << mlc_bool( mlc::ret_found_in_<no> ) << std::endl;
}
Index: mlc/ret.hh
--- mlc/ret.hh (revision 428)
+++ mlc/ret.hh (working copy)
@@ -29,6 +29,7 @@
# define METALIC_RET_HH
# include <mlc/typedef.hh>
+# include <mlc/cmp.hh>
Index: mlc/int.hh
--- mlc/int.hh (revision 0)
+++ mlc/int.hh (revision 0)
@@ -0,0 +1,88 @@
+// 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_INT_HH
+# define METALIC_INT_HH
+
+# include <mlc/value.hh>
+
+
+
+/// Internal macros.
+
+# define mlc_internal_decl_unsigned_integer(Type, TypeName) \
+template <Type val> \
+struct TypeName : public abstract::unsigned_integer \
+{ \
+ typedef Type type; \
+ static const Type value = val; \
+}
+
+
+# define mlc_internal_decl_signed_integer(Type, TypeName) \
+template <Type val> \
+struct TypeName : public abstract::signed_integer \
+{ \
+ typedef Type type; \
+ static const Type value = val; \
+}
+
+
+
+namespace mlc {
+
+
+ namespace abstract {
+
+ /// Abstractions for integer values as types.
+
+ struct integer : public value {};
+ struct unsigned_integer : public integer {};
+ struct signed_integer : public integer {};
+
+ } // end of namespace mlc::abstract
+
+
+
+ // Dedicated sub-classes for builtin types.
+
+ mlc_internal_decl_unsigned_integer( unsigned char, uchar_ );
+ mlc_internal_decl_unsigned_integer( unsigned short, ushort_ );
+ mlc_internal_decl_unsigned_integer( unsigned int, uint_ );
+ mlc_internal_decl_unsigned_integer( unsigned long, ulong_ );
+
+ mlc_internal_decl_signed_integer( signed char, schar_ );
+ mlc_internal_decl_signed_integer( signed short, short_ );
+ mlc_internal_decl_signed_integer( signed int, int_ );
+ mlc_internal_decl_signed_integer( signed long, long_ );
+
+
+} // end of namespace mlc
+
+
+
+#endif // ! METALIC_INT_HH
Index: mlc/bool.hh
--- mlc/bool.hh (revision 428)
+++ mlc/bool.hh (working copy)
@@ -29,17 +29,7 @@
# define METALIC_BOOL_HH
# include <mlc/value.hh>
-# include <mlc/flags.hh>
-
-
-/*! \def mlc_bool(Bexpr)
-**
-** Macro that retrieves a Boolean value from a Boolean expression type.
-** Its result is either true or false.
-*/
-# define mlc_bool(Bexpr) mlc::internal::get_bool<Bexpr>::value
-
-
+# include <mlc/bexpr.hh>
namespace mlc
@@ -49,12 +39,10 @@
/*! \class mlc::abstract::boolean
**
- ** Abstract base class for Booleans represented as types. This
- ** class has two important sub-classes: mlc::true_ and
- ** mlc::false_.
- **
- ** Any mlc Boolean expression type derives from either mlc::true_
- ** or mlc::false_ so derives from mlc::abstract::boolean.
+ ** Abstract base class for Boolean values represented as types.
+ ** This class has exactly one sub-class: mlc::bool_<b> where b is
+ ** either true or false. Thanks to aliases, mlc::bool_<true> and
+ ** mlc::bool_<false> are respectively mlc::true_ and mlc::false_.
*/
struct boolean : public value {};
@@ -62,40 +50,16 @@
} // end of mlc::abstract
- // fwd decl
- template <bool> struct bool_;
-
-
- namespace internal
- {
-
- /*! \class mlc::get_bool<T>
- **
- ** Internal class so do not use it. This class gives access to a
- ** Boolean value from a Boolean expression type; it is used in the
- ** mlc_bool(T) macro.
- **
- ** \see mlc_bool(T)
- */
- template <typename T>
- struct get_bool
- {
- static const bool value = T::bool_value_;
- };
-
- /*! \class mlc::value_<bool, b>
- **
- ** Specialization of value_<T, val> for the Boolean case.
+ /*! \class mlc::bool_<b>
**
- ** Design notes: 1) This specialization is defined so that mlc
- ** Booleans derive from mlc::abstract::boolean. 2) This
- ** specialization conforms to the interface of the generic version
- ** of mlc::internal::value_.
+ ** Value type corresponding to bool.
*/
template <bool b>
- struct value_ <bool, b> : public abstract::boolean
+ struct bool_ : public bexpr_is_<b>,
+ public abstract::boolean
+
{
/*! \typedef type
**
@@ -112,129 +76,29 @@
** This member is provided for any mlc value class such as
** mlc::int_<51> and mlc::char_<'c'>. However, to access the
** regular value of a type T that you know to be a mlc Boolean
- ** expression, you should prefer to use the macro mlc_bool(T).
- ** This macro also ensures that T really is an expression.
+ ** expression, you should prefer to use the macro mlc_value(T).
+ ** This macro also ensures that T is a mlc value type.
**
*/
static const bool value = b;
-
- /*! \typedef eval
- **
- ** Returns mlc::true_ or mlc::false_.
- **
- ** Since Boolean expression types derive from either mlc::true_
- ** or mlc::false_, these expression types are never exactly
- ** mlc::true_ nor mlc::false_. This typedef thus allows for the
- ** expression evaluation.
- **
- ** Please note that, however, we usually do not need expression
- ** evaluation. The most common use of a Boolean expression is
- ** to check that it is verified (true) and, for that, we provide
- ** "assert_<bexpr, errmsg>::check()". For instance:
- ** assert_< or_<mlc_is_a(T, int), mlc_is_a(T, unsigned)> >::check();
- ** ensures that T is int or unsigned without using ::eval.
- **
- ** \see mlc::true_, mlc::false_, mlc::assert_<bexpr, errmsg>.
- */
- typedef bool_<b> eval;
-
- private:
-
- /*! \member bool_value_
- **
- ** This member is redundant with the member 'value'. It is used
- ** by the mlc_bool(T) macro to ensure that T actually derives
- ** from mlc::true_ or mlc::false_.
- */
- static const bool bool_value_ = b;
-
- template <typename T> friend class get_bool;
};
- } // end of namespace mlc::internal
-
-
-
- /*! \class mlc::bool_<true>
- **
- ** Specialization of mlc::bool_<b> for b set to true. This type
- ** is also known as mlc::true_. Every Boolean expression types
- ** derive either from this type or from mlc::false_.
- **
- ** Design notes: 1) This specialization is defined so that mlc
- ** Booleans derive from mlc::abstract::boolean. 2) This
- ** specialization conforms to the interface of the generic version
- ** of mlc::internal::value_.
+ /*! \def mlc::true_
**
- ** \see mlc::bool_<false>
+ ** This is an alias (typedef) for mlc::bool_<true>.
*/
-
- template <>
- struct bool_<true> : public internal::value_<bool, true>
- {
-
- // FIXME: doc
- using internal::value_<bool, true>::value;
- using internal::value_<bool, true>::eval;
-
- /*! \typedef is_true
- **
- ** You should not use this typedef.
- **
- ** This typedef is inherited in every Boolean expression types
- ** that derive from mlc::true_. This typedef is not provided in
- ** mlc::false_. The type returned by this typedef has no meaning
- ** (and thus no significant value). Static checks via
- ** "mlc::assert_<bexpr, err>" rely on the presence or absence of
- ** this typedef.
- **
- ** \see mlc::assert_<bexpr, err>
- */
- typedef dummy is_true;
-
- };
-
typedef bool_<true> true_;
- /*! \class mlc::bool_<false>
- **
- ** Specialization of mlc::bool_<b> for b set to false. This type
- ** is also known as mlc::false_. Every Boolean expression types
- ** derive either from this type or from mlc::true_.
- **
- ** Conversely to mlc::true_, this class does not feature the typedef
- ** "is_true". So, when a Boolean expression type, say Expr, is
- ** evaluated to false, the static checks via "assert_<Expr>"
- ** do not compile.
- **
- ** Design notes: 1) This specialization is defined so that mlc
- ** Booleans derive from mlc::abstract::boolean. 2) This
- ** specialization conforms to the interface of the generic version
- ** of mlc::internal::value_.
+ /*! \def mlc::false_
**
- ** \see mlc::bool_<true>, mlc::assert_<bexpr, errmsg>
+ ** This is an alias (typedef) for mlc::bool_<false>.
*/
-
- template <>
- struct bool_<false> : public internal::value_<bool, false>
- {
- // FIXME: doc
- private:
- typedef internal::value_<bool, false> super_type;
- public:
- using super_type::value;
- using super_type::eval;
- };
-
typedef bool_<false> false_;
} // end of namespace mlc
-# include <mlc/logic.hh>
-
-
#endif // ! METALIC_BOOL_HH
Index: mlc/pair.hh
--- mlc/pair.hh (revision 428)
+++ mlc/pair.hh (working copy)
@@ -28,7 +28,8 @@
#ifndef METALIC_PAIR_HH
# define METALIC_PAIR_HH
-# include <mlc/bool.hh>
+# include <mlc/assert.hh>
+# include <mlc/logic.hh>
# include <mlc/uint.hh>
Index: mlc/logic.hh
--- mlc/logic.hh (revision 428)
+++ mlc/logic.hh (working copy)
@@ -28,9 +28,8 @@
#ifndef METALIC_LOGIC_HH
# define METALIC_LOGIC_HH
-# include <mlc/bool.hh>
+# include <mlc/bexpr.hh>
# include <mlc/assert.hh>
-# include <mlc/flags.hh>
@@ -44,7 +43,7 @@
*/
template <typename T>
struct not_
- : public bool_<( !mlc_bool(T) )>
+ : public bexpr_is_<( !mlc_bool(T) )>
{};
@@ -57,7 +56,7 @@
*/
template <typename L, typename R>
struct and_
- : public bool_<( mlc_bool(L) && mlc_bool(R) )>
+ : public bexpr_is_<( mlc_bool(L) && mlc_bool(R) )>
{};
@@ -70,7 +69,7 @@
*/
template <typename L, typename R>
struct nand_
- : public bool_<( !(mlc_bool(L) && mlc_bool(R)) )>
+ : public bexpr_is_<( !(mlc_bool(L) && mlc_bool(R)) )>
{};
@@ -83,7 +82,7 @@
*/
template <typename L, typename R>
struct or_
- : public bool_<( mlc_bool(L) || mlc_bool(R) )>
+ : public bexpr_is_<( mlc_bool(L) || mlc_bool(R) )>
{};
@@ -96,7 +95,7 @@
*/
template <typename L, typename R>
struct nor_
- : public bool_<( !(mlc_bool(L) || mlc_bool(R)) )>
+ : public bexpr_is_<( !(mlc_bool(L) || mlc_bool(R)) )>
{};
@@ -107,7 +106,7 @@
*/
template <typename L, typename R>
struct xor_
- : public bool_<( mlc_bool(L) != mlc_bool(R) )>
+ : public bexpr_is_<( mlc_bool(L) != mlc_bool(R) )>
{};
@@ -118,204 +117,204 @@
*/
template <typename L, typename R>
struct xnor_
- : public bool_<( !(mlc_bool(L) != mlc_bool(R)) )>
+ : public bexpr_is_<( !(mlc_bool(L) != mlc_bool(R)) )>
{};
- /// Internal helpers for logical operators between several Boolean types
+// /// Internal helpers for logical operators between several Boolean types
- namespace internal
- {
- // FIXME: doc
-
- template <typename A>
- struct is_bexpr_or_none_ : public true_ // FIXME: pb using mlc_is_a because of
circular deps
- {
- };
-
-
- // va_eval_
-
- template <typename A>
- struct va_eval_
- {
- typedef typename A::eval ret;
- };
-
- template <>
- struct va_eval_ <none>
- {
- typedef none ret;
- };
-
-
- // or_list_2_
-
- template <typename A1, typename A2>
- struct or_list_2_
- : public or_<A1, A2>::eval
- {};
-
- template <>
- struct or_list_2_ <none, none>
- : public true_
- {};
-
- template <typename A1>
- struct or_list_2_ <A1, none>
- : public A1
- {};
-
- template <typename A2>
- struct or_list_2_ <none, A2>; // forbidden
-
- // or_list_4_
-
- template <typename A1, typename A2, typename A3, typename A4>
- struct or_list_4_
- : public or_list_2_< typename or_list_2_<A1, A2>::eval,
- typename or_list_2_<A3, A4>::eval >::eval
- {};
-
- template <>
- struct or_list_4_ <none, none, none, none>
- : public true_
- {};
-
- // or_list_
-
- template <typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
- struct or_list_
- : public or_list_2_< typename or_list_4_<A1, A2, A3, A4>::eval,
- typename or_list_4_<A5, A6, A7, A8>::eval >::eval
- {};
-
-
- // and_list_2_
-
- template <typename A1, typename A2>
- struct and_list_2_
- : public and_<A1, A2>::eval
- {};
-
- template <>
- struct and_list_2_ <none, none>
- : public true_
- {};
-
- template <typename A1>
- struct and_list_2_ <A1, none>
- : public A1
- {};
-
- template <typename A2>
- struct and_list_2_ <none, A2>; // forbidden
-
- // and_list_4_
-
- template <typename A1, typename A2, typename A3, typename A4>
- struct and_list_4_
- : public and_list_2_< typename and_list_2_<A1, A2>::eval,
- typename and_list_2_<A3, A4>::eval >::eval
- {};
-
- template <>
- struct and_list_4_ <none, none, none, none>
- : public true_
- {};
-
- // and_list_
-
- template <typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
- struct and_list_
- : public and_list_2_< typename and_list_4_<A1, A2, A3, A4>::eval,
- typename and_list_4_<A5, A6, A7, A8>::eval >::eval
- {};
-
- } // end of mlc::internal
-
-
-
- /*! \class mlc::or_list_<..>
- **
- ** Logical n-ary 'or' operator on a set of Boolean expression types.
- ** The number of arguments (parameters) should be at least 3 and at
- ** most 8. This class is also a Boolean expression type.
- **
- ** Sample use:
- ** mlc::or_list_< mlc::eq_<T, int>,
- ** mlc_is_a(T, mlc::int_),
- ** mlc_is_a(T, my::integer) >
- **
- ** \see mlc::or_<L,R> mlc::and_list_<..>
- */
-
- template <typename A1,
- typename A2,
- typename A3,
- typename A4 = none,
- typename A5 = none,
- typename A6 = none,
- typename A7 = none,
- typename A8 = none>
- struct or_list_ : private multiple_assert_< internal::is_bexpr_or_none_<A1>,
- internal::is_bexpr_or_none_<A2>,
- internal::is_bexpr_or_none_<A3>,
- internal::is_bexpr_or_none_<A4>,
- internal::is_bexpr_or_none_<A5>,
- internal::is_bexpr_or_none_<A6>,
- internal::is_bexpr_or_none_<A7>,
- internal::is_bexpr_or_none_<A8> >,
- public internal::or_list_< typename internal::va_eval_<A1>::ret,
- typename internal::va_eval_<A2>::ret,
- typename internal::va_eval_<A3>::ret,
- typename internal::va_eval_<A4>::ret,
- typename internal::va_eval_<A5>::ret,
- typename internal::va_eval_<A6>::ret,
- typename internal::va_eval_<A7>::ret,
- typename internal::va_eval_<A8>::ret >
- {
- };
-
-
-
- /*! \class mlc::and_list_<..>
- **
- ** Logical n-ary 'and' operator on a set of Boolean expression types.
- ** The number of arguments (parameters) should be at least 3 and at
- ** most 8. This class is also a Boolean expression type.
- **
- ** \see mlc::and_<L,R> mlc::or_list_<..>
- */
-
- template <typename A1,
- typename A2,
- typename A3,
- typename A4 = none,
- typename A5 = none,
- typename A6 = none,
- typename A7 = none,
- typename A8 = none>
- struct and_list_ : private multiple_assert_< internal::is_bexpr_or_none_<A1>,
- internal::is_bexpr_or_none_<A2>,
- internal::is_bexpr_or_none_<A3>,
- internal::is_bexpr_or_none_<A4>,
- internal::is_bexpr_or_none_<A5>,
- internal::is_bexpr_or_none_<A6>,
- internal::is_bexpr_or_none_<A7>,
- internal::is_bexpr_or_none_<A8> >,
- public internal::and_list_< typename internal::va_eval_<A1>::ret,
- typename internal::va_eval_<A2>::ret,
- typename internal::va_eval_<A3>::ret,
- typename internal::va_eval_<A4>::ret,
- typename internal::va_eval_<A5>::ret,
- typename internal::va_eval_<A6>::ret,
- typename internal::va_eval_<A7>::ret,
- typename internal::va_eval_<A8>::ret >
- {
- };
+// namespace internal
+// {
+// // FIXME: doc
+
+// template <typename A>
+// struct is_bexpr_or_none_ : public true_ // FIXME: pb using mlc_is_a because of
circular deps
+// {
+// };
+
+
+// // va_eval_
+
+// template <typename A>
+// struct va_eval_
+// {
+// typedef typename A::eval ret;
+// };
+
+// template <>
+// struct va_eval_ <none>
+// {
+// typedef none ret;
+// };
+
+
+// // or_list_2_
+
+// template <typename A1, typename A2>
+// struct or_list_2_
+// : public or_<A1, A2>::eval
+// {};
+
+// template <>
+// struct or_list_2_ <none, none>
+// : public true_
+// {};
+
+// template <typename A1>
+// struct or_list_2_ <A1, none>
+// : public A1
+// {};
+
+// template <typename A2>
+// struct or_list_2_ <none, A2>; // forbidden
+
+// // or_list_4_
+
+// template <typename A1, typename A2, typename A3, typename A4>
+// struct or_list_4_
+// : public or_list_2_< typename or_list_2_<A1, A2>::eval,
+// typename or_list_2_<A3, A4>::eval >::eval
+// {};
+
+// template <>
+// struct or_list_4_ <none, none, none, none>
+// : public true_
+// {};
+
+// // or_list_
+
+// template <typename A1, typename A2, typename A3, typename A4,
+// typename A5, typename A6, typename A7, typename A8>
+// struct or_list_
+// : public or_list_2_< typename or_list_4_<A1, A2, A3, A4>::eval,
+// typename or_list_4_<A5, A6, A7, A8>::eval >::eval
+// {};
+
+
+// // and_list_2_
+
+// template <typename A1, typename A2>
+// struct and_list_2_
+// : public and_<A1, A2>::eval
+// {};
+
+// template <>
+// struct and_list_2_ <none, none>
+// : public true_
+// {};
+
+// template <typename A1>
+// struct and_list_2_ <A1, none>
+// : public A1
+// {};
+
+// template <typename A2>
+// struct and_list_2_ <none, A2>; // forbidden
+
+// // and_list_4_
+
+// template <typename A1, typename A2, typename A3, typename A4>
+// struct and_list_4_
+// : public and_list_2_< typename and_list_2_<A1, A2>::eval,
+// typename and_list_2_<A3, A4>::eval >::eval
+// {};
+
+// template <>
+// struct and_list_4_ <none, none, none, none>
+// : public true_
+// {};
+
+// // and_list_
+
+// template <typename A1, typename A2, typename A3, typename A4,
+// typename A5, typename A6, typename A7, typename A8>
+// struct and_list_
+// : public and_list_2_< typename and_list_4_<A1, A2, A3, A4>::eval,
+// typename and_list_4_<A5, A6, A7, A8>::eval >::eval
+// {};
+
+// } // end of mlc::internal
+
+
+
+// /*! \class mlc::or_list_<..>
+// **
+// ** Logical n-ary 'or' operator on a set of Boolean expression types.
+// ** The number of arguments (parameters) should be at least 3 and at
+// ** most 8. This class is also a Boolean expression type.
+// **
+// ** Sample use:
+// ** mlc::or_list_< mlc::eq_<T, int>,
+// ** mlc_is_a(T, mlc::int_),
+// ** mlc_is_a(T, my::integer) >
+// **
+// ** \see mlc::or_<L,R> mlc::and_list_<..>
+// */
+
+// template <typename A1,
+// typename A2,
+// typename A3,
+// typename A4 = none,
+// typename A5 = none,
+// typename A6 = none,
+// typename A7 = none,
+// typename A8 = none>
+// struct or_list_ : private multiple_assert_<
internal::is_bexpr_or_none_<A1>,
+// internal::is_bexpr_or_none_<A2>,
+// internal::is_bexpr_or_none_<A3>,
+// internal::is_bexpr_or_none_<A4>,
+// internal::is_bexpr_or_none_<A5>,
+// internal::is_bexpr_or_none_<A6>,
+// internal::is_bexpr_or_none_<A7>,
+// internal::is_bexpr_or_none_<A8> >,
+// public internal::or_list_< typename internal::va_eval_<A1>::ret,
+// typename internal::va_eval_<A2>::ret,
+// typename internal::va_eval_<A3>::ret,
+// typename internal::va_eval_<A4>::ret,
+// typename internal::va_eval_<A5>::ret,
+// typename internal::va_eval_<A6>::ret,
+// typename internal::va_eval_<A7>::ret,
+// typename internal::va_eval_<A8>::ret >
+// {
+// };
+
+
+
+// /*! \class mlc::and_list_<..>
+// **
+// ** Logical n-ary 'and' operator on a set of Boolean expression types.
+// ** The number of arguments (parameters) should be at least 3 and at
+// ** most 8. This class is also a Boolean expression type.
+// **
+// ** \see mlc::and_<L,R> mlc::or_list_<..>
+// */
+
+// template <typename A1,
+// typename A2,
+// typename A3,
+// typename A4 = none,
+// typename A5 = none,
+// typename A6 = none,
+// typename A7 = none,
+// typename A8 = none>
+// struct and_list_ : private multiple_assert_<
internal::is_bexpr_or_none_<A1>,
+// internal::is_bexpr_or_none_<A2>,
+// internal::is_bexpr_or_none_<A3>,
+// internal::is_bexpr_or_none_<A4>,
+// internal::is_bexpr_or_none_<A5>,
+// internal::is_bexpr_or_none_<A6>,
+// internal::is_bexpr_or_none_<A7>,
+// internal::is_bexpr_or_none_<A8> >,
+// public internal::and_list_< typename internal::va_eval_<A1>::ret,
+// typename internal::va_eval_<A2>::ret,
+// typename internal::va_eval_<A3>::ret,
+// typename internal::va_eval_<A4>::ret,
+// typename internal::va_eval_<A5>::ret,
+// typename internal::va_eval_<A6>::ret,
+// typename internal::va_eval_<A7>::ret,
+// typename internal::va_eval_<A8>::ret >
+// {
+// };
} // end of namespace mlc
Index: mlc/if.hh
--- mlc/if.hh (revision 428)
+++ mlc/if.hh (working copy)
@@ -28,7 +28,9 @@
#ifndef METALIC_IF_HH
# define METALIC_IF_HH
-# include <mlc/bool.hh>
+# include <mlc/bexpr.hh>
+# include <mlc/assert.hh>
+# include <mlc/is_a.hh>
/** \def mlc_if(Cond, Then, Else)
@@ -85,7 +87,10 @@
** evaluated, whatever the result of \a Cond.
*/
template <typename cond_type, typename then_type, typename else_type>
- struct if_ : public internal::if_ < mlc_bool(cond_type), then_type, else_type >
+ struct if_ :
+ // FIXME: enable the static assertion below!!!
+ private assert_< mlc_is_a(cond_type, mlc::abstract::bexpr) >,
+ public internal::if_ < mlc_bool(cond_type), then_type, else_type >
{
};
Index: mlc/values.hh
--- mlc/values.hh (revision 0)
+++ mlc/values.hh (revision 0)
@@ -0,0 +1,49 @@
+// 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_VALUES_HH
+# define METALIC_VALUES_HH
+
+
+
+/*!
+**
+** This file is provided to group all value types.
+*/
+
+# include <mlc/value.hh>
+# include <mlc/bool.hh>
+# include <mlc/char.hh>
+# include <mlc/int.hh>
+# include <mlc/uint.hh>
+
+
+// ...
+
+
+
+#endif // ! METALIC_VALUES_HH
Index: mlc/assert.hh
--- mlc/assert.hh (revision 428)
+++ mlc/assert.hh (working copy)
@@ -28,8 +28,6 @@
#ifndef METALIC_ASSERT_HH
# define METALIC_ASSERT_HH
-# include <mlc/bool.hh>
-
namespace mlc
@@ -228,7 +226,4 @@
} // end of namespace mlc
-# include <mlc/logic.hh>
-
-
-#endif // ! METALIC_BOOL_HH
+#endif // ! METALIC_ASSERT_HH
Index: mlc/valist.hh
--- mlc/valist.hh (revision 428)
+++ mlc/valist.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef METALIC_VALIST_HH
# define METALIC_VALIST_HH
-# include <mlc/bool.hh>
+# include <mlc/assert.hh>
# include <mlc/cmp.hh>
# include <mlc/uint.hh>
Index: mlc/implies.hh
--- mlc/implies.hh (revision 428)
+++ mlc/implies.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef METALIC_IMPLIES_HH
# define METALIC_IMPLIES_HH
-# include <mlc/bool.hh>
+# include <mlc/bexpr.hh>
/*! \def mlc_implies(Left_BExpr, Right_BExpr)
@@ -40,7 +40,7 @@
*/
# define mlc_implies(Left_BExpr, Right_BExpr) \
- typename mlc::implies_<Left_BExpr, Right_BExpr>::ret
+ mlc::bexpr_< typename mlc::implies_<Left_BExpr, Right_BExpr>::ret >
# define mlc_implies_(Left_BExpr, Right_BExpr) \
mlc::implies_<Left_BExpr, Right_BExpr>::ret
@@ -61,7 +61,7 @@
template <typename L, typename R>
struct implies_
- : public bool_<( !mlc_bool(L) || mlc_bool(R) )>
+ : public mlc::bexpr_is_<( !mlc_bool(L) || mlc_bool(R) )>
{};
} // end of namespace mlc
Index: mlc/wrap.hh
--- mlc/wrap.hh (revision 428)
+++ mlc/wrap.hh (working copy)
@@ -28,23 +28,10 @@
#ifndef METALIC_WRAP_HH
# define METALIC_WRAP_HH
-# include <mlc/is_a.hh>
-
namespace mlc
{
- /// Forward declarations of types used in specific version of wrap_.
- /// \{
- namespace abstract
- {
- struct value;
- struct boolean;
- }
- /// \}
-
-
-
/*! \class mlc::wrap_<T>
**
** This class is a workaround to the problem of implicit typename
@@ -69,48 +56,6 @@
template <class T>
struct wrap_ : public T
{
- // FIXME: there's no use to unwrap so disabled(?)
- // typedef T unwrap;
- };
-
-
-
- /*! \class mlc::value_wrap_<T>
- **
- ** This class acts like mlc::wrap_<T> but is dedicated to
- ** value types. The parameter \a T should be a value type.
- **
- ** \see mlc::wrap_<T>
- */
-
- template <class T>
- struct value_wrap_ : private assert_< mlc_is_a(T, mlc::abstract::value) >,
- public T
- {
- typedef typename T::type type;
- static const T value = T::value;
- };
-
-
-
- /*! \class mlc::boolean_wrap_<T>
- **
- ** This class acts like mlc::wrap_<T> but is dedicated to Boolean.
- ** The parameter \a T should be a Boolean expression type. FIXME:
- ** there is a confusion between the Boolean value type and Boolean
- ** expression types!!!
- **
- ** \see mlc::wrap_<T>
- */
-
- template <class T>
- struct boolean_wrap_ : private assert_< mlc_is_a(T, mlc::abstract::boolean) >,
- public T
- {
- typedef typename T::type type;
- static const T value = T::value;
-
- typedef typename T::eval eval;
};
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 428)
+++ mlc/is_a.hh (working copy)
@@ -30,6 +30,7 @@
# include <mlc/bool.hh>
# include <mlc/bexpr.hh>
+# include <mlc/wrap.hh>
// private macro so do _not_ use it
@@ -107,7 +108,7 @@
template<class T, class U>
struct ret
- : public bool_<( mlc_internal_is_a_result_ )>
+ : public mlc::bexpr_is_<( mlc_internal_is_a_result_ )>
{
};
};
@@ -130,7 +131,7 @@
template<class T, template < class > class U>
struct ret
- : public bool_<( mlc_internal_is_a_result_ )>
+ : public mlc::bexpr_is_<( mlc_internal_is_a_result_ )>
{
};
};
@@ -153,7 +154,7 @@
template<class T, template < class,class > class U>
struct ret
- : public bool_<( mlc_internal_is_a_result_ )>
+ : public mlc::bexpr_is_<( mlc_internal_is_a_result_ )>
{};
};
@@ -175,7 +176,7 @@
template<class T, template < template < class > class > class
U>
struct ret
- : public bool_<( mlc_internal_is_a_result_ )>
+ : public mlc::bexpr_is_<( mlc_internal_is_a_result_ )>
{};
};
@@ -197,7 +198,7 @@
template<class T, template < template < class,class > class > class
U>
struct ret
- : public bool_<( mlc_internal_is_a_result_ )>
+ : public mlc::bexpr_is_<( mlc_internal_is_a_result_ )>
{};
};
@@ -238,7 +239,7 @@
*/
# define mlc_is_a(T, U) \
-mlc::bexpr_< typename mlc::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 >
Index: mlc/case.hh
--- mlc/case.hh (revision 428)
+++ mlc/case.hh (working copy)
@@ -198,14 +198,16 @@
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, \
+ typedef mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i+1>), \
+ mlc::case_selected) next_case_is_selected; \
+ typedef mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i+1>), \
+ mlc::case_not_selected) next_case_is_not_selected; \
+ \
+ 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; \
+ mlc_bool(next_case_is_selected),
mlc_bool(next_case_is_not_selected) \
+ > handle_next_case_t; \
+ typedef typename handle_next_case_t::ret ret; \
}; \
\
\
@@ -217,14 +219,15 @@
mlc::locked >, \
mlc::ERROR::A_case_STATEMENT_SHOULD_NOT_START_AT_INDEX_0_BUT_1 > \
{ \
- typedef handle_case_ < \
- use, \
+ typedef mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, 1>), \
+ mlc::case_selected) first_case_is_selected; \
+ typedef mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, 1>), \
+ mlc::case_not_selected) first_case_is_not_selected; \
+ 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; \
+ mlc_bool(first_case_is_selected),
mlc_bool(first_case_is_not_selected) \
+ > handle_first_case_t; \
+ typedef typename handle_first_case_t::ret ret; \
}; \
\
\
@@ -260,7 +263,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
Index: mlc/value.hh
--- mlc/value.hh (revision 428)
+++ mlc/value.hh (working copy)
@@ -29,56 +29,8 @@
# define METALIC_VALUE_HH
# include <mlc/type.hh>
-// # include <mlc/wrap.hh>
-
-
-
-/** \def mlc_value(T)
- ** \brief Returns the value of a value type.
- **
- ** Only works when \a T is a value type such as mlc::bool_<b> or
- ** mlc::int_<i>. The result is respectively a bool value and an int
- ** value. Please prefer using this macro to a direct call to
- ** T::value because such a direct call may not compile (read the
- ** design notes below for details).
- **
- ** Design notes: FIXME: doc
- */
-
-// # define mlc_value(T) mlc::wrap_<T>::value
-
-
-
-/// Internal macros.
-
-
-# define mlc_internal_decl_unsigned_(Type, TypeName) \
-namespace internal \
-{ \
- template <Type val> \
- struct value_ <Type, val> : public abstract::unsigned_integer \
- { \
- typedef Type type; \
- static const Type value = val; \
- }; \
-} \
-template <Type val> \
-struct TypeName : public internal::value_<Type, val> {}
-
-
-# define mlc_internal_decl_signed_(Type, TypeName) \
-namespace internal \
-{ \
- template <Type val> \
- struct value_ <Type, val> : public abstract::signed_integer \
- { \
- typedef Type type; \
- static const Type value = val; \
- }; \
-} \
-template <Type val> \
-struct TypeName : public internal::value_<Type, val> {}
-
+// # include <mlc/assert.hh>
+// # include <mlc/is_a.hh>
@@ -99,86 +51,43 @@
{
};
- /// Abstractions for integer values as types.
-
- struct integer : public value {};
- struct unsigned_integer : public integer {};
- struct signed_integer : public integer {};
-
} // end of namespace mlc::abstract
namespace internal
{
- /*! \class mlc::internal::value_<T, val>
- **
- ** Base class for values to be represented by types. This class
- ** is in the internal namespace so you should not use it. Its
- ** purpose is only to factor code for derived classes that are not
- ** internal (for instance, mlc::true_ or mlc::int_<51>).
- **
- ** Design note: this class can only be used for values that can be
- ** a parameter (mlc::internal::value_<float, 3.14f> is incorrect).
- **
- ** Parameter T is the type of the value. Parameter val is the
- ** value itself.
- **
- ** \see mlc/bool.hh
- */
-
- template <typename T, T val>
- struct value_ : public abstract::value
+ template <typename T>
+ struct value_of_
+ // FIXME: commented below to avoid circular dependances
+ // : private assert_< mlc_is_a(T, mlc::abstract::value) >
{
- /*! \typedef type
- **
- ** Gives the regular type of the value. For instance,
- ** mlc::true_::type is bool and mlc::int_<51>::type is int.
- */
- typedef T type;
-
- /*! \member value
- **
- ** Gives the regular value. For instance,
- ** mlc::true_::value is true and mlc::int_<51>::value is 51.
- */
- static const T value = val;
+ static const typename T::type ret = T::value;
};
} // end of namespace mlc::internal
+} // end of namespace mlc
- // Dedicated sub-classes for builtin types.
-
- mlc_internal_decl_unsigned_( unsigned char, uchar_ );
- mlc_internal_decl_unsigned_( unsigned short, ushort_ );
- mlc_internal_decl_unsigned_( unsigned int, uint_ );
- mlc_internal_decl_unsigned_( unsigned long, ulong_ );
-
- mlc_internal_decl_signed_( signed char, schar_ );
- mlc_internal_decl_signed_( signed short, short_ );
- mlc_internal_decl_signed_( signed int, int_ );
- mlc_internal_decl_signed_( signed long, long_ );
-
-
- // char
-
- template <char c>
- struct char_ : public internal::value_<char, c>
- {
- };
-
-
- // Boolean values as types are defined elsewhere
- // see: mlc/bool.hh
+/** \def mlc_value(T)
+ ** \brief Returns the value of a value type.
+ **
+ ** Only works when \a T is a value type such as mlc::bool_<b> or
+ ** mlc::int_<i>. The result is respectively a bool value and an int
+ ** value; for instance mlc_value(mlc::int_<51>) gives 51. Please
+ ** prefer using this macro to a direct call to T::value because such
+ ** a direct call may not compile (read the design notes below for
+ ** details).
+ **
+ ** Design notes: FIXME: doc
+ */
-} // end of namespace mlc
+# define mlc_value(T) mlc::internal::value_of_<T>::ret
-# include <mlc/bool.hh>
#endif // ! METALIC_VALUE_HH
Index: mlc/char.hh
--- mlc/char.hh (revision 0)
+++ mlc/char.hh (revision 0)
@@ -0,0 +1,51 @@
+// 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_CHAR_HH
+# define METALIC_CHAR_HH
+
+# include <mlc/value.hh>
+
+
+
+namespace mlc
+{
+
+ // char
+
+ template <char c>
+ struct char_ : public abstract::value
+ {
+ typedef char type;
+ static const char value = c;
+ };
+
+
+} // end of namespace mlc
+
+
+#endif // ! METALIC_CHAR_HH
Index: mlc/cmp.hh
--- mlc/cmp.hh (revision 428)
+++ mlc/cmp.hh (working copy)
@@ -28,8 +28,9 @@
#ifndef METALIC_CMP_HH
# define METALIC_CMP_HH
-# include <mlc/bool.hh>
+# include <mlc/bexpr.hh>
# include <mlc/is_a.hh>
+# include <mlc/logic.hh>
/// Macros mlc_eq and mlc_neq.
@@ -59,17 +60,14 @@
template <typename T1, typename T2>
struct eq_ : private multiple_assert_< is_not_value<T1>,
is_not_value<T2> >,
- public false_
+ public bexpr_is_<false>
{
};
template <typename T>
struct eq_ <T, T> : private assert_< is_not_value<T> >,
- public true_
+ public bexpr_is_<true>
{
- // Solve the ambiguity on ensure(), a static member function
- // inherited both from true_ and assert_.
- using true_::ensure;
};
/// \}
@@ -78,13 +76,13 @@
template <typename T1, typename T2>
struct neq_ : private multiple_assert_< is_not_value<T1>,
is_not_value<T2> >,
- public true_
+ public bexpr_is_<true>
{
};
template <typename T>
struct neq_ <T, T> : private assert_< is_not_value<T> >,
- public false_
+ public bexpr_is_<false>
{
};
/// \}
@@ -110,9 +108,9 @@
/// Check whether a type is a sound (supposedly before using it).
template <typename T>
- struct is_ok : public and_list_< neq_<T, not_found>,
- neq_<T, not_ok>,
- neq_<T, undefined > >
+ struct is_ok : public and_< neq_<T, not_found>,
+ and_< neq_<T, not_ok>,
+ neq_<T, undefined > > >
{
};
Index: mlc/bexpr.hh
--- mlc/bexpr.hh (revision 428)
+++ mlc/bexpr.hh (working copy)
@@ -28,25 +28,152 @@
#ifndef METALIC_BEXPR_HH
# define METALIC_BEXPR_HH
+# include <mlc/type.hh>
+# include <mlc/flags.hh>
+
+
namespace mlc
{
- /*! \class mlc::bexpr_<T>
+
+ /// Forward declarations for Booleans value type and their aliases.
+ /// \{
+ template <bool b> struct bool_;
+ typedef bool_<true> true_;
+ typedef bool_<false> false_;
+ /// \}
+
+
+
+ namespace abstract {
+
+ /*! \class mlc::abstract::bexpr
+ **
+ ** Abstract base class for mlc Boolean expression types.
**
- ** This class is a wrapper for Boolean expression types. FIXME: doc
+ ** When you define a new class for a Boolean expression type, you
+ ** should not directly derive from this class from fom its
+ ** subclass: bexpr_is_<b>.
**
- ** \see mlc::wrap_<T>
+ ** \see bexpr_is_<b>
*/
- template <class T>
- struct bexpr_ : public T
+ struct bexpr : public type
{
- typedef typename T::eval eval;
+ // typedef void eval;
};
+ } // end of namespace mlc::abstract
+
+
+
+ /*! \class mlc::bexpr_is_<b>
+ **
+ ** Base class for any class of mlc Boolean expression types.
+ ** When you define a new class for a Boolean expression type, you
+ ** should directly derive from this class.
+ **
+ ** This class provides the typedef 'eval' which evaluates to either
+ ** mlc::true_ or mlc::false_ the expression.
+ **
+ ** \see mlc::bexpr_is_<true>, mlc::bexpr_is_<false>
+ */
+
+ template <bool b> struct bexpr_is_;
+
+
+ /*! \class mlc::bexpr_is_<true>
+ **
+ ** Specialization of mlc::bexpr_is_<b> when b is 'true'. This class
+ ** provides the typedef member 'is_true' to every Boolean expression
+ ** type that evaluates to true_.
+ **
+ ** \see mlc::bexpr_is_<b>, mlc::bexpr_is_<false>
+ */
+
+ template <>
+ struct bexpr_is_ < true > : public abstract::bexpr
+ {
+ typedef mlc::true_ eval;
+
+ /*! \typedef is_true
+ **
+ ** This member is inherited in every Boolean expression type that
+ ** evaluates to true_. Conversely, such member does not appear in
+ ** bexpr_is_<false> so it does not exist in every Boolean
+ ** expression type that evaluates to false_.
+ */
+ typedef mlc::dummy is_true;
+ };
+
+
+ /*! \class mlc::bexpr_is_<false>
+ **
+ ** Specialization of mlc::bexpr_is_<b> when b is 'false'. This class
+ ** does not provide the typedef member 'is_true' to every Boolean expression
+ ** type that evaluates to false_.
+ **
+ ** \see mlc::bexpr_is_<b>, mlc::bexpr_is_<true>
+ */
+
+ template <>
+ struct bexpr_is_ < false > : public abstract::bexpr
+ {
+ typedef mlc::false_ eval;
+ };
+
+
+
+
+ namespace internal
+ {
+
+ /// \class mlc::internal::bool_of_<bexpr>
+ /// \brief Returns the bool value corresponding to a Boolean expression type.
+ /// \note Internal class, don't use it directly.
+
+ template <typename bexpr>
+ struct bool_of_
+ // FIXME: commented below to avoid circular dependances
+ // : private assert_< mlc_is_a(bexpr, mlc::abstract::bexpr) >
+ {
+ // 1) the bexpr evaluates to either mlc::true_ or mlc::false_
+ // so the expected result comes from the value of b in
+ // mlc::bool_<b>
+ // 2) retrieving b is performed by the specialization of
+ // internal::bool_of_ provided few lines below
+ static const bool ret = internal::bool_of_<typename bexpr::eval>::ret;
+ };
+
+ /// \class mlc::internal::bool_of_< mlc::bool_<b> >
+ /// \brief Specialization of mlc::internal::bool_of_<bexpr>
+ /// \note Internal class, don't use it directly.
+ /// \see mlc::internal::bool_of_<bexpr>
+ template <bool b>
+ struct bool_of_ < mlc::bool_<b> >
+ {
+ static const bool ret = b;
+ };
+
+ } // end of namespace mlc::internal
+
} // end of namespace mlc
+
+
+/** \def mlc_bool(Bexpr)
+ **
+ ** Returns the bool value corresponding to a Boolean expression type.
+ **
+ ** \note Value retrieval is performed by
+ ** mlc::internal::bool_of_<Bexpr>
+ */
+
+# define mlc_bool(Bexpr) mlc::internal::bool_of_<Bexpr>::ret
+
+
+
#endif // ! METALIC_BEXPR_HH