427: Create assert.hh from bool.hh contents.

https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Create assert.hh from bool.hh contents. * mlc/bool.hh (mlc_type_iff, mlc::type_iff_): Remove cause soon obsolete. (bool_<true>::ensure()): Remove to force the client to use assert_. (bool_): Add using clauses to make contents explicit. (internal::check_, internal::check_item_): Move to... (literal_, no_error_message, no_bexpr): Move to... (assert_, multiple_assert_): Move to... * mlc/assert.hh: ... this new file. * tests/is_a.cc: Update. * tests/if.cc: Update. * tests/typedef.cc: Update. * mlc/logic.hh: Update. mlc/assert.hh | 234 ++++++++++++++++++++++++++++++++++++++++++++++++ mlc/bool.hh | 267 ++++--------------------------------------------------- mlc/logic.hh | 1 tests/if.cc | 5 - tests/is_a.cc | 5 - tests/typedef.cc | 7 + 6 files changed, 267 insertions(+), 252 deletions(-) Index: tests/is_a.cc --- tests/is_a.cc (revision 426) +++ tests/is_a.cc (working copy) @@ -1,4 +1,5 @@ #include <mlc/is_a.hh> +#include <mlc/assert.hh> struct A {}; struct B : public A {}; @@ -9,6 +10,6 @@ int main () { - mlc_is_a_(B, A)::ensure(); - mlc_is_a_(D<int>, C<int>)::ensure(); + mlc::assert_< mlc_is_a_(B, A) >::check(); + mlc::assert_< mlc_is_a_(D<int>, C<int>) >::check(); } Index: tests/if.cc --- tests/if.cc (revision 426) +++ tests/if.cc (working copy) @@ -1,5 +1,6 @@ #include <mlc/if.hh> #include <mlc/cmp.hh> +#include <mlc/assert.hh> struct alpha; struct beta; @@ -10,8 +11,8 @@ main() { typedef mlc_if_(mlc::true_, alpha, beta) x; - mlc_eq(x, alpha)::ensure(); + mlc::assert_< mlc_eq(x, alpha) >::check(); typedef mlc_if_(mlc::false_, gamma, delta) y; - mlc_eq(y, delta)::ensure(); + mlc::assert_< mlc_eq(y, delta) >::check(); } Index: tests/typedef.cc --- tests/typedef.cc (revision 426) +++ tests/typedef.cc (working copy) @@ -1,5 +1,6 @@ #include <mlc/typedef.hh> #include <mlc/cmp.hh> +#include <mlc/assert.hh> struct foo { @@ -12,6 +13,8 @@ int main () { - mlc_eq(mlc_typedef_(foo, good_type), foo::good_type)::ensure(); - mlc_eq(mlc_typedef_(foo, bad_type), mlc::not_found)::ensure(); + mlc::assert_< mlc_eq(mlc_typedef_(foo, good_type), + foo::good_type) >::check(); + mlc::assert_< mlc_eq(mlc_typedef_(foo, bad_type), + mlc::not_found) >::check(); } Index: mlc/bool.hh --- mlc/bool.hh (revision 426) +++ mlc/bool.hh (working copy) @@ -30,25 +30,14 @@ # include <mlc/value.hh> # include <mlc/flags.hh> -# include <mlc/wrap.hh> -/*! \def mlc_bool(BExpr) +/*! \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 - - - -/*! \def mlc_type_iff(Type, BExpr) -** -** FIXME: doc -*/ -# define mlc_type_iff(Type, BExpr) typename mlc::type_iff_<Type, BExpr>::ret -# define mlc_type_iff_(Type, BExpr) mlc::type_iff_<Type, BExpr>::ret - +# define mlc_bool(Bexpr) mlc::internal::get_bool<Bexpr>::value @@ -141,11 +130,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 "assert_<expr..>". For instance: - ** or_<mlc_is_a(T, int), mlc_is_a(T, unsigned)>::ensure(); + ** "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_<expr..>. + ** \see mlc::true_, mlc::false_, mlc::assert_<bexpr, errmsg>. */ typedef bool_<b> eval; @@ -163,214 +152,10 @@ }; - /*! \class mlc::internal::check_<bexpr, result> - ** - ** Internal so do not use it. This class is for use in the - ** 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::assert_<bexpr, err> - */ - - template <typename bexpr, typename result> - struct check_ - { - }; - - - /*! \class mlc::internal::check_item_<i, bexpr, result> - ** - ** Internal so do not use it. This class is for use in the - ** definition of mlc::multiple_assert_<..>. - ** - ** Design note: this class does not derive from abstract::type - ** because it is used in inheritance so a ctor should exist. - ** - ** \see mlc::multiple_assert_<..> - */ - - template <unsigned i, typename bexpr, typename result> - struct check_item_ - { - }; - } // end of namespace mlc::internal - /*! \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. - ** - ** assert_<expr> only accepts one parameter, which has to be a - ** Boolean expression type. An equivalent version for a variadic - ** list of parameters is multiple_assert_<expr1,..> - ** - ** Sample use: - ** - ** template <class T> - ** struct foo : private virtual assert_< neq_<T, int> > - ** { ... - ** }; - ** means that T can be any type but int. - ** - ** - ** Please avoid the following code: - ** template <class T1, class T2> - ** 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 multiple_assert_< neq_<T1, int>, - ** neq_<T2, int> > - ** { ... - ** }; - ** see the design notes below for details. - ** - ** 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::assert_item_ to check that - ** the expression is true. 3) When several contrains such as - ** "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 assert_<..>". - ** - ** \see multiple_assert_<bexpr1,..> - ** - */ - - template <typename bexpr, typename err = no_error_message> - struct assert_ : - public virtual internal::check_<bexpr, typename bexpr::is_true> - { - public: - static void ensure() {} - protected: - assert_() {} - }; - - - /*! \class mlc::type_iff_<T, bexpr> - ** - ** FIXME: doc - ** returns type T iff bexpr - */ - template <typename T, typename bexpr> - struct type_iff_ : - private assert_<bexpr> - { - typedef T ret; - }; - - - /*! \class mlc::literal_<T> - ** - ** FIXME: doc - */ - - template <typename T> - struct literal_ - { - typedef T ret; - }; - - - /*! \class mlc::multiple_assert_<bexpr1..> - ** - ** FIXME: this doc is partially obsolete! - ** - ** This class is a replacement for a sequence of instructions: - ** "expr1::ensure(); .." when there is no room for having - ** instructions. The typical use is to express a constraint (or - ** several constraints) upon a parameter (or several parameters) - ** of a templated class. - ** - ** 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 assert_<expr>. - ** - ** - ** Sample use: - ** - ** template <class T1, class T2> - ** 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::assert_item_ to check that - ** each expression is true. 3) using "virtual" allow to encompass - ** the multiple base class problem. - ** - ** Limitation: no error message can be provided with this present - ** version of multiple_assert_ so prefer using several assert_. - ** - ** \see assert_<bexpr, err> - */ - - template <typename bexpr1, - typename bexpr2, - 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_ : - private virtual internal::check_item_<1, bexpr1, typename bexpr1::is_true>, - private virtual internal::check_item_<2, bexpr2, typename bexpr2::is_true>, - private virtual internal::check_item_<3, bexpr3, typename bexpr3::is_true>, - private virtual internal::check_item_<4, bexpr4, typename bexpr4::is_true>, - private virtual internal::check_item_<5, bexpr5, typename bexpr5::is_true>, - private virtual internal::check_item_<6, bexpr6, typename bexpr6::is_true>, - private virtual internal::check_item_<7, bexpr7, typename bexpr7::is_true>, - private virtual internal::check_item_<8, bexpr8, typename bexpr8::is_true>, - private virtual internal::check_item_<9, bexpr9, typename bexpr9::is_true> - { - protected: - multiple_assert_() {} - }; - - /*! \class mlc::bool_<true> ** ** Specialization of mlc::bool_<b> for b set to true. This type @@ -388,25 +173,10 @@ template <> struct bool_<true> : public internal::value_<bool, true> { - /*! \member ensure() - ** - ** This member is inherited in every Boolean expression types that - ** derive from mlc::true_. This member is not provided in - ** mlc::false_. - ** - ** A static check to ensure that a Boolean expression type, say - ** Expr, is verified can thus be written as an instruction: - ** "Expr::ensure();" - ** - ** When there is no room in code for an instruction, use - ** mlc::assert_<bexpr> instead. - ** - ** Design note: This member is a no-op (it has no cost at - ** run-time). - ** - ** \see: mlc::assert_<expr> - */ - static void ensure() {} + + // FIXME: doc + using internal::value_<bool, true>::value; + using internal::value_<bool, true>::eval; /*! \typedef is_true ** @@ -434,23 +204,28 @@ ** 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 ensure() - ** nor assert_. So, when a Boolean expression type, say Expr, - ** is evaluated to false, the static checks "Expr::ensure();" and - ** "Expr::assert_" do not compile. + ** 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_. 3) Conversely to "mlc::bool_<true>" - ** no typedef "is_true" is provided. + ** of mlc::internal::value_. ** - ** \see mlc::bool_<true> + ** \see mlc::bool_<true>, mlc::assert_<bexpr, errmsg> */ 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_; Index: mlc/logic.hh --- mlc/logic.hh (revision 426) +++ mlc/logic.hh (working copy) @@ -29,6 +29,7 @@ # define METALIC_LOGIC_HH # include <mlc/bool.hh> +# include <mlc/assert.hh> # include <mlc/flags.hh> Index: mlc/assert.hh --- mlc/assert.hh (revision 0) +++ mlc/assert.hh (revision 0) @@ -0,0 +1,234 @@ +// Copyright (C) 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_ASSERT_HH +# define METALIC_ASSERT_HH + +# include <mlc/bool.hh> + + + +namespace mlc +{ + + + namespace internal + { + + /*! \class mlc::internal::check_<bexpr, result> + ** + ** Internal so do not use it. This class is for use in the + ** 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::assert_<bexpr, err> + */ + + template <typename bexpr, typename result> + struct check_ + { + }; + + + /*! \class mlc::internal::check_item_<i, bexpr, result> + ** + ** Internal so do not use it. This class is for use in the + ** definition of mlc::multiple_assert_<..>. + ** + ** Design note: this class does not derive from abstract::type + ** because it is used in inheritance so a ctor should exist. + ** + ** \see mlc::multiple_assert_<..> + */ + + template <unsigned i, typename bexpr, typename result> + struct check_item_ + { + }; + + } // end of namespace mlc::internal + + + + /*! \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. + ** + ** assert_<expr> only accepts one parameter, which has to be a + ** Boolean expression type. An equivalent version for a variadic + ** list of parameters is multiple_assert_<expr1,..> + ** + ** Sample use: + ** + ** template <class T> + ** struct foo : private virtual assert_< neq_<T, int> > + ** { ... + ** }; + ** means that T can be any type but int. + ** + ** + ** Please avoid the following code: + ** template <class T1, class T2> + ** 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 multiple_assert_< neq_<T1, int>, + ** neq_<T2, int> > + ** { ... + ** }; + ** see the design notes below for details. + ** + ** 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::assert_item_ to check that + ** the expression is true. 3) When several contrains such as + ** "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 assert_<..>". + ** + ** \see multiple_assert_<bexpr1,..> + ** + */ + + template <typename bexpr, typename err = no_error_message> + struct assert_ : + public virtual internal::check_<bexpr, typename bexpr::is_true> + { + public: + static void check() {} + protected: + assert_() {} + }; + + + + /*! \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 + ** instructions. The typical use is to express a constraint (or + ** several constraints) upon a parameter (or several parameters) + ** of a templated class. + ** + ** 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 assert_<expr>. + ** + ** + ** Sample use: + ** + ** template <class T1, class T2> + ** 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::assert_item_ to check that + ** each expression is true. 3) using "virtual" allow to encompass + ** the multiple base class problem. + ** + ** Limitation: no error message can be provided with this present + ** version of multiple_assert_ so prefer using several assert_. + ** + ** \see assert_<bexpr, err> + */ + + template <typename bexpr1, + typename bexpr2, + 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_ : + private virtual internal::check_item_<1, bexpr1, typename bexpr1::is_true>, + private virtual internal::check_item_<2, bexpr2, typename bexpr2::is_true>, + private virtual internal::check_item_<3, bexpr3, typename bexpr3::is_true>, + private virtual internal::check_item_<4, bexpr4, typename bexpr4::is_true>, + private virtual internal::check_item_<5, bexpr5, typename bexpr5::is_true>, + private virtual internal::check_item_<6, bexpr6, typename bexpr6::is_true>, + private virtual internal::check_item_<7, bexpr7, typename bexpr7::is_true>, + private virtual internal::check_item_<8, bexpr8, typename bexpr8::is_true>, + private virtual internal::check_item_<9, bexpr9, typename bexpr9::is_true> + { + public: + static void check() {} + protected: + multiple_assert_() {} + }; + + +} // end of namespace mlc + + +# include <mlc/logic.hh> + + +#endif // ! METALIC_BOOL_HH
participants (1)
-
Thierry Geraud