
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Add protection mechanism to case definitions and update. * tests/switch.cc: Update. * tests/protected.cc: New file. * tests/Makefile.am (protected): New entry. * mlc/ret.hh (mlc_ret_, mlc_ret_found_in): New macros. (ret_found_in_): Update. * mlc/if.hh (FIXME): Remove. (if_): Change inheritance into composition. * mlc/typedef.hh: Cosmetics. * mlc/switch.hh (mlc_switch, mlc_switch_): New macros. * mlc/TODO: Update. * mlc/case.hh (mlc_case, mlc_case_): New macros. (ERROR): Update and augment. (WARNING): New. (mlc_case_equipment_for_namespace): Update to handle protected_. * mlc/cmp.hh (mlc_is_found, mlc_is_not_found): New macros. (mlc_is_undefined, mlc_is_defined): New macros. (mlc_is_ok, mlc_is_not_ok): New macros. (is_value, is_not_value): Update. (is_not_found_, is_found_): Update. (is_not_ok_, is_ok_): Update. mlc/TODO | 51 ++++++++++--- mlc/case.hh | 194 +++++++++++++++++++++++++++++++++++++++++++++-------- mlc/cmp.hh | 64 +++++++++++++++-- mlc/if.hh | 12 ++- mlc/ret.hh | 13 +++ mlc/switch.hh | 12 +++ mlc/typedef.hh | 4 - tests/Makefile.am | 2 tests/protected.cc | 149 ++++++++++++++++++++++++++++++++++++++++ tests/switch.cc | 54 ++++++++++++++ 10 files changed, 501 insertions(+), 54 deletions(-) Index: tests/switch.cc --- tests/switch.cc (revision 446) +++ tests/switch.cc (working copy) @@ -31,7 +31,7 @@ typedef int ret; }; -// // or: +// // ok // template <class T> // struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) > @@ -39,6 +39,20 @@ // typedef mlc::not_found ret; // }; +// // ok + +// template <class T> +// struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) > +// { +// struct protected_ { +// typedef mlc::not_found ret; +// }; +// }; + + + + + // // ko @@ -54,6 +68,21 @@ // }; // template <class T> +// struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) > +// { +// struct protected_ { +// }; +// typedef int ret; +// }; + +// template <class T> +// struct case_ <test, T, 3> : public mlc::where_< mlc_is_a(T, char) > +// { +// struct protected_ { +// }; +// }; + +// template <class T> // struct case_ <test, T, 3> // { // typedef int ret; @@ -70,10 +99,33 @@ // { // }; +// template <class T> +// struct default_case_ <test, T> : public mlc::where_< mlc_is_a(T, char) > +// { +// typedef int ret; +// }; + +// template <class T> +// struct default_case_ <test, T> +// { +// struct protected_ { +// typedef int ret; +// } +// typedef int ret; +// }; + +// template <class T> +// struct default_case_ <test, T> +// { +// struct protected_ { +// } +// }; + } // end of namespace client + template <class T> void print() { Index: tests/Makefile.am --- tests/Makefile.am (revision 446) +++ tests/Makefile.am (working copy) @@ -12,6 +12,7 @@ if \ is_a \ or \ + protected \ ret \ switch \ typedef @@ -20,6 +21,7 @@ if_SOURCES = if.cc is_a_SOURCES = is_a.cc or_SOURCES = or.cc +protected_SOURCES = protected.cc ret_SOURCES = ret.cc switch_SOURCES = switch.cc typedef_SOURCES = typedef.cc Index: tests/protected.cc --- tests/protected.cc (revision 0) +++ tests/protected.cc (revision 0) @@ -0,0 +1,149 @@ +#include <mlc/switch.hh> +#include <mlc/cmp.hh> +#include <mlc/typedef.hh> +#include <mlc/assert.hh> +#include <mlc/implies.hh> + + +mlc_case_equipment_for_namespace(client); +mlc_decl_typedef(protected_); + +template <typename T> +void reveal() +{ + T tmp; +} + + + +namespace client +{ + + struct A + { + typedef bool typedef_in_A_only; + }; + + struct B + { + typedef char typedef_in_B_only; + }; + + + + // simple_test + + struct simple_test; + + template <class T> + struct case_ <simple_test, T, 1> : public mlc::where_< mlc_eq(T, A) > + { + typedef A ret; + }; + + template <class T> + struct case_ <simple_test, T, 2> : public mlc::where_< mlc_eq(T, B) > + { + typedef B ret; + }; + + + // test_ok + + struct test_ok; + + template <class T> + struct case_ <test_ok, T, 1> : public mlc::where_< mlc_eq(T, A) > + { + typedef typename A::typedef_in_A_only ret; + }; + + template <class T> + struct case_ <test_ok, T, 2> : public mlc::where_< mlc_eq(T, B) > + { + typedef typename B::typedef_in_B_only ret; + }; + + + + // test_KO + + struct test_KO; + + template <class T> + struct case_ <test_KO, T, 1> : public mlc::where_< mlc_eq(T, A) > + { + typedef typename T::typedef_in_A_only ret; + }; + + template <class T> + struct case_ <test_KO, T, 2> : public mlc::where_< mlc_eq(T, B) > + { + typedef typename T::typedef_in_B_only ret; + }; + + + // test_soluce + + struct test_soluce; + + template <class T> + struct case_ <test_soluce, T, 1> : public mlc::where_< mlc_eq(T, A) > + { + struct protected_ { + typedef typename T::typedef_in_A_only ret; + }; + }; + + template <class T> + struct case_ <test_soluce, T, 2> : public mlc::where_< mlc_eq(T, B) > + { + // typedef mlc::dummy ret; + struct protected_ { + typedef typename T::typedef_in_B_only ret; + }; + }; + + + +} // end of namespace client + + +struct ERROR_USE_EITHER_PROTECT_OR_RET_IN_A_CASE; + + + +int main() +{ + + using namespace client; + + typedef switch_<simple_test, B>::ret type; + reveal<type>(); + + + // typedef switch_<test, B> ::ret type; + // which is equiv to: + // typedef case_<test, B>::ret ::ret type; + +// typedef case_<test_soluce, B>::ret ::protect::ret type; + + + + +// typedef case_<test_soluce, B>::ret the_case; +// typedef mlc_typedef_(the_case, protected_) the_case_protected; +// typedef mlc_ret_(the_case) the_case_ret; + +// mlc::assert_< mlc::xor_< mlc_is_found(the_case_protected), +// mlc_is_found(the_case_ret) >, +// ERROR_USE_EITHER_PROTECT_OR_RET_IN_A_CASE +// >::check(); + +// typedef mlc::if_< mlc::eq_< the_case_protected, mlc::not_found >, +// the_case_ret, +// mlc_ret_(the_case_protected) >::ret result; + + +// reveal<result>(); +} Index: mlc/ret.hh --- mlc/ret.hh (revision 446) +++ mlc/ret.hh (working copy) @@ -48,7 +48,14 @@ +/// \{ +/// Macros mlc_ret and mlc_ret_. + # define mlc_ret(Type) typename mlc::typedef_::ret::from_<Type>::ret +# define mlc_ret_(Type) mlc::typedef_::ret::from_<Type>::ret + +/// \} + // test code @@ -62,10 +69,14 @@ template <typename T> struct ret_found_in_ : public mlc::eq_< typename mlc::typedef_::ret::from_<T>::ret2::first_elt, - mlc::found > + mlc::found >::bexpr {}; } // end of namespace mlc +# define mlc_ret_found_in(T) mlc::ret_found_in_<T> + + + #endif // ! METALIC_RET_HH Index: mlc/if.hh --- mlc/if.hh (revision 446) +++ mlc/if.hh (working copy) @@ -53,10 +53,11 @@ namespace ERROR { - struct FIXME; + struct THE_FIRST_PARAMETER_OF_AN_mlc_if_SHOULD_BE_AN_mlc_bexpr; } // end of mlc::ERROR + namespace internal { @@ -92,13 +93,16 @@ ** \note \a Then and \a Else must be valid types, since they are both ** evaluated, whatever the result of \a Cond. */ + template <typename cond_type, typename then_type, typename else_type> struct if_ : - // FIXME: enable the static assertion below!!! + private assert_< mlc_is_a(cond_type, mlc::abstract::bexpr), - mlc::ERROR::FIXME >, - public internal::if_ < mlc_bool(cond_type), then_type, else_type > + mlc::ERROR::THE_FIRST_PARAMETER_OF_AN_mlc_if_SHOULD_BE_AN_mlc_bexpr > { + typedef typename internal::if_< mlc_bool(cond_type), + then_type, + else_type >::ret ret; }; } // end of namespace mlc Index: mlc/typedef.hh --- mlc/typedef.hh (revision 446) +++ mlc/typedef.hh (working copy) @@ -242,6 +242,9 @@ + + + /*! \macro mlc_typedef_in(Namespace, Type, TypedefName) ** ** FIXME: doc @@ -254,7 +257,6 @@ Namespace::typedef_::TypedefName::from_<Type>::ret - /*! \macro mlc_typedef_onlyif(Type, TypedefName, Bexpr) ** ** FIXME: doc Index: mlc/switch.hh --- mlc/switch.hh (revision 446) +++ mlc/switch.hh (working copy) @@ -32,4 +32,16 @@ # include <mlc/case.hh> +/// Macros mlc_switch and mlc_switch_. +/// \{ + +# define mlc_switch(Namespace, Context, Data) \ + typename Namespace::switch_<Context, Data>::ret + +# define mlc_switch_(Namespace, Context, Data) \ + Namespace::switch_<Context, Data>::ret + +/// \} + + #endif // ! METALIC_SWITCH_HH Index: mlc/TODO --- mlc/TODO (revision 446) +++ mlc/TODO (working copy) @@ -2,15 +2,6 @@ * files -** bool.hh - -create assert.hh from parts of bool.hh - -** boolean and bexpr - -there is a confusion between mlc::abstract::boolean and the notion of -bexpr (Boolean expression type)! - ** value.hh This file mixes bool_, int_, etc. so I should be split into several @@ -21,7 +12,22 @@ * addition -mlc_eval (such as mlc_bool and mlc_value) +** macros + +*** mlc_eval + +mlc_eval should exist (in a similar way to mlc_bool and mlc_value) + +*** mlc_value + +rec pb + +** cmp.hh + +clearly check that params are neither values not bexprs + +clearly state the difference (and use cases) between mlc_eq and mlc_is_a +then check that is_something facilities conform to the use case rules * renaming @@ -50,6 +56,29 @@ works well and we do not have to write mlc_is_a_ with the '_' at the end so that's better. yet is it a direct consequence of the wrapping? +** if_ + +then_type and else_type are not protected; find a solution + +** logic.hh + +add some tests to check that err msg are ok +(the pb is that they may propagate...) + + + + +* DONE! + +** bool.hh + +create assert.hh from parts of bool.hh + +** boolean and bexpr + +there is a confusion between mlc::abstract::boolean and the notion of +bexpr (Boolean expression type)! + ** boolean and bexpr the last part of the disambiguation between boolean and bexpr is to @@ -63,5 +92,3 @@ static checks should change *** remove eval in true_ and false_ - - Index: mlc/case.hh --- mlc/case.hh (revision 446) +++ mlc/case.hh (working copy) @@ -30,6 +30,7 @@ # include <mlc/bexpr.hh> # include <mlc/assert.hh> +# include <mlc/abort.hh> # include <mlc/ret.hh> # include <mlc/is_a.hh> # include <mlc/implies.hh> @@ -38,6 +39,19 @@ # include <mlc/if.hh> +/// Macros mlc_case and mlc_case_. +/// \{ + +# define mlc_case(Namespace, Context, Data) \ + typename Namespace::case_<Context, Data>::ret + +# define mlc_case_(Namespace, Context, Data) \ + Namespace::case_<Context, Data>::ret + +/// \} + + + // FIXME: doc this file! @@ -59,14 +73,52 @@ namespace ERROR { + struct PARAMETER_OF_mlc_where_SHOULD_BE_A_BEXPR; + struct A_case_STATEMENT_SHOULD_NOT_START_AT_INDEX_0_BUT_1; + struct A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_; struct A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_; + + struct A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_EITHER_A_ret_OR_A_protected; + struct A_default_case_STATEMENT_IN_A_switch_SHOULD_NOT_HAVE_BOTH_A_ret_AND_A_protected; + struct THE_protected_PART_OF_A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret; + + struct A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_EITHER_A_ret_OR_A_protected; + struct A_case_STATEMENT_IN_A_switch_SHOULD_NOT_HAVE_BOTH_A_ret_AND_A_protected; + struct THE_protected_PART_OF_A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret; + struct NO_case_STATEMENT_CAN_BE_SELECTED; - struct A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret; - struct A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret; - struct PARAMETER_OF_mlc_where_SHOULD_BE_A_BEXPR; - } + + } // end of namespace mlc::ERROR + + + namespace WARNING + { + struct NO_default_case_STATEMENT_HAS_BEEN_DEFINED; + + } // end of namespace mlc::WARNING + + + + namespace internal + { + + template <typename T, typename T_is_bexpr> + struct where_; + + template <typename bexpr> + struct where_ < bexpr, mlc::true_ > + : public mlc_if_(bexpr, case_selected, case_not_selected) + { + }; + + template <typename T> + struct where_ < T, mlc::false_ > + { + }; + + } // end of namespace mlc::internal template <typename bexpr> @@ -75,11 +127,17 @@ private assert_< mlc_is_a(bexpr, mlc::abstract::bexpr), mlc::ERROR::PARAMETER_OF_mlc_where_SHOULD_BE_A_BEXPR >, - public mlc_if_( bexpr, case_selected, case_not_selected ) + // hack so that the error above cannot propagate to the mlc_if_ + public internal::where_< bexpr, + typename mlc_is_a(bexpr, mlc::abstract::bexpr)::eval > { }; + + mlc_decl_typedef(protected_); + + } // end of namespace mlc @@ -114,6 +172,17 @@ }; \ \ \ + template <typename a_case> \ + struct protected_in_ \ + { \ + typedef typename mlc::typedef_::protected_::from_<a_case>::ret the; \ + typedef typename mlc::is_found_<the>::bexpr is_found; \ + typedef typename mlc::ret_found_in_<the>::bexpr is_found_with_ret; \ + typedef mlc_ret(the) ret; \ + }; \ + \ + \ + \ namespace internal \ { \ \ @@ -129,20 +198,53 @@ struct handle_case_ <use, context, data, i, 1, 1>; \ \ \ - template <typename use, typename context, typename data> \ - struct handle_default_case_ \ + template <typename use, \ + typename context, typename data> \ + struct handle_default_case_; \ + \ \ - : private mlc::assert_< mlc::implies_< mlc_is_not_a(mlc_comma_1(NAMESPACE::default_case_<context, data>), \ - mlc::undefined), \ + \ + template <typename context, typename data> \ + struct handle_default_case_ < mlc::internal::a_simple_case, context, data > \ + \ + : private mlc::assert_< mlc::implies_< mlc::is_defined_< NAMESPACE::default_case_<context, data> >, \ mlc_is_not_a(mlc_comma_1(NAMESPACE::default_case_<context, data>), \ mlc::where_) >, \ - mlc::ERROR::A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_ >, \ + mlc::ERROR::A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_ > \ + { \ + typedef NAMESPACE::default_case_<context, data> case_t; \ + typedef typename protected_in_<case_t>::the protected_case_t; \ \ - private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \ + typedef typename mlc::if_< mlc::is_found_<protected_case_t>, \ + protected_case_t, \ + case_t >::ret ret; \ + }; \ + \ + \ + template <typename context, typename data> \ + struct handle_default_case_ < mlc::internal::a_switch_case, context, data > \ + \ + : private mlc::assert_< mlc::implies_< mlc::is_defined_< NAMESPACE::default_case_<context, data> >, \ mlc_is_not_a(mlc_comma_1(NAMESPACE::default_case_<context, data>), \ - mlc::undefined) >, \ - mlc::ret_found_in_< NAMESPACE::default_case_<context, data> > >, \ - mlc::ERROR::A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ + mlc::where_) >, \ + mlc::ERROR::A_default_case_STATEMENT_SHOULD_NOT_DERIVE_FROM_mlc_where_ >, \ + \ + private mlc::assert_< mlc::implies_< mlc::is_defined_< NAMESPACE::default_case_<context, data> >, \ + mlc::or_< mlc::ret_found_in_< NAMESPACE::default_case_<context, data> >, \ + typename protected_in_< NAMESPACE::default_case_<context, data> >::is_found > >, \ + mlc::ERROR::A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_EITHER_A_ret_OR_A_protected >, \ + \ + private mlc::assert_< mlc::implies_< mlc::and_< mlc::is_defined_< NAMESPACE::default_case_<context, data> >, \ + mlc::or_< mlc::ret_found_in_< NAMESPACE::default_case_<context, data> >, \ + typename protected_in_< NAMESPACE::default_case_<context, data> >::is_found > >, \ + mlc::xor_< mlc::ret_found_in_< NAMESPACE::default_case_<context, data> >, \ + typename protected_in_< NAMESPACE::default_case_<context, data> >::is_found > >, \ + mlc::ERROR::A_default_case_STATEMENT_IN_A_switch_SHOULD_NOT_HAVE_BOTH_A_ret_AND_A_protected >, \ + \ + private mlc::assert_< mlc::implies_< typename protected_in_< NAMESPACE::default_case_<context, data> >::is_found, \ + typename protected_in_< NAMESPACE::default_case_<context, data> >::is_found_with_ret >, \ + mlc::ERROR::THE_protected_PART_OF_A_default_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ + \ { \ typedef NAMESPACE::default_case_<context, data> case_t; \ typedef typename mlc::if_<mlc_is_a(case_t, mlc::undefined), \ @@ -154,14 +256,19 @@ template <typename use, typename context, typename data, unsigned i> \ struct handle_case_ <use, context, data, i, 0, 0> \ \ - : private mlc::assert_< mlc::implies_< mlc_is_not_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \ - mlc::undefined), \ + : private mlc::assert_< mlc::implies_< mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \ mlc::where_) >, \ - mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ > \ + mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >, \ + \ + private mlc::assert_< mlc::is_defined_< NAMESPACE::default_case_<context, data> >, \ + mlc::WARNING::NO_default_case_STATEMENT_HAS_BEEN_DEFINED > \ + \ { \ typedef handle_default_case_<use, context, data> handle_t; \ - typedef typename handle_t::ret ret; \ + typedef typename mlc::if_< mlc::is_defined_< NAMESPACE::default_case_<context, data> >, \ + typename handle_t::ret, \ + mlc::none >::ret ret; \ }; \ \ \ @@ -177,12 +284,31 @@ mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >, \ \ private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \ - mlc_is_not_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \ - mlc::undefined) >, \ - mlc::ret_found_in_< NAMESPACE::case_<context, data, i> > >, \ - mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ + mlc::is_defined_< NAMESPACE::case_<context, data, i> > >, \ + mlc::or_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ + mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_EITHER_A_ret_OR_A_protected >, \ + \ + private mlc::assert_< mlc::implies_< mlc::and_list_< mlc::eq_<use, mlc::internal::a_switch_case>, \ + mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ + mlc::or_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ + mlc::xor_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ + mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_NOT_HAVE_BOTH_A_ret_AND_A_protected >, \ + \ + private mlc::assert_< mlc::implies_< mlc::and_list_< mlc::eq_<use, mlc::internal::a_switch_case>, \ + mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found_with_ret >, \ + mlc::ERROR::THE_protected_PART_OF_A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ { \ - typedef NAMESPACE::case_<context, data, i> ret; \ + typedef NAMESPACE::case_<context, data, i> case_t; \ + typedef typename protected_in_<case_t>::the protected_case_t; \ + \ + typedef typename mlc::if_< mlc::is_found_<protected_case_t>, \ + protected_case_t, \ + case_t >::ret ret; \ }; \ \ \ @@ -198,10 +324,24 @@ mlc::ERROR::A_case_STATEMENT_SHOULD_DERIVE_FROM_mlc_where_ >, \ \ private mlc::assert_< mlc::implies_< mlc::and_< mlc::eq_<use, mlc::internal::a_switch_case>, \ - mlc_is_not_a(mlc_comma_2(NAMESPACE::case_<context, data, i>), \ - mlc::undefined) >, \ - mlc::ret_found_in_< NAMESPACE::case_<context, data, i> > >, \ - mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ + mlc::is_defined_< NAMESPACE::case_<context, data, i> > >, \ + mlc::or_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ + mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_EITHER_A_ret_OR_A_protected >, \ + \ + private mlc::assert_< mlc::implies_< mlc::and_list_< mlc::eq_<use, mlc::internal::a_switch_case>, \ + mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ + mlc::or_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ + mlc::xor_< mlc::ret_found_in_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found > >, \ + mlc::ERROR::A_case_STATEMENT_IN_A_switch_SHOULD_NOT_HAVE_BOTH_A_ret_AND_A_protected >, \ + \ + private mlc::assert_< mlc::implies_< mlc::and_list_< mlc::eq_<use, mlc::internal::a_switch_case>, \ + mlc::is_defined_< NAMESPACE::case_<context, data, i> >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found >, \ + typename protected_in_< NAMESPACE::case_<context, data, i> >::is_found_with_ret >, \ + mlc::ERROR::THE_protected_PART_OF_A_case_STATEMENT_IN_A_switch_SHOULD_HAVE_A_ret > \ { \ typedef mlc_is_a(mlc_comma_2(NAMESPACE::case_<context, data, i+1>), \ mlc::case_selected) next_case_is_selected; \ Index: mlc/cmp.hh --- mlc/cmp.hh (revision 446) +++ mlc/cmp.hh (working copy) @@ -33,23 +33,45 @@ # include <mlc/logic.hh> -/// Macros mlc_eq and mlc_neq. + +/// \{ +/// Macros mlc_eq(T1, T2) and mlc_neq(T1, T2). + # define mlc_eq( T1, T2) mlc::eq_ <T1, T2> # define mlc_neq(T1, T2) mlc::neq_<T1, T2> +/// \} + + + +/// \{ +/// Macros mlc_something(T) corresponding to mlc::something_<T>. + +# define mlc_is_found(T) mlc::is_found_<T> +# define mlc_is_not_found(T) mlc::is_not_found_<T> + +# define mlc_is_undefined(T) mlc::is_undefined_<T> +# define mlc_is_defined(T) mlc::is_defined_<T> + +# define mlc_is_ok(T) mlc::is_ok_<T> +# define mlc_is_not_ok(T) mlc::is_not_ok_<T> + +/// \} + + namespace mlc { /// Check whether \a T is a mlc::abstract::value. template <typename T> - struct is_value : public mlc_is_a(T, mlc::abstract::value) + struct is_value : public mlc_is_a(T, mlc::abstract::value)::bexpr { }; /// Check whether \a T is not a mlc::abstract::value. template <typename T> - struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)> + struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)>::bexpr { }; @@ -71,6 +93,8 @@ }; /// \} + + /// Inequality test between a couple of types. /// \{ template <typename T1, typename T2> @@ -95,24 +119,48 @@ /// Shortcuts for comparison with mlc::not_found. /// \{ template <typename T> - struct is_found : public neq_<T, not_found> + struct is_not_found_ : public mlc_is_a(T, mlc::not_found)::bexpr { }; template <typename T> - struct is_not_found : public neq_<T, not_found> + struct is_found_ : public mlc_is_not_a(T, mlc::not_found)::bexpr + { + }; + /// \} + + + /// Shortcuts for testing inheritance from mlc::undefined. + /// \{ + template <typename T> + struct is_undefined_ : public mlc_is_a(T, mlc::undefined)::bexpr + { + }; + + template <typename T> + struct is_defined_ : public mlc_is_not_a(T, mlc::undefined)::bexpr { }; /// \} /// Check whether a type is a sound (supposedly before using it). + /// \{ + template <typename T> + struct is_not_ok_ : public or_list_< is_not_found_<T>, + is_undefined_<T>, + mlc_is_a(T, mlc::not_ok) >::bexpr + { + }; + template <typename T> - struct is_ok : public and_< neq_<T, not_found>, - and_< neq_<T, not_ok>, - neq_<T, undefined > > > + struct is_ok_ : public and_list_< is_found_<T>, + is_defined_<T>, + mlc_is_not_a(T, mlc::not_ok) >::bexpr { }; + /// \} + } // end of namespace mlc