Commit dc064b57 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

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.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@409 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent f35df02f
2006-02-16 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.
2006-02-15 Thierry Geraud <theo@lrde.epita.fr>
Add new features such as variadic type list.
......
......@@ -141,11 +141,11 @@ namespace mlc
** 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 @@ namespace mlc
};
/*! \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 @@ namespace mlc
/*! \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 @@ namespace mlc
**
** 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 @@ namespace mlc
*/
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 @@ namespace mlc
** 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 @@ namespace mlc
** "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 @@ namespace mlc
** 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>
*/
......
......@@ -57,14 +57,14 @@ namespace mlc
/// 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 @@ namespace mlc
/// 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_
{
};
......
......@@ -55,7 +55,7 @@ namespace mlc
** 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".
*/
......
......@@ -218,7 +218,7 @@ namespace mlc
** 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) > {
** // ...
** };
**
......
......@@ -259,7 +259,7 @@ namespace mlc
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 @@ namespace mlc
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>,
......
......@@ -59,7 +59,7 @@ namespace mlc
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>
{
......
......@@ -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 @@ namespace mlc
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>
{
......
......@@ -99,7 +99,7 @@ namespace my
typedef mlc::undefined baz_type;
};
class A
struct A
{
// Aliases.
typedef my_type_of_(A, foo) foo_type;
......@@ -136,7 +136,7 @@ namespace my
};
// 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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment