
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from 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. bool.hh | 244 ++++++++++++----------------------------------- logic.hh | 323 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 388 insertions(+), 179 deletions(-) Index: mlc/bool.hh --- mlc/bool.hh (revision 403) +++ mlc/bool.hh (working copy) @@ -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 @@ }; - /*! \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 @@ ** \see mlc::ensure_<..> */ - struct none_ + template <typename bexpr> + struct retrieve_ensure_ + { + typedef typename bexpr::internal_ensure_ ret; // provided such as in classes inheriting from true_ + }; + + template <> + struct retrieve_ensure_ < mlc::none > { - typedef none_ internal_ensure_; // provided such as in classes inheriting from true_ + typedef mlc::dummy ret; }; @@ -239,17 +254,27 @@ ** 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 @@ ** \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 @@ ** ** \see mlc::internal::ensure_item_<i, expr> */ - typedef internal::none_ internal_ensure_; + typedef dummy internal_ensure_; }; @@ -390,158 +424,10 @@ 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 Index: mlc/logic.hh --- mlc/logic.hh (revision 0) +++ mlc/logic.hh (revision 0) @@ -0,0 +1,323 @@ +// 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_< 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 > + { + }; + + +} // end of namespace mlc + + +#endif // ! METALIC_LOGIC_HH