386: Add mlc::ensure_ and update.

26 Jan
2006
26 Jan
'06
3:29 p.m.
https://svn.lrde.epita.fr/svn/oln/trunk/metalic Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Add mlc::ensure_ and update. . * mlc/bool.hh: Update documentation. (internal::value_<bool,b>::ret): Rename as... (internal::value_<bool,b>::eval): ...this. (bool_<true>::ensure_t): Rename as... (bool_<true>::internal_ensure_): ...this. (internal::ensure_item<i,expr>): New class. (internal::none_): Relocate. (internal::none_::internal_ensure_): New typedef. (ensure_): New class. * mlc/value.hh (is_value, is_not_value): Move to... * mlc/cmp.hh (is_value, is_not_value): ...here. (eq_, neq_): Update static checks. bool.hh | 170 +++++++++++++++++++++++++++++++++++++++++++++------------------ cmp.hh | 22 ++++++-- value.hh | 25 +++++---- 3 files changed, 156 insertions(+), 61 deletions(-) Index: mlc/bool.hh --- mlc/bool.hh (revision 385) +++ mlc/bool.hh (working copy) @@ -115,7 +115,7 @@ */ static const bool value = b; - /*! \typedef ret + /*! \typedef eval ** ** Returns mlc::true_ or mlc::false_. ** @@ -127,11 +127,13 @@ ** Please note that, however, we usually do not need expression ** evaluation. The most common use of a Boolean expression is ** to check that it is verified (true) and, for that, we provide - ** ::ensure() and ::ensure_t. + ** "expr::ensure();" and "ensure_<expr..>". For instance: + ** or_<mlc_is_a(T, int), mlc_is_a(T, unsigned)>::ensure(); + ** ensures that T is int or unsigned without using ::eval. ** - ** \see mlc::true_ and mlc::false_ + ** \see mlc::true_, mlc::false_, mlc::ensure_<expr..>. */ - typedef bool_<b> ret; + typedef bool_<b> eval; private: @@ -146,9 +148,112 @@ template <typename T> friend class get_bool; }; + + /*! \class mlc::internal::ensure_item<i, expr> + ** + ** Internal so do not use it. This class is for use in the + ** definition of mlc::ensure_<..>. + ** + ** Design note: this class does not derive from abstract::type + ** because it is used in inheritance so a ctor should exist. + ** + ** \see mlc::ensure_<..> + */ + + template <unsigned i, typename expr> + struct ensure_item + { + }; + + + /*! \class mlc::internal::none_ + ** + ** Internal so do not use it. This class is for use in the + ** definition of mlc::ensure_<..>. + ** + ** 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 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. + ** + ** \see mlc::ensure_<..> + */ + + struct none_ + { + typedef none_ internal_ensure_; // provided such as in classes inheriting from true_ + }; + + } // end of namespace mlc::internal + + /*! \class mlc::ensure_<expr1..> + ** + ** This class is a replacement for a sequence of instructions: + ** "expr1::ensure(); .." when there is no room for having + ** instructions. The typical use is to express a constraint (or + ** several constraints) upon a parameter (or several parameters) + ** of a templated class. + ** + ** ensure_<..> has a variadic list of parameters. It expects at + ** least one parameter and handles up to 9 parameters. Each parameter + ** has to be a Boolean expression type. + ** + ** Sample uses: + ** + ** template <class T> + ** struct dummy : private ensure_< neq_<T, int> > + ** { ... + ** }; + ** means that T can be any type but int. + ** + ** 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_< 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. + ** + */ + + template <typename expr_1, + typename expr_2 = internal::none_, + 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_> + struct ensure_ : + 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_> + { + }; + + + + /*! \class mlc::bool_<true> ** ** Specialization of mlc::bool_<b> for b set to true. This type @@ -177,55 +282,29 @@ ** "Expr::ensure();" ** ** When there is no room in code for an instruction, use - ** ensure_t instead. + ** mlc::ensure_<expr1..> instead. ** ** Design note: This member is a no-op (it has no cost at ** run-time). + ** + ** \see: mlc::ensure<expr1..> */ static void ensure() {} - /*! \typedef ensure_t - ** - ** This typedef is inherited in every Boolean expression types that - ** derive from mlc::true_. This typedef is not provided in - ** mlc::false_. The type returned by this typedef has no meaning - ** (and thus no significant value). + /*! \typedef internal_ensure_ ** - ** A static check to ensure that a Boolean expression type, say - ** Expr, is verified can thus be written through the typedef - ** access: "Expr::ensure_t". This is a replacement for the - ** instruction "Expr::ensure();" when there is no room in code for - ** an instruction. + ** This is internal stuff so do not use it. ** - ** Sample use: - ** template <class T> - ** struct foo - ** : private mlc_is_a(T, base)::ensure_t - ** { - ** //... - ** }; - ** meaning that foo's parameter is constrainted to be a sub-class - ** of base. + ** This typedef is inherited in every Boolean expression types + ** that derive from mlc::true_. This typedef is not provided in + ** mlc::false_. The type returned by this typedef has no meaning + ** (and thus no significant value). A static check via + ** "mlc::ensure_<..>" uses this typedef. ** - ** Limitation: when using ensure_t to express several - ** constraints through private inheritance, such as in the sample - ** use above, one should express the set of constraints by a - ** single expression. The following code is not ok: - ** template <class T1, class T2> - ** struct foo - ** : private mlc_is_a(T1, base)::ensure_t, - ** private mlc_is_a(T2, base)::ensure_t - ** { ... }; - ** the problem being that we mulitply inherit from the same - ** class. The correct code should be written with a single - ** Boolean; practically the following code is ok: - ** template <class T1, class T2> - ** struct foo - ** : private mlc::and_<mlc_is_a(T1, base), - ** mlc_is_a(T2, base)>::ensure_t - ** { ... }; + ** \see mlc::internal::ensure_item<i, expr> */ - typedef struct{} ensure_t; + typedef internal::none_ internal_ensure_; + }; typedef bool_<true> true_; @@ -238,9 +317,9 @@ ** derive either from this type or from mlc::true_. ** ** Conversely to mlc::true_, this class does not feature ensure() - ** nor ensure_t. So, when a Boolean expression type, say Expr, + ** nor ensure_. So, when a Boolean expression type, say Expr, ** is evaluated to false, the static checks "Expr::ensure();" and - ** "Expr::ensure_t" do not compile. + ** "Expr::ensure_" do not compile. ** ** Design notes: 1) This specialization is defined so that mlc ** Booleans derive from mlc::abstract::boolean. 2) This @@ -321,7 +400,6 @@ namespace internal { - struct none_; // ors_2_ template <typename A1, typename A2> struct ors_2_ : public or_<A1, A2> {}; Index: mlc/value.hh --- mlc/value.hh (revision 385) +++ mlc/value.hh (working copy) @@ -162,22 +162,25 @@ # include <mlc/bool.hh> -# include <mlc/is_a.hh> -namespace mlc { +// FIXME: the following code causes inclusion recursion... - template <typename T> - struct is_value : public mlc_is_a(T, mlc::abstract::value) - { - }; +// # include <mlc/is_a.hh> - template <typename T> - struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)> - { - }; +// namespace mlc { -} // end of namespace mlc +// template <typename T> +// struct is_value : public mlc_is_a(T, mlc::abstract::value) +// { +// }; + +// template <typename T> +// struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)> +// { +// }; + +// } // end of namespace mlc #endif // ! METALIC_VALUE_HH Index: mlc/cmp.hh --- mlc/cmp.hh (revision 385) +++ mlc/cmp.hh (working copy) @@ -39,18 +39,31 @@ namespace mlc { + // FIXME: code moved from the end of value.hh + + template <typename T> + struct is_value : public mlc_is_a(T, mlc::abstract::value) + { + }; + + template <typename T> + struct is_not_value : public not_<mlc_is_a(T, mlc::abstract::value)> + { + }; + /// Equality test between a couple of types. template <typename T1, typename T2> - struct eq_ : private and_< is_not_value<T1>, is_not_value<T2> >::ensure_type, + struct eq_ : private ensure_< is_not_value<T1>, + is_not_value<T2> >, public false_ { }; template <typename T> - struct eq_ <T, T> : private is_not_value<T>::ensure_type, + struct eq_ <T, T> : private ensure_< is_not_value<T> >, public true_ { }; @@ -59,13 +72,14 @@ /// Inequality test between a couple of types. template <typename T1, typename T2> - struct neq_ : private and_< is_not_value<T1>, is_not_value<T2> >::ensure_type, + struct neq_ : private ensure_< is_not_value<T1>, + is_not_value<T2> >, public true_ { }; template <typename T> - struct neq_ <T, T> : private is_not_value<T>::ensure_type, + struct neq_ <T, T> : private ensure_< is_not_value<T> >, public false_ { };
7173
Age (days ago)
7173
Last active (days ago)
0 comments
1 participants
participants (1)
-
Thierry GERAUD