
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Modify mlc::assert_ to handle explicit error messages; also. * mlc/elt.hh: Fix bug. * mlc/pair.hh: Add explicit error messages. * mlc/valist.hh: Likewise. * mlc/bool.hh (ASSERTION_FAILED_, AN_ASSERTION_FAILED_): Remove so that error messages are more concise. (iff_, mlc_iff): Rename as... (type_iff_, mlc_type_iff): ...these. (assert_): Update. * mlc/switch.hh: New. * mlc/is_a.hh (internal::is_a): Move and rename as... (is_a_): ...this so error messages are shortern. * mlc/cmp.hh: Pretty print. bool.hh | 85 ++++++++++------------------ cmp.hh | 0 elt.hh | 4 - is_a.hh | 67 ++++++++++++---------- pair.hh | 12 +++ switch.hh | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ valist.hh | 16 ++++- 7 files changed, 281 insertions(+), 90 deletions(-) Index: mlc/elt.hh --- mlc/elt.hh (revision 411) +++ mlc/elt.hh (working copy) @@ -29,9 +29,9 @@ # define METALIC_ELT_HH -# define mlc_elt(Type, Ith) typename Type::template elt<I>::ret +# define mlc_elt(Type, Index) typename Type::template elt<Index>::ret -# define mlc_elt_(Type, Ith) Type::template elt<I>::ret +# define mlc_elt_(Type, Index) Type::template elt<Index>::ret Index: mlc/pair.hh --- mlc/pair.hh (revision 411) +++ mlc/pair.hh (working copy) @@ -46,6 +46,15 @@ } // end of namespace mlc::internal + + namespace ERROR + { + struct PAIR_ELT_INDEX_SHOULD_BE_1_OR_2; + + } // end of namespace mlc::ERROR + + + /*! \class mlc::pair_<E1, E2> ** ** This class is FIXME */ @@ -60,7 +69,8 @@ template <unsigned i> struct elt : private assert_< or_< uint_equal_<i, 1>, - uint_equal_<i, 2> > >, + uint_equal_<i, 2> >, + ERROR::PAIR_ELT_INDEX_SHOULD_BE_1_OR_2 >, public internal::pair_elt_<E1, E2, i> { }; Index: mlc/bool.hh --- mlc/bool.hh (revision 411) +++ mlc/bool.hh (working copy) @@ -42,12 +42,12 @@ -/*! \def mlc_iff(Type, BExpr) +/*! \def mlc_type_iff(Type, BExpr) ** ** FIXME: doc */ -# define mlc_iff(Type, BExpr) typename mlc::iff_<Type, BExpr>::ret -# define mlc_iff_(Type, BExpr) mlc::iff_<Type, BExpr>::ret +# 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 @@ -196,41 +196,6 @@ { }; - - // 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> - { - }; - - } // end of namespace mlc::internal @@ -310,27 +275,40 @@ */ template <typename bexpr, typename err = no_error_message> - struct assert_ : public internal::ASSERTION_FAILED_<bexpr, err> + struct assert_ : + private virtual internal::check_<bexpr, typename bexpr::is_true> { - static void run() {} + typedef dummy is_true; protected: assert_() {} }; - /*! \class mlc::iff_<T, bexpr> + /*! \class mlc::type_iff_<T, bexpr> ** ** FIXME: doc - ** T iff bexpr + ** returns type T iff bexpr */ template <typename T, typename bexpr> - struct iff_ : + 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! @@ -373,23 +351,22 @@ 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> + 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> { - static void run() {} protected: multiple_assert_() {} }; - /*! \class mlc::bool_<true> ** ** Specialization of mlc::bool_<b> for b set to true. This type Index: mlc/switch.hh --- mlc/switch.hh (revision 0) +++ mlc/switch.hh (revision 0) @@ -0,0 +1,187 @@ +// Copyright (C) 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_SWITCH_HH +# define METALIC_SWITCH_HH + +# include <mlc/bool.hh> +# include <mlc/typedef.hh> +# include <mlc/is_a.hh> +# include <mlc/implies.hh> +# include <mlc/comma.hh> +# include <mlc/cmp.hh> + + +namespace mlc +{ + + // FIXME: doc + + template <typename bexpr> + struct where_ : public bexpr::eval + { + }; + + + + // FIXME: doc + + template <typename context, + typename data, + unsigned i> + struct case_ : public undefined + { + }; + + template <typename context, + typename data> + struct case_ <context, data, 0>; + + + template <typename context, + typename data> + struct default_case_ : public undefined + { + }; + + + namespace ERROR + { + struct A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_; + struct A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_; + struct RESULT_NOT_FOUND; + + } // end of namespace mlc::ERROR + + + namespace internal + { + + template <typename context, typename data, unsigned i, + bool the_ith_case_derives_from_true, + bool the_ith_case_derives_from_false> + struct handle_case_; + + + // impossible situation + template <typename context, typename data, unsigned i> + struct handle_case_ <context, data, i, + 1, 1>; + + template <typename context, typename data> + struct handle_default_case_ + : private assert_< implies_< mlc_is_not_a(mlc_comma_1(default_case_<context, data>), + undefined), + mlc_is_not_a(mlc_comma_1(default_case_<context, data>), + where_) >, + ERROR::A_default_case_STATEMENT_IN_mlc_switch_SHOULD_NOT_DERIVE_FROM_mlc_where_ > + { + typedef mlc_ret( mlc_comma_1(default_case_<context, data>) ) ret; + }; + + // there is no more user-defined cases + // so go to the default case + template <typename context, typename data, unsigned i> + struct handle_case_ <context, data, i, + 0, 0> + : private assert_< implies_< mlc_is_not_a(mlc_comma_2(case_<context, data, i>), + undefined), + mlc_is_a(mlc_comma_2(case_<context, data, i>), + where_) >, + ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ > + { + typedef mlc_ret( mlc_comma_1(handle_default_case_<context, data>) ) ret; + }; + + + // current case is the one + template <typename context, typename data, unsigned i> + struct handle_case_ <context, data, i, + 1, 0> + : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>), + where_), + mlc_is_a(mlc_comma_2(case_<context, data, i>), + undefined) >, + ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ > + { + typedef mlc_ret( mlc_comma_2(case_<context, data, i>) ) ret; + }; + + + // current case is not the one + // so go to the next case + template <typename context, typename data, unsigned i> + struct handle_case_ <context, data, i, + 0, 1> + : private assert_< or_< mlc_is_a(mlc_comma_2(case_<context, data, i>), + where_), + mlc_is_a(mlc_comma_2(case_<context, data, i>), + undefined) >, + ERROR::A_case_STATEMENT_IN_mlc_switch_SHOULD_DERIVE_FROM_mlc_where_ > + { + typedef handle_case_ < context, data, i+1, + mlc_is_a(mlc_comma_2(case_<context, data, i+1>), + true_)::value, + mlc_is_a(mlc_comma_2(case_<context, data, i+1>), + false_)::value > next_t; + typedef typename next_t::ret ret; + }; + + + // switch_ + template <typename context, typename data> + struct switch_ + { + typedef typename internal::handle_case_ < context, data, 1, + mlc_is_a(mlc_comma_2(case_<context, data, 1>), + true_)::value, + mlc_is_a(mlc_comma_2(case_<context, data, 1>), + false_)::value + >::ret ret; + }; + + + } // end of namespace mlc::internal + + + + // FIXME: doc + + template <typename context, typename data> + struct switch_ + : private assert_< neq_<typename internal::switch_<context, data>::ret, + not_found>, + ERROR::RESULT_NOT_FOUND > + { + typedef typename internal::switch_<context, data>::ret ret; + }; + + +} // end of namespace mlc + + +#endif // ! METALIC_SWITCH_HH Index: mlc/valist.hh --- mlc/valist.hh (revision 411) +++ mlc/valist.hh (working copy) @@ -46,7 +46,6 @@ # define mlc_internal_valist_elt_spe(I) \ template < mlc_internal_valist_decl_params_ > \ struct valist_elt_ < mlc_internal_valist_params_, I > \ - : private assert_< neq_<E##I, internal::valist_none> > \ { \ typedef E##I ret; \ } @@ -74,6 +73,15 @@ ** ** This class is FIXME */ + + namespace ERROR + { + struct VALIST_ELT_INDEX_SHOULD_BE_1_OR_GREATER; + struct VALIST_ELT_INDEX_IS_GREATER_THAN_LIST_SIZE; + + } // end of namespace mlc::ERROR + + template < typename E1 = internal::valist_none, typename E2 = internal::valist_none, typename E3 = internal::valist_none, @@ -89,8 +97,10 @@ valist_<mlc_internal_valist_params_> >::value; template <unsigned i> - struct elt : private multiple_assert_< uint_greater_or_equal_<i, 1>, - uint_less_or_equal_<i, size_value> >, + struct elt : private assert_< uint_greater_or_equal_<i, 1>, + ERROR::VALIST_ELT_INDEX_SHOULD_BE_1_OR_GREATER >, + private assert_< uint_less_or_equal_<i, size_value>, + ERROR::VALIST_ELT_INDEX_IS_GREATER_THAN_LIST_SIZE >, public internal::valist_elt_<mlc_internal_valist_params_, i> { }; Index: mlc/is_a.hh --- mlc/is_a.hh (revision 411) +++ mlc/is_a.hh (working copy) @@ -34,7 +34,7 @@ // private macro so do _not_ use it # define mlc_internal_is_a_result_ \ -sizeof(helper<T,U>::select((T*)helper<T,U>::makeT())) == sizeof(yes_) +sizeof(helper<T,U>::select((T*)helper<T,U>::makeT())) == sizeof(internal::yes_) namespace mlc @@ -81,25 +81,27 @@ typedef char yes_; struct no_ { char dummy[2]; }; + } // end of namespace mlc::internal + - // dev note : below, is_a<T,id> is a better factorization + // dev note : below, is_a_<T,id> is a better factorization // but g++ 2.95.4 has some trouble with it template<unsigned id> - struct is_a; + struct is_a_; // class_ template<> - struct is_a< form::class_ > + struct is_a_< form::class_ > { - typedef is_a< form::class_ > self; + typedef is_a_< form::class_ > self; template<class T, class U> struct helper { - static yes_ select(U*); - static no_ select(...); + static internal::yes_ select(U*); + static internal::no_ select(...); static T* makeT(); }; @@ -113,16 +115,16 @@ // template_l_class_r_class_ template<> - struct is_a< form::template_l_class_r_class_ > + struct is_a_< form::template_l_class_r_class_ > { - typedef is_a< form::template_l_class_r_class_ > self; + typedef is_a_< form::template_l_class_r_class_ > self; template<class T, template < class > class U> struct helper { template<class V> - static yes_ select(U<V>*); - static no_ select(...); + static internal::yes_ select(U<V>*); + static internal::no_ select(...); static T* makeT(); }; @@ -136,16 +138,16 @@ // template_l_class_class_r_class_ template<> - struct is_a< form::template_l_class_class_r_class_ > + struct is_a_< form::template_l_class_class_r_class_ > { - typedef is_a< form::template_l_class_class_r_class_ > self; + typedef is_a_< form::template_l_class_class_r_class_ > self; template<class T, template < class,class > class U> struct helper { template<class V, class W> - static yes_ select(U<V,W>*); - static no_ select(...); + static internal::yes_ select(U<V,W>*); + static internal::no_ select(...); static T* makeT(); }; @@ -158,16 +160,16 @@ // template_l_template_l_class_r_class_r_class_ template<> - struct is_a< form::template_l_template_l_class_r_class_r_class_ > + struct is_a_< form::template_l_template_l_class_r_class_r_class_ > { - typedef is_a< form::template_l_template_l_class_r_class_r_class_ > self; + typedef is_a_< form::template_l_template_l_class_r_class_r_class_ > self; template<class T, template < template < class > class > class U> struct helper { template<template<class> class V> - static yes_ select(U<V>*); - static no_ select(...); + static internal::yes_ select(U<V>*); + static internal::no_ select(...); static T* makeT(); }; @@ -180,16 +182,16 @@ // template_l_template_l_class_class_r_class_r_class_ template<> - struct is_a< form::template_l_template_l_class_class_r_class_r_class_ > + struct is_a_< form::template_l_template_l_class_class_r_class_r_class_ > { - typedef is_a< form::template_l_template_l_class_class_r_class_r_class_ > self; + typedef is_a_< form::template_l_template_l_class_class_r_class_r_class_ > self; template<class T, template < template < class,class > class > class U> struct helper { template<template<class,class> class V> - static yes_ select(U<V>*); - static no_ select(...); + static internal::yes_ select(U<V>*); + static internal::no_ select(...); static T* makeT(); }; @@ -199,7 +201,6 @@ {}; }; - } // end of namespace mlc::internal } // end of namespace mlc @@ -237,19 +238,25 @@ */ # define mlc_is_a(T, U) \ -mlc::wrap_<typename mlc::internal::is_a<sizeof(mlc::form::of<U >())>::ret<T,U > > +mlc::wrap_< typename mlc::is_a_<sizeof(mlc::form::of<U >())>::ret<T,U > > +# define mlc_is_a_(T, U) \ +mlc::is_a_< sizeof(mlc::form::of<U >())>::ret<T,U > -/*! \def mlc_is_a_(T, U) + +/*! \def mlc_is_not_a(T, U) ** -** Macro equivalent as mlc_is_a(T, U) for use in a non templated -** context. The result is a Boolean expression type. +** Macro equivalent as "not mlc_is_a(T, U)". The result is a Boolean +** expression type. ** ** \see mlc_is_a(T, U) */ -# define mlc_is_a_(T, U) \ -mlc::wrap_<mlc::internal::is_a< sizeof(mlc::form::of<U >())>::ret<T,U > > +# define mlc_is_not_a(T, U) \ +mlc::not_< typename mlc::is_a_<sizeof(mlc::form::of<U >())>::ret<T,U > > + +# define mlc_is_not_a_(T, U) \ +mlc::not_< mlc::is_a_< sizeof(mlc::form::of<U >())>::ret<T,U > > #endif // ! METALIC_IS_A_HH Index: mlc/cmp.hh