389: Modify slightly the ensure_ and ensure_list_ tools.
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Modify slightly the ensure_ and ensure_list_ tools. * mlc/wrap.hh (wrap): Rename into... (wrap_): ...this. * mlc/bool.hh (ensure_item): Rename into... (ensure_item_): ...this and add a parameter to ease disambiguation. (ensure_list_): Update. (documentation): Update. * mlc/cmp.hh: Update. bool.hh | 82 ++++++++++++++++++++++++++++++++-------------------------------- cmp.hh | 4 +-- wrap.hh | 8 +++--- 3 files changed, 48 insertions(+), 46 deletions(-) Index: mlc/wrap.hh --- mlc/wrap.hh (revision 388) +++ mlc/wrap.hh (working copy) @@ -31,7 +31,7 @@ namespace mlc { - /*! \class mlc::wrap<T> + /*! \class mlc::wrap_<T> ** ** This class is a workaround to the problem of implicit typename ** that appears when writting something like: @@ -41,7 +41,7 @@ ** typedef typename outer_struct::inner_struct temp; ** temp::value ** you can write directly: - ** wrap< typename outer_struct::inner_struct >::value + ** wrap_< typename outer_struct::inner_struct >::value ** ** This class is used by the mlc_is_a macro. ** @@ -50,7 +50,7 @@ */ template <class T> - struct wrap : public T + struct wrap_ : public T { typedef T unwrap; }; @@ -67,7 +67,7 @@ #include <iostream> #include <mlc/bool.hh> -template <class T> struct wrap : public T {}; +template <class T> struct wrap_ : public T {}; namespace my { Index: mlc/bool.hh --- mlc/bool.hh (revision 388) +++ mlc/bool.hh (working copy) @@ -149,7 +149,7 @@ }; - /*! \class mlc::internal::ensure_item<i, expr> + /*! \class mlc::internal::ensure_item_<i, expr, check> ** ** Internal so do not use it. This class is for use in the ** definition of mlc::ensure_<..>. @@ -160,8 +160,8 @@ ** \see mlc::ensure_<..> */ - template <unsigned i, typename expr> - struct ensure_item + template <unsigned i, typename expr, typename check> + struct ensure_item_ { }; @@ -175,7 +175,7 @@ ** 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. + ** appearing in an ensure_item_. ** ** \see mlc::ensure_<..> */ @@ -201,31 +201,43 @@ ** Boolean expression type. An equivalent version for a variadic ** list of parameters is ensure_list_<expr1,..> ** - ** Sample uses: + ** Sample use: ** ** template <class T> - ** struct dummy : private ensure_< neq_<T, int> > + ** struct foo : private virtual ensure_< neq_<T, int> > ** { ... ** }; ** means that T can be any type but int. ** + ** + ** Please avoid the following code: ** template <class T1, class T2> - ** struct dummy2 : private ensure_< neq_<T1, int> >, - ** private ensure_< neq_<T2, float> > + ** struct bar : private virtual ensure_< neq_<T1, int> >, + ** private virtual ensure_< neq_<T2, int> > ** { ... ** }; - ** means that T1 should not be int and that T2 should not be float. - ** This last example is equivalent to: + ** a better replacement is: ** template <class T1, class T2> - ** struct dummy2 : private ensure_list_< neq_<T1, int>, - ** neq_<T2, float> > + ** struct bar : private virtual ensure_list_< 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 + ** 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 - ** the expression is true. + ** This class relies on mlc::internal::ensure_item_ to check that + ** the expression is true. 3) When several contrains such as + ** "private ensure_<..>" 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_<..>". ** ** \see ensure_list_<expr1,..> ** @@ -233,7 +245,7 @@ template <typename expr> struct ensure_ : - private internal::ensure_item<0, typename expr::internal_ensure_> + private virtual internal::ensure_item_<0, expr, typename expr::internal_ensure_> { }; @@ -252,30 +264,20 @@ ** parameter has to be a Boolean expression type. To check only a ** single expression, the appropriate tool is ensure_<expr>. ** - ** Sample uses: ** - ** template <class T> - ** struct dummy : private ensure_< neq_<T, int> > - ** { ... - ** }; - ** means that T can be any type but int. + ** Sample use: ** ** template <class T1, class T2> - ** struct dummy2 : private ensure_< neq_<T1, int> >, - ** private ensure_< neq_<T2, int> > - ** { ... - ** }; - ** is equivalent to: - ** template <class T1, class T2> - ** struct dummy2 : private ensure_list< neq_<T1, int>, + ** struct foo : private virtual ensure_list_< 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 - ** each expression is true. + ** This class relies on mlc::internal::ensure_item_ to check that + ** each expression is true. 3) using "virtual" allow to encompass + ** the multiple base class problem. ** ** \see ensure_<expr> */ @@ -290,15 +292,15 @@ typename expr_8 = internal::none_, typename expr_9 = internal::none_> struct ensure_list_ : - private internal::ensure_item<1, typename expr_1::internal_ensure_>, - private internal::ensure_item<2, typename expr_2::internal_ensure_>, - private internal::ensure_item<3, typename expr_3::internal_ensure_>, - private internal::ensure_item<4, typename expr_4::internal_ensure_>, - private internal::ensure_item<5, typename expr_5::internal_ensure_>, - private internal::ensure_item<6, typename expr_6::internal_ensure_>, - private internal::ensure_item<7, typename expr_7::internal_ensure_>, - private internal::ensure_item<8, typename expr_8::internal_ensure_>, - private internal::ensure_item<9, typename expr_9::internal_ensure_> + 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_> { }; @@ -352,7 +354,7 @@ ** (and thus no significant value). A static check via ** "mlc::ensure_<..>" uses this typedef. ** - ** \see mlc::internal::ensure_item<i, expr> + ** \see mlc::internal::ensure_item_<i, expr> */ typedef internal::none_ internal_ensure_; Index: mlc/cmp.hh --- mlc/cmp.hh (revision 388) +++ mlc/cmp.hh (working copy) @@ -56,7 +56,7 @@ /// Equality test between a couple of types. template <typename T1, typename T2> - struct eq_ : private ensure_< is_not_value<T1>, + struct eq_ : private ensure_list_< is_not_value<T1>, is_not_value<T2> >, public false_ { @@ -72,7 +72,7 @@ /// Inequality test between a couple of types. template <typename T1, typename T2> - struct neq_ : private ensure_< is_not_value<T1>, + struct neq_ : private ensure_list_< is_not_value<T1>, is_not_value<T2> >, public true_ {
participants (1)
-
Thierry Geraud