Commit 26c4d911 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Split bool.hh to move logical ops in an independant file.

- mlc/bool.hh: Move logical ops in...
- mlc/logic.hh: this new file.
(ors_, ands_): Rename as...
(or_list_, and_list_): ...these.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@404 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent d5db6ee5
2006-02-15 Thierry Geraud <theo@lrde.epita.fr>
Split bool.hh to move logical ops in an independant file.
* mlc/bool.hh: Move logical ops in...
* mlc/logic.hh: this new file.
(ors_, ands_): Rename as...
(or_list_, and_list_): ...these.
2006-02-14 Roland Levillain <roland@lrde.epita.fr>
Add the old properties system.
......
......@@ -29,14 +29,22 @@
# define METALIC_BOOL_HH
# include <mlc/value.hh>
# include <mlc/flags.hh>
/*! \macro mlc_bool(T)
/*! \macro mlc_bool(BExpr)
**
** Macro that retrieves a Boolean value from a Boolean expression type
** T. Its result is either true or false.
** Macro that retrieves a Boolean value from a Boolean expression type.
** Its result is either true or false.
*/
# define mlc_bool(Type) mlc::internal::get_bool<Type>::value
# define mlc_bool(BExpr) mlc::internal::get_bool<BExpr>::value
// FIXME: keep it or not?
# define mlc_type_when(T, BExpr) \
typename type_when_<T, BExpr>::ret
namespace mlc
......@@ -166,7 +174,7 @@ namespace mlc
};
/*! \class mlc::internal::none_
/*! \class mlc::internal::retrieve_ensure_
**
** Internal so do not use it. This class is for use in the
** definition of mlc::ensure_<..>.
......@@ -180,9 +188,16 @@ namespace mlc
** \see mlc::ensure_<..>
*/
struct none_
template <typename bexpr>
struct retrieve_ensure_
{
typedef none_ internal_ensure_; // provided such as in classes inheriting from true_
typedef typename bexpr::internal_ensure_ ret; // provided such as in classes inheriting from true_
};
template <>
struct retrieve_ensure_ < mlc::none >
{
typedef mlc::dummy ret;
};
......@@ -239,17 +254,27 @@ namespace mlc
** multiple inheritance of the same base class; the solution is to
** systematically write "private virtual ensure_<..>".
**
** \see ensure_list_<expr1,..>
** \see ensure_list_<bexpr1,..>
**
*/
template <typename expr>
template <typename bexpr>
struct ensure_ :
private virtual internal::ensure_item_<0, expr, typename expr::internal_ensure_>
private virtual internal::ensure_item_<0, bexpr,
typename internal::retrieve_ensure_<bexpr>::ret>
{
};
// FIXME: keep it or not?
template <typename T, typename bexpr>
struct type_when_ :
private ensure_<bexpr>
{
typedef T ret;
};
/*! \class mlc::ensure_list_<expr1..>
**
......@@ -282,25 +307,34 @@ namespace mlc
** \see ensure_<expr>
*/
template <typename expr_1,
typename expr_2,
typename expr_3 = internal::none_,
typename expr_4 = internal::none_,
typename expr_5 = internal::none_,
typename expr_6 = internal::none_,
typename expr_7 = internal::none_,
typename expr_8 = internal::none_,
typename expr_9 = internal::none_>
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, expr_1, typename expr_1::internal_ensure_>,
private virtual internal::ensure_item_<2, expr_2, typename expr_2::internal_ensure_>,
private virtual internal::ensure_item_<3, expr_3, typename expr_3::internal_ensure_>,
private virtual internal::ensure_item_<4, expr_4, typename expr_4::internal_ensure_>,
private virtual internal::ensure_item_<5, expr_5, typename expr_5::internal_ensure_>,
private virtual internal::ensure_item_<6, expr_6, typename expr_6::internal_ensure_>,
private virtual internal::ensure_item_<7, expr_7, typename expr_7::internal_ensure_>,
private virtual internal::ensure_item_<8, expr_8, typename expr_8::internal_ensure_>,
private virtual internal::ensure_item_<9, expr_9, typename expr_9::internal_ensure_>
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>
{
};
......@@ -356,7 +390,7 @@ namespace mlc
**
** \see mlc::internal::ensure_item_<i, expr>
*/
typedef internal::none_ internal_ensure_;
typedef dummy internal_ensure_;
};
......@@ -390,158 +424,10 @@ namespace mlc
typedef bool_<false> false_;
/*! \class mlc::not_<T>
**
** Logical unary 'not' operator on a Boolean expression type. This
** class is also a Boolean expression type.
*/
template <typename T> struct not_ : public bool_<(!mlc_bool(T))> {};
/*! \class mlc::and_<L,R>
**
** Logical binary 'and' operator on a couple of Boolean expression
** types. This class is also a Boolean expression type.
**
** \see mlc::ands_<..>
*/
template <typename L, typename R> struct and_ : public bool_< (mlc_bool(L) && mlc_bool(R)) > {};
/*! \class mlc::nand_<L,R>
**
** Logical binary 'not and' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
**
** Design note: an equivalent is mlc::not_< mlc::and_<L,R> >.
*/
template <typename L, typename R> struct nand_ : public bool_<(!(mlc_bool(L) && mlc_bool(R)))> {};
/*! \class mlc::or_<L,R>
**
** Logical binary 'or' operator on a couple of Boolean expression
** types. This class is also a Boolean expression type.
**
** \see mlc::ors_<..>
*/
template <typename L, typename R> struct or_ : public bool_< (mlc_bool(L) || mlc_bool(R)) > {};
/*! \class mlc::nor_<L,R>
**
** Logical binary 'not or' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
**
** Design note: an equivalent is mlc::not_< mlc::or_<L,R> >.
*/
template <typename L, typename R> struct nor_ : public bool_<(!(mlc_bool(L) || mlc_bool(R)))> {};
/*! \class mlc::xor_<L,R>
**
** Logical binary 'exclusive or' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
*/
template <typename L, typename R> struct xor_ : public bool_< (mlc_bool(L) != mlc_bool(R)) > {};
/*! \class mlc::xnor_<L,R>
**
** Logical binary 'exclusive not or' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
*/
template <typename L, typename R> struct xnor_ : public bool_<(!(mlc_bool(L) != mlc_bool(R)))> {};
/// Internal helpers for logical operators between several Boolean types
namespace internal
{
// ors_2_
template <typename A1, typename A2> struct ors_2_ : public or_<A1, A2> {};
template <> struct ors_2_ <none_, none_> : public true_ {};
template <typename A1> struct ors_2_ <A1, none_> : public A1 {};
template <typename A2> struct ors_2_ <none_, A2>;
// ors_4_
template <typename A1, typename A2,
typename A3, typename A4>
struct ors_4_ : public ors_2_< ors_2_<A1, A2>,
ors_2_<A3, A4> > {};
template <>
struct ors_4_ <none_, none_, none_, none_> : public true_ {};
// ors_8_
template <typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8>
struct ors_8_ : public ors_2_< ors_4_<A1, A2, A3, A4>,
ors_4_<A5, A6, A7, A8> > {};
// ands_2_
template <typename A1, typename A2> struct ands_2_ : public and_<A1, A2> {};
template <> struct ands_2_ <none_, none_> : public true_ {};
template <typename A1> struct ands_2_ <A1, none_> : public A1 {};
template <typename A2> struct ands_2_ <none_, A2>;
// ands_4_
template <typename A1, typename A2,
typename A3, typename A4>
struct ands_4_ : public ands_2_< ands_2_<A1, A2>,
ands_2_<A3, A4> > {};
template <>
struct ands_4_ <none_, none_, none_, none_> : public true_ {};
// ands_8_
template <typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8>
struct ands_8_ : public ands_2_< ands_4_<A1, A2, A3, A4>,
ands_4_<A5, A6, A7, A8> > {};
} // end of mlc::internal
/*! \class mlc::ors_<..>
**
** 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::ors_< mlc::eq_<T, int>,
** mlc_is_a(T, mlc::int_),
** mlc_is_a(T, my::integer) >
**
** \see mlc::or_<L,R> mlc::ands_<..>
*/
template <typename A1,
typename A2,
typename A3,
typename A4 = internal::none_,
typename A5 = internal::none_,
typename A6 = internal::none_,
typename A7 = internal::none_,
typename A8 = internal::none_>
struct ors_ : public internal::ors_8_< A1, A2, A3, A4, A5, A6, A7, A8 >
{
};
/*! \class mlc::ands_<..>
**
** 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::ors_<..>
*/
template <typename A1,
typename A2,
typename A3,
typename A4 = internal::none_,
typename A5 = internal::none_,
typename A6 = internal::none_,
typename A7 = internal::none_,
typename A8 = internal::none_>
struct ands_ : public internal::ands_8_< A1, A2, A3, A4, A5, A6, A7, A8 >
{
};
} // end of namespace mlc
} // end of namespace mlc
# include <mlc/logic.hh>
#endif // ! METALIC_BOOL_HH
// Copyright (C) 2001, 2002, 2003, 2004, 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_LOGIC_HH
# define METALIC_LOGIC_HH
# include <mlc/bool.hh>
# include <mlc/flags.hh>
namespace mlc
{
/*! \class mlc::not_<T>
**
** Logical unary 'not' operator on a Boolean expression type. This
** class is also a Boolean expression type.
*/
template <typename T>
struct not_
: public bool_<( !mlc_bool(T) )>
{};
/*! \class mlc::and_<L,R>
**
** Logical binary 'and' operator on a couple of Boolean expression
** types. This class is also a Boolean expression type.
**
** \see mlc::and_list_<..>
*/
template <typename L, typename R>
struct and_
: public bool_<( mlc_bool(L) && mlc_bool(R) )>
{};
/*! \class mlc::nand_<L,R>
**
** Logical binary 'not and' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
**
** Design note: an equivalent is mlc::not_< mlc::and_<L,R> >.
*/
template <typename L, typename R>
struct nand_
: public bool_<( !(mlc_bool(L) && mlc_bool(R)) )>
{};
/*! \class mlc::or_<L,R>
**
** Logical binary 'or' operator on a couple of Boolean expression
** types. This class is also a Boolean expression type.
**
** \see mlc::or_list_<..>
*/
template <typename L, typename R>
struct or_
: public bool_<( mlc_bool(L) || mlc_bool(R) )>
{};
/*! \class mlc::nor_<L,R>
**
** Logical binary 'not or' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
**
** Design note: an equivalent is mlc::not_< mlc::or_<L,R> >.
*/
template <typename L, typename R>
struct nor_
: public bool_<( !(mlc_bool(L) || mlc_bool(R)) )>
{};
/*! \class mlc::xor_<L,R>
**
** Logical binary 'exclusive or' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
*/
template <typename L, typename R>
struct xor_
: public bool_<( mlc_bool(L) != mlc_bool(R) )>
{};
/*! \class mlc::xnor_<L,R>
**
** Logical binary 'exclusive not or' operator on a couple of Boolean
** expression types. This class is also a Boolean expression type.
*/
template <typename L, typename R>
struct xnor_
: public bool_<( !(mlc_bool(L) != mlc_bool(R)) )>
{};
/// 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 ensure_list_< 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 ensure_list_< 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_< typena