
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@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