
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Replace ensure_ (ensure_list_) with assert_ (multiple_assert_). * tests/properties.cc: Fix bug to get compatibility with g++-3.3. * mlc/bool.hh (ensure_item_<i, expr, check>): Rename as... (check_item_<i, bexpr, result>): ...this. (check_<bexpr, result>): New class dedicated to assert_. (retrieve_ensure_): Remove. (ASSERTION_FAILED_, AN_ASSERTION_FAILED_): New internal classes mimicking respectively the old ensure_ and ensure_list_. (no_error_message, no_bexpr): New classes. (ensure_, ensure_list_): Rename as... (assert_, multiple_assert_): ...these. * mlc/pair.hh: Update. * mlc/logic.hh: Update. * mlc/valist.hh: Update. * mlc/implies.hh: Update. * mlc/is_a.hh: Update. * mlc/cmp.hh: Update. mlc/bool.hh | 209 +++++++++++++++++++++++++++++++--------------------- mlc/cmp.hh | 8 - mlc/implies.hh | 2 mlc/is_a.hh | 2 mlc/logic.hh | 4 mlc/pair.hh | 2 mlc/valist.hh | 4 tests/properties.cc | 4 8 files changed, 138 insertions(+), 97 deletions(-) Index: tests/properties.cc --- tests/properties.cc (revision 408) +++ tests/properties.cc (working copy) @@ -99,7 +99,7 @@ typedef mlc::undefined baz_type; }; - class A + struct A { // Aliases. typedef my_type_of_(A, foo) foo_type; @@ -136,7 +136,7 @@ }; // FIXME: Is there any `set_super_type(T)'' sugar available? - class B : public internal::get_super_type<B> + struct B : public internal::get_super_type<B> { // Aliases. typedef my_type_of_(B, foo) foo_type; Index: mlc/pair.hh --- mlc/pair.hh (revision 408) +++ mlc/pair.hh (working copy) @@ -59,7 +59,7 @@ typedef E2 second_elt; template <unsigned i> - struct elt : private ensure_< or_< uint_equal_<i, 1>, + struct elt : private assert_< or_< uint_equal_<i, 1>, uint_equal_<i, 2> > >, public internal::pair_elt_<E1, E2, i> { Index: mlc/bool.hh --- mlc/bool.hh (revision 408) +++ mlc/bool.hh (working copy) @@ -141,11 +141,11 @@ ** 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 - ** "expr::ensure();" and "ensure_<expr..>". For instance: + ** "expr::ensure();" and "assert_<expr..>". For instance: ** or_<mlc_is_a(T, int), mlc_is_a(T, unsigned)>::ensure(); ** ensures that T is int or unsigned without using ::eval. ** - ** \see mlc::true_, mlc::false_, mlc::ensure_<expr..>. + ** \see mlc::true_, mlc::false_, mlc::assert_<expr..>. */ typedef bool_<b> eval; @@ -163,47 +163,71 @@ }; - /*! \class mlc::internal::ensure_item_<i, expr, check> + /*! \class mlc::internal::check_<bexpr, result> ** ** Internal so do not use it. This class is for use in the - ** definition of mlc::ensure_<..>. + ** definition of mlc::assert_<bexpr, err>. ** ** Design note: this class does not derive from abstract::type ** because it is used in inheritance so a ctor should exist. ** - ** \see mlc::ensure_<..> + ** \see mlc::assert_<bexpr, err> */ - template <unsigned i, typename expr, typename check> - struct ensure_item_ + template <typename bexpr, typename result> + struct check_ { }; - /*! \class mlc::internal::retrieve_ensure_ + /*! \class mlc::internal::check_item_<i, bexpr, result> ** ** Internal so do not use it. This class is for use in the - ** definition of mlc::ensure_<..>. + ** definition of mlc::multiple_assert_<..>. ** - ** Design notes: 1) This class does not derive from abstract::type - ** because it is used in inheritance so a ctor should exist. 2) - ** This class provides internal_ensure_ so that it acts like the - ** value 'true' in a sequence of 'and'; it thus has no effect when - ** appearing in an ensure_item_. + ** Design note: this class does not derive from abstract::type + ** because it is used in inheritance so a ctor should exist. ** - ** \see mlc::ensure_<..> + ** \see mlc::multiple_assert_<..> */ - template <typename bexpr> - struct retrieve_ensure_ + template <unsigned i, typename bexpr, typename result> + struct check_item_ { - typedef typename bexpr::internal_ensure_ ret; // provided such as in classes inheriting from true_ }; - template <> - struct retrieve_ensure_ < mlc::none > + + // 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> { - typedef mlc::dummy ret; }; @@ -211,21 +235,42 @@ - /*! \class mlc::ensure_<expr> + /*! \class mlc::no_error_message + ** + ** FIXME: doc + */ + + struct no_error_message; + + + /*! \class mlc::no_bexpr + ** + ** Internal class for use in mlc::multiple_assert_<..>. + */ + + struct no_bexpr + { + typedef dummy is_true; + }; + + + /*! \class mlc::assert_<bexpr, err> + ** + ** FIXME: this doc is partially obsolete! ** ** This class is a replacement for the instruction "expr::ensure();" ** when there is no room for having instruction. The typical use ** is to express a constraint (or several constraints) upon a ** parameter (or several parameters) of a templated class. ** - ** ensure_<expr> only accepts one parameter, which has to be a + ** assert_<expr> only accepts one parameter, which has to be a ** Boolean expression type. An equivalent version for a variadic - ** list of parameters is ensure_list_<expr1,..> + ** list of parameters is multiple_assert_<expr1,..> ** ** Sample use: ** ** template <class T> - ** struct foo : private virtual ensure_< neq_<T, int> > + ** struct foo : private virtual assert_< neq_<T, int> > ** { ... ** }; ** means that T can be any type but int. @@ -233,42 +278,43 @@ ** ** Please avoid the following code: ** template <class T1, class T2> - ** struct bar : private virtual ensure_< neq_<T1, int> >, - ** private virtual ensure_< neq_<T2, int> > + ** struct bar : private virtual assert_< neq_<T1, int> >, + ** private virtual assert_< neq_<T2, int> > ** { ... ** }; ** a better replacement is: ** template <class T1, class T2> - ** struct bar : private virtual ensure_list_< neq_<T1, int>, + ** struct bar : private virtual multiple_assert_< neq_<T1, int>, ** neq_<T2, int> > ** { ... ** }; ** see the design notes below for details. ** - ** Also prefer the use of ensure_list_<expr1, expr2> than the - ** equivalent ensure_< and_<expr1, expr2> >. Actually, the former + ** Also prefer the use of multiple_assert_<expr1, expr2> than the + ** equivalent assert_< and_<expr1, expr2> >. Actually, the former ** provides better error messages since the compiler is able to ** say which expr is not verified, whereas the latter cannot. ** ** ** Design notes: 1) This class does not derive from abstract::type ** because it is used in inheritance so a ctor should exist. 2) - ** This class relies on mlc::internal::ensure_item_ to check that + ** This class relies on mlc::internal::assert_item_ to check that ** the expression is true. 3) When several contrains such as - ** "private ensure_<..>" appear through a hierarchy of classes or + ** "private assert_<..>" appear through a hierarchy of classes or ** for a given class, the program may not compile because of ** multiple inheritance of the same base class; the solution is to - ** systematically write "private virtual ensure_<..>". + ** systematically write "private virtual assert_<..>". ** - ** \see ensure_list_<bexpr1,..> + ** \see multiple_assert_<bexpr1,..> ** */ - template <typename bexpr> - struct ensure_ : - private virtual internal::ensure_item_<0, bexpr, - typename internal::retrieve_ensure_<bexpr>::ret> + template <typename bexpr, typename err = no_error_message> + struct assert_ : public internal::ASSERTION_FAILED_<bexpr, err> { + static void run() {} + protected: + assert_() {} }; @@ -279,14 +325,15 @@ */ template <typename T, typename bexpr> struct iff_ : - private ensure_<bexpr> + private assert_<bexpr> { typedef T ret; }; - - /*! \class mlc::ensure_list_<expr1..> + /*! \class mlc::multiple_assert_<bexpr1..> + ** + ** FIXME: this doc is partially obsolete! ** ** This class is a replacement for a sequence of instructions: ** "expr1::ensure(); .." when there is no room for having @@ -294,63 +341,55 @@ ** several constraints) upon a parameter (or several parameters) ** of a templated class. ** - ** ensure_list_<..> has a variadic list of parameters. It expects + ** multiple_assert_<..> has a variadic list of parameters. It expects ** at least 2 parameters and handles up to 9 parameters. Each ** parameter has to be a Boolean expression type. To check only a - ** single expression, the appropriate tool is ensure_<expr>. + ** single expression, the appropriate tool is assert_<expr>. ** ** ** Sample use: ** ** template <class T1, class T2> - ** struct foo : private virtual ensure_list_< neq_<T1, int>, + ** struct foo : private virtual multiple_assert_< neq_<T1, int>, ** neq_<T2, int> > ** { ... ** }; ** ** Design notes: 1) This class does not derive from abstract::type ** because it is used in inheritance so a ctor should exist. 2) - ** This class relies on mlc::internal::ensure_item_ to check that + ** This class relies on mlc::internal::assert_item_ to check that ** each expression is true. 3) using "virtual" allow to encompass ** the multiple base class problem. ** - ** \see ensure_<expr> + ** \see assert_<bexpr, err> */ template <typename bexpr1, typename bexpr2, - typename bexpr3 = none, - typename bexpr4 = none, - typename bexpr5 = none, - typename bexpr6 = none, - typename bexpr7 = none, - typename bexpr8 = none, - typename bexpr9 = none> - struct ensure_list_ : - private virtual internal::ensure_item_<1, bexpr1, - typename internal::retrieve_ensure_<bexpr1>::ret>, - private virtual internal::ensure_item_<2, bexpr2, - typename internal::retrieve_ensure_<bexpr2>::ret>, - private virtual internal::ensure_item_<3, bexpr3, - typename internal::retrieve_ensure_<bexpr3>::ret>, - private virtual internal::ensure_item_<4, bexpr4, - typename internal::retrieve_ensure_<bexpr4>::ret>, - private virtual internal::ensure_item_<5, bexpr5, - typename internal::retrieve_ensure_<bexpr5>::ret>, - private virtual internal::ensure_item_<6, bexpr6, - typename internal::retrieve_ensure_<bexpr6>::ret>, - private virtual internal::ensure_item_<7, bexpr7, - typename internal::retrieve_ensure_<bexpr7>::ret>, - private virtual internal::ensure_item_<8, bexpr8, - typename internal::retrieve_ensure_<bexpr8>::ret>, - private virtual internal::ensure_item_<9, bexpr9, - typename internal::retrieve_ensure_<bexpr9>::ret> + typename bexpr3 = no_bexpr, + typename bexpr4 = no_bexpr, + typename bexpr5 = no_bexpr, + typename bexpr6 = no_bexpr, + 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> { + static void run() {} + protected: + multiple_assert_() {} }; - /*! \class mlc::bool_<true> ** ** Specialization of mlc::bool_<b> for b set to true. This type @@ -379,28 +418,29 @@ ** "Expr::ensure();" ** ** When there is no room in code for an instruction, use - ** mlc::ensure_<expr1..> instead. + ** mlc::assert_<bexpr> instead. ** ** Design note: This member is a no-op (it has no cost at ** run-time). ** - ** \see: mlc::ensure<expr1..> + ** \see: mlc::assert_<expr> */ static void ensure() {} - /*! \typedef internal_ensure_ + /*! \typedef is_true ** - ** This is internal stuff so do not use it. + ** 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). A static check via - ** "mlc::ensure_<..>" uses this typedef. + ** (and thus no significant value). Static checks via + ** "mlc::assert_<bexpr, err>" rely on the presence or absence of + ** this typedef. ** - ** \see mlc::internal::ensure_item_<i, expr> + ** \see mlc::assert_<bexpr, err> */ - typedef dummy internal_ensure_; + typedef dummy is_true; }; @@ -414,14 +454,15 @@ ** derive either from this type or from mlc::true_. ** ** Conversely to mlc::true_, this class does not feature ensure() - ** nor ensure_. So, when a Boolean expression type, say Expr, + ** nor assert_. So, when a Boolean expression type, say Expr, ** is evaluated to false, the static checks "Expr::ensure();" and - ** "Expr::ensure_" do not compile. + ** "Expr::assert_" 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_. + ** of mlc::internal::value_. 3) Conversely to "mlc::bool_<true>" + ** no typedef "is_true" is provided. ** ** \see mlc::bool_<true> */ Index: mlc/logic.hh --- mlc/logic.hh (revision 408) +++ mlc/logic.hh (working copy) @@ -259,7 +259,7 @@ typename A6 = none, typename A7 = none, typename A8 = none> - struct or_list_ : private ensure_list_< internal::is_bexpr_or_none_<A1>, + 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>, @@ -297,7 +297,7 @@ typename A6 = none, typename A7 = none, typename A8 = none> - struct and_list_ : private ensure_list_< internal::is_bexpr_or_none_<A1>, + 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>, Index: mlc/valist.hh --- mlc/valist.hh (revision 408) +++ mlc/valist.hh (working copy) @@ -46,7 +46,7 @@ # define mlc_internal_valist_elt_spe(I) \ template < mlc_internal_valist_decl_params_ > \ struct valist_elt_ < mlc_internal_valist_params_, I > \ - : private ensure_< neq_<E##I, internal::valist_none> > \ + : private assert_< neq_<E##I, internal::valist_none> > \ { \ typedef E##I ret; \ } @@ -89,7 +89,7 @@ valist_<mlc_internal_valist_params_> >::value; template <unsigned i> - struct elt : private ensure_list_< uint_greater_or_equal_<i, 1>, + struct elt : private multiple_assert_< uint_greater_or_equal_<i, 1>, uint_less_or_equal_<i, size_value> >, public internal::valist_elt_<mlc_internal_valist_params_, i> { Index: mlc/implies.hh --- mlc/implies.hh (revision 408) +++ mlc/implies.hh (working copy) @@ -55,7 +55,7 @@ ** expression types. This class is also a Boolean expression type. ** ** Sample use: - ** mlc::implies_< mlc_is_builtin(T), mlc_eq(T, int) >::ensure(); + ** mlc::implies_< mlc_is_builtin(T), mlc_eq(T, int) >::assert(); ** which means "if T is a buit-in type, it has to be int". */ Index: mlc/is_a.hh --- mlc/is_a.hh (revision 408) +++ mlc/is_a.hh (working copy) @@ -218,7 +218,7 @@ ** A constraint on the parameter of a class, which should be any ** subclass of base<B>, whatever B, can then be easily written: ** template <class T> -** struct foo : private mlc::ensure_< mlc_is_a(T, base) > { +** struct foo : private mlc::assert_< mlc_is_a(T, base) > { ** // ... ** }; ** Index: mlc/cmp.hh --- mlc/cmp.hh (revision 408) +++ mlc/cmp.hh (working copy) @@ -57,14 +57,14 @@ /// Equality test between a couple of types. /// \{ template <typename T1, typename T2> - struct eq_ : private ensure_list_< is_not_value<T1>, + struct eq_ : private multiple_assert_< is_not_value<T1>, is_not_value<T2> >, public false_ { }; template <typename T> - struct eq_ <T, T> : private ensure_< is_not_value<T> >, + struct eq_ <T, T> : private assert_< is_not_value<T> >, public true_ { }; @@ -73,14 +73,14 @@ /// Inequality test between a couple of types. /// \{ template <typename T1, typename T2> - struct neq_ : private ensure_list_< is_not_value<T1>, + struct neq_ : private multiple_assert_< is_not_value<T1>, is_not_value<T2> >, public true_ { }; template <typename T> - struct neq_ <T, T> : private ensure_< is_not_value<T> >, + struct neq_ <T, T> : private assert_< is_not_value<T> >, public false_ { };