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