384: Clean up of core mlc classes and add some documentation.

https://svn.lrde.epita.fr/svn/oln/trunk Index: ChangeLog from Thierry Geraud <theo@lrde.epita.fr> Clean up of core mlc classes and add some documentation. A lot of cleanups. Client concrete classes in mlc are now all postfixed by '_'. For instance, we have and_, int_, and so on. * metalic: New. * metalic/mlc: New. * metalic/mlc/type.hh: New. * metalic/mlc/bool.hh: New. (abstract::boolean): New class. (bool_): New class. (value, true_type, false_type): Rename as... (value_, true_, false_): ...these. (ors, ands): Rename as... (ors_, ands_): ...these. (internal): Cosmetic change. (is_true, is_false): Remove. (true_, false_): New typedef ensure_t. * metalic/mlc/is_a.hh: New. (form): Move in the internal namespace cause names are too long for a decent client use. * metalic/mlc/value.hh: New. (value): Rename as... (value_): ...this. (mlc_internal_decl_unsigned_): New macro. (mlc_internal_decl_signed_): New macro. (uchar_, ushort_, uint_, ulong_): New classes. (schar_, short_, int_, long_): New classes. (is_value, is_not_value): New meta-functions. * metalic/mlc/flags.hh: New. (flag): New abstract class. (undefined_type, unknown_type, no_type): Rename as... (undefined, unknown, none): ...these. (not_ok): Remove cause useless. * metalic/mlc/cmp.hh: New. (eq, neq): Rename as... (eq_, neq_): ...these. (is_found, is_not_found, is_ok): Remove cause irrelevant here. (mlc_is_found, mlc_is_not_found): Likewise. * metalic/mlc/typedef.hh: New. bool.hh | 417 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- cmp.hh | 46 ++---- flags.hh | 83 +++++++++--- is_a.hh | 67 ++++------ type.hh | 61 +++++++++ value.hh | 154 +++++++++++++++++++++-- 6 files changed, 624 insertions(+), 204 deletions(-) Index: metalic/mlc/type.hh --- metalic/mlc/type.hh (revision 0) +++ metalic/mlc/type.hh (revision 0) @@ -0,0 +1,61 @@ +// Copyright (C) 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_TYPE_HH +# define METALIC_TYPE_HH + + +namespace mlc { + + namespace abstract { + + /*! \class mlc::abstract::type + ** + ** Abstract base class for about all the types defined in the mlc + ** library. Types deriving from this class are intended to be + ** used only as types, not as objects; so they cannot be + ** instantiated. + ** + ** This class is useful to check at compile-time that a parameter + ** P is an mlc type (with the "mlc_is_a" facility). + ** + ** Example: mlc::true_ is a mlc::abstract::type. + */ + + struct type + { + private: + /// Ctor is private to prevent instantiations. + type() {} + }; + + } // end of namespace mlc::abstract + +} // end of namespace mlc + + +#endif // ! METALIC_TYPE_HH Index: metalic/mlc/bool.hh --- metalic/mlc/bool.hh (revision 0) +++ metalic/mlc/bool.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory +// 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 @@ -29,166 +29,385 @@ # define METALIC_BOOL_HH # include <mlc/value.hh> -# include <mlc/types.hh> -/// Macro that retrieves a Boolean value from a static type representing a Boolean. -# define mlc_bool(Type) mlc::internal::helper_get_bool< Type >::ret +/*! \macro mlc_bool(T) +** +** Macro that retrieves a Boolean value from a Boolean expression type +** T. Its result is either true or false. +*/ +# define mlc_bool(Type) mlc::internal::get_bool<Type>::value namespace mlc { - /// Specializations of mlc::value for T = bool; when v = true, ensure() is provided. + namespace abstract { - template <> - struct value <bool, true> - { - static const bool Boolean_value = true; - static const bool val = true; - static void ensure() {} - protected: - value() {} - }; + /*! \class mlc::abstract::boolean + ** + ** Abstract base class for Booleans represented as types. This + ** class has two important sub-classes: mlc::true_ and + ** mlc::false_. + ** + ** Any mlc Boolean expression type derives from either mlc::true_ + ** or mlc::false_ so derives from mlc::abstract::boolean. + */ - template <> - struct value <bool, false> - { - static const bool Boolean_value = false; - static const bool val = false; - protected: - value() {} - }; + struct boolean : public value {}; + + } // end of mlc::abstract - /// Typedefs of true_type and false_type. - typedef value<bool, true> true_type; - typedef value<bool, false> false_type; + // fwd decl + template <bool> struct bool_; namespace internal { + /*! \class mlc::get_bool<T> + ** + ** Internal class so do not use it. This class gives access to a + ** Boolean value from a Boolean expression type; it is used in the + ** mlc_bool(T) macro. + ** + ** \see mlc_bool(T) + */ template <typename T> - struct helper_get_bool + struct get_bool { - // FIXME: static check that T dderives from either true_type or false_type... - static const bool ret = T::Boolean_value; + static const bool value = T::bool_value_; }; - } // end of namespace mlc::internal - - - /// Classes is_true<b> and is_false<b> (only provided for bkd compability). + /*! \class mlc::value_<bool, b> + ** + ** Specialization of value_<T, val> for the Boolean case. + ** + ** Design notes: 1) This specialization is defined so that mlc + ** Booleans derive from mlc::abstract::boolean. 2) This + ** specialization conforms to the interface of the generic version + ** of mlc::internal::value_. + */ - template <bool b> struct is_true {}; - template <> struct is_true <true> { static void ensure() {} }; + template <bool b> + struct value_ <bool, b> : public abstract::boolean + { + /*! \typedef type + ** + ** Gives the regular type, that is bool, corresponding to this + ** class. + */ + typedef bool type; + + /*! \member value + ** + ** Gives the regular value of the Boolean represented by this + ** class. The result is either true or false. + ** + ** This member is provided for any mlc value class such as + ** mlc::int_<51> and mlc::char_<'c'>. However, to access the + ** regular value of a type T that you know to be a mlc Boolean + ** expression, you should prefer to use the macro mlc_bool(T). + ** This macro also ensures that T really is an expression. + ** + */ + static const bool value = b; + + /*! \typedef ret + ** + ** Returns mlc::true_ or mlc::false_. + ** + ** Since Boolean expression types derive from either mlc::true_ + ** or mlc::false_, these expression types are never exactly + ** mlc::true_ nor mlc::false_. This typedef thus allows for the + ** expression evaluation. + ** + ** 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. + ** + ** \see mlc::true_ and mlc::false_ + */ + typedef bool_<b> ret; + + private: + + /*! \member bool_value_ + ** + ** This member is redundant with the member 'value'. It is used + ** by the mlc_bool(T) macro to ensure that T actually derives + ** from mlc::true_ or mlc::false_. + */ + static const bool bool_value_ = b; - template <bool b> struct is_false {}; - template <> struct is_false <false> { static void ensure() {} }; + template <typename T> friend class get_bool; + }; + } // end of namespace mlc::internal - /// Logical unary not of a Boolean type + /*! \class mlc::bool_<true> + ** + ** Specialization of mlc::bool_<b> for b set to true. This type + ** is also known as mlc::true_. Every Boolean expression types + ** derive either from this type or from mlc::false_. + ** + ** Design notes: 1) This specialization is defined so that mlc + ** Booleans derive from mlc::abstract::boolean. 2) This + ** specialization conforms to the interface of the generic version + ** of mlc::internal::value_. + ** + ** \see mlc::bool_<false> + */ - template <typename T> - struct not_ : public value<bool, !mlc_bool(T)> + template <> + struct bool_<true> : public internal::value_<bool, true> { - // FIXME: static assert here and below s.a. ~not_() { mlc_is_a(not_<T>, Boolean_value); } - }; + /*! \member ensure() + ** + ** This member is inherited in every Boolean expression types that + ** derive from mlc::true_. This member is not provided in + ** mlc::false_. + ** + ** A static check to ensure that a Boolean expression type, say + ** Expr, is verified can thus be written as an instruction: + ** "Expr::ensure();" + ** + ** When there is no room in code for an instruction, use + ** ensure_t instead. + ** + ** Design note: This member is a no-op (it has no cost at + ** run-time). + */ + static void ensure() {} - /// Logical binary operators between a couple of Boolean types + /*! \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). + ** + ** 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. + ** + ** 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. + ** + ** 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 + ** { ... }; + */ + typedef struct{} ensure_t; + }; - template <typename L, typename R> struct and_ : public value <bool, (mlc_bool(L) && mlc_bool(R)) > {}; - template <typename L, typename R> struct nand_ : public value <bool, (!(mlc_bool(L) && mlc_bool(R)))> {}; - template <typename L, typename R> struct or_ : public value <bool, (mlc_bool(L) || mlc_bool(R)) > {}; - template <typename L, typename R> struct nor_ : public value <bool, (!(mlc_bool(L) || mlc_bool(R)))> {}; - template <typename L, typename R> struct xor_ : public value <bool, (mlc_bool(L) != mlc_bool(R)) > {}; - template <typename L, typename R> struct xnor_ : public value <bool, (!(mlc_bool(L) != mlc_bool(R)))> {}; + typedef bool_<true> true_; + /*! \class mlc::bool_<false> + ** + ** Specialization of mlc::bool_<b> for b set to false. This type + ** is also known as mlc::false_. Every Boolean expression types + ** 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, + ** is evaluated to false, the static checks "Expr::ensure();" and + ** "Expr::ensure_t" do not compile. + ** + ** Design notes: 1) This specialization is defined so that mlc + ** Booleans derive from mlc::abstract::boolean. 2) This + ** specialization conforms to the interface of the generic version + ** of mlc::internal::value_. + ** + ** \see mlc::bool_<true> + */ - namespace internal + template <> + struct bool_<false> : public internal::value_<bool, false> { - // helpers for mlc::ors + }; - template <typename A1, typename A2> - struct ors2 : public or_<A1, A2> {}; + 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)))> {}; - template <> - struct ors2 <no_type, no_type> : public true_type {}; - template <typename A1> - struct ors2 <A1, no_type> : public A1 {}; + /// Internal helpers for logical operators between several Boolean types - template <typename A2> - struct ors2 <no_type, A2>; + namespace internal + { + struct none_; + // 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 ors4 : public ors2< ors2<A1, A2>, ors2<A3, A4> > {}; - + struct ors_4_ : public ors_2_< ors_2_<A1, A2>, + ors_2_<A3, A4> > {}; template <> - struct ors4 <no_type, no_type, no_type, no_type> : public true_type {}; - + 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 ors8 : public ors2< ors4<A1, A2, A3, A4>, ors4<A5, A6, A7, A8> > {}; - - // helpers for mlc::ands - - template <typename A1, typename A2> - struct ands2 : public and_<A1, A2> {}; - - template <> - struct ands2 <no_type, no_type> : public true_type {}; - - template <typename A1> - struct ands2 <A1, no_type> : public A1 {}; - - template <typename A2> - struct ands2 <no_type, A2>; - + 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 ands4 : public ands2< ands2<A1, A2>, ands2<A3, A4> > {}; - + struct ands_4_ : public ands_2_< ands_2_<A1, A2>, + ands_2_<A3, A4> > {}; template <> - struct ands4 <no_type, no_type, no_type, no_type> : public true_type {}; - + 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 ands8 : public ands2< ands4<A1, A2, A3, A4>, ands4<A5, A6, A7, A8> > {}; + struct ands_8_ : public ands_2_< ands_4_<A1, A2, A3, A4>, + ands_4_<A5, A6, A7, A8> > {}; } // end of mlc::internal - // 'ors' is a list of 'or_'. + /*! \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 = no_type, - typename A5 = no_type, - typename A6 = no_type, - typename A7 = no_type, - typename A8 = no_type> - struct ors : public internal::ors8< A1, A2, A3, A4, A5, A6, A7, A8 > - {}; + 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 > + { + }; + - // 'ands' is a list of 'and_'. + /*! \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 = no_type, - typename A5 = no_type, - typename A6 = no_type, - typename A7 = no_type, - typename A8 = no_type> - struct ands : public internal::ands8< A1, A2, A3, A4, A5, A6, A7, A8 > - {}; + 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 Index: metalic/mlc/is_a.hh --- metalic/mlc/is_a.hh (revision 0) +++ metalic/mlc/is_a.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory +// 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 @@ -28,13 +28,13 @@ #ifndef METALIC_IS_A_HH # define METALIC_IS_A_HH -# include <mlc/any.hh> # include <mlc/bool.hh> -// private macro so do _not_ use it -# define is_a__check_result_ \ -sizeof(helper<T ,U >::check( (T *) helper<T,U >::makeT() )) \ -== sizeof(mlc::internal::yes_) + + +// internal macro so do not use it +# define mlc_internal_is_a__check_result_ \ +sizeof(helper<T ,U >::check( (T *) helper<T,U >::makeT() )) == sizeof(mlc::internal::yes_) namespace mlc @@ -44,23 +44,13 @@ { // - // wrap - // - // FIXME: This type is a workaround for g++-2.95 problem with implicit - // typename in <foo<T>::ret::dim>, - // write <wrap<typename foo<T>::ret>::dim instead. - // - + // wrap is a workaround to fix g++-2.95 problem with implicit: + // instead of typename in <foo<T>::ret::dim> + // write <wrap<typename foo<T>::ret>::dim template <class T> struct wrap : public T {}; - } // internal - - /*-----. - | is_a | - `-----*/ - // FIXME: form is a namespace to avoid g++-3.2 bug with template function - // overloading in class. + /// form namespace form { @@ -93,10 +83,9 @@ static desc< template_l_template_l_class_class_g_class_g_class_ > get(); // ... - } - namespace internal - { + } // end of namespace mlc::internal::form + typedef char yes_; struct no_ { char dummy[2]; }; @@ -125,7 +114,7 @@ template<class T, class U> struct check - : public value<bool,( is_a__check_result_ )> + : public bool_<( mlc_internal_is_a__check_result_ )> { }; }; @@ -148,7 +137,7 @@ template<class T, template < class > class U> struct check - : public value<bool,( is_a__check_result_ )> + : public bool_<( mlc_internal_is_a__check_result_ )> { }; }; @@ -171,7 +160,7 @@ template<class T, template < class,class > class U> struct check - : public value<bool,( is_a__check_result_ )> + : public bool_<( mlc_internal_is_a__check_result_ )> {}; }; @@ -193,7 +182,7 @@ template<class T, template < template < class > class > class U> struct check - : public value<bool,( is_a__check_result_ )> + : public bool_<( mlc_internal_is_a__check_result_ )> {}; }; @@ -215,26 +204,24 @@ template<class T, template < template < class,class > class > class U> struct check - : public value<bool,( is_a__check_result_ )> + : public bool_<( mlc_internal_is_a__check_result_ )> {}; }; - } // end of internal -} // end of mlc + } // end of namespace mlc::internal -// private macros: do _not_ use them -# define is_a__2nd_is_meta(T,U) mlc::internal::is_a_< id_of_typeform(U) >::check<T, U > +} // end of namespace mlc -// client macros -# define id_of_typeform(T) sizeof(mlc::form::get<T >()) -template <class T> -struct id_ { typedef T ret; }; +/// Client macro mlc_is_a(T, U) + +# define mlc_is_a(T, U) \ +mlc::internal::wrap<typename mlc::internal::is_a_< sizeof(mlc::internal::form::get<U >()) >::check<T, U > > + +# define mlc_is_a_(T, U) \ +mlc::internal::wrap< mlc::internal::is_a_< sizeof(mlc::internal::form::get<U >()) >::check<T, U > > -// FIXME: can we get rid of mlc::wrap ? -# define mlc_is_a(T, U) mlc::internal::wrap<typename mlc::internal::is_a_< id_of_typeform(U) >::check<T, U > > -# define mlc_is_a_(T, U) mlc::internal::wrap<mlc::internal::is_a_< id_of_typeform(U) >::check<T, U > > -#endif // ndef METALIC_IS_A_HH +#endif // ! METALIC_IS_A_HH Index: metalic/mlc/value.hh --- metalic/mlc/value.hh (revision 0) +++ metalic/mlc/value.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2005 EPITA Research and Development Laboratory +// 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 @@ -28,23 +28,155 @@ #ifndef METALIC_VALUE_HH # define METALIC_VALUE_HH +# include <mlc/type.hh> + + + +/// Internal macros. + + +# define mlc_internal_decl_unsigned_(Type, TypeName) \ +namespace internal \ +{ \ + template <Type val> \ + struct value_ <Type, val> : public abstract::unsigned_integer \ + { \ + typedef Type type; \ + static const Type value = val; \ + }; \ +} \ +template <Type val> \ +struct TypeName : public internal::value_<Type, val> {} + + +# define mlc_internal_decl_signed_(Type, TypeName) \ +namespace internal \ +{ \ + template <Type val> \ + struct value_ <Type, val> : public abstract::signed_integer \ + { \ + typedef Type type; \ + static const Type value = val; \ + }; \ +} \ +template <Type val> \ +struct TypeName : public internal::value_<Type, val> {} + + + -/*! \namespace mlc -** \brief mlc namespace. -*/ namespace mlc { - /// Class that defines a mlc value as a type (for instance mlc::value<int,3>). - template <typename T, T v> - struct value - { - static const T val = v; - value() {} - operator T() const { return v; } + namespace abstract { + + /*! \class mlc::abstract::value + ** + ** Abstract base class for mlc types that represent values. + ** + ** For instance, the types mlc::true_ and mlc::int_<51> derive + ** from this abstraction. + */ + + struct value : public type + { + }; + + /// Abstractions for integer values as types. + + struct integer : public value {}; + struct unsigned_integer : public integer {}; + struct signed_integer : public integer {}; + + } // end of namespace mlc::abstract + + + namespace internal + { + + /*! \class mlc::internal::value_<T, val> + ** + ** Base class for values to be represented by types. This class + ** is in the internal namespace so you should not use it. Its + ** purpose is only to factor code for derived classes that are not + ** internal (for instance, mlc::true_ or mlc::int_<51>). + ** + ** Design note: this class can only be used for values that can be + ** a parameter (mlc::internal::value_<float, 3.14f> is incorrect). + ** + ** Parameter T is the type of the value. Parameter val is the + ** value itself. + ** + ** \see mlc/bool.hh + */ + + template <typename T, T val> + struct value_ : public abstract::value + { + /*! \typedef type + ** + ** Gives the regular type of the value. For instance, + ** mlc::true_::type is bool and mlc::int_<51>::type is int. + */ + typedef T type; + + /*! \member value + ** + ** Gives the regular value. For instance, + ** mlc::true_::value is true and mlc::int_<51>::value is 51. + */ + static const T value = val; + }; + + } // end of namespace mlc::internal + + + + + // Dedicated sub-classes for builtin types. + + mlc_internal_decl_unsigned_( unsigned char, uchar_ ); + mlc_internal_decl_unsigned_( unsigned short, ushort_ ); + mlc_internal_decl_unsigned_( unsigned int, uint_ ); + mlc_internal_decl_unsigned_( unsigned long, ulong_ ); + + mlc_internal_decl_signed_( signed char, schar_ ); + mlc_internal_decl_signed_( signed short, short_ ); + mlc_internal_decl_signed_( signed int, int_ ); + mlc_internal_decl_signed_( signed long, long_ ); + + + // char + + template <char c> + struct char_ : public internal::value_<char, c> + { }; + // Boolean values as types are defined elsewhere + // see: mlc/bool.hh + + +} // end of namespace mlc + + +# include <mlc/bool.hh> +# include <mlc/is_a.hh> + + +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 Index: metalic/mlc/flags.hh --- metalic/mlc/flags.hh (revision 0) +++ metalic/mlc/flags.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2005 EPITA Research and Development Laboratory +// 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 @@ -25,39 +25,78 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef METALIC_TYPES_HH -# define METALIC_TYPES_HH +#ifndef METALIC_FLAGS_HH +# define METALIC_FLAGS_HH +# include <mlc/type.hh> -/*! \namespace mlc -** \brief mlc namespace. -*/ namespace mlc { - /*! \class undefined_type + namespace abstract { + + /*! \class mlc::abstract::flag + ** + ** Abstract base class for types that are only flags. + ** + ** Example: mlc::undefined is a mlc::abstract::flag. + */ + + struct flag : public type {}; + + } // end of namespace mlc::abstract + + + /*! \class mlc::undefined + ** + ** Flag class to state that a type is undefined, that is, declared + ** but not defined. + ** + ** Sample use: you want to define a trait to get the signed version + ** of a type T. For that, you write: + ** + ** template <typename T> + ** struct signed_type_of + ** { + ** typedef mlc::undefined ret; + ** }; + ** + ** which means that the return type (ret) is not defined by default. + ** Put differently, this trait is just declared. So far, the + ** type "signed_type_of<unsigned short>::ret" is "mlc::undefined". + ** + ** Other flags are mlc::unknown, mlc::none, and mlc::not_found. + */ + struct undefined : public abstract::flag {}; + + struct unknown : public abstract::flag {}; + + struct none : public abstract::flag {}; + + + /*! \class mlc::not_found + ** + ** Flag class to state that a type is not found (for use in the + ** context of trying to retrieve a type). + ** + ** Design issue: this flag is used in some meta-code to handle the + ** case of an "absent" typedef. For instance it is used in the + ** meta-code behind mlc_typedef: + ** mlc_typedef(std::vector<int>, value_type) is int, whereas + ** mlc_typedef(std::vector<int>, walue_type) is mlc::not_found. + ** + ** Other flags are mlc::undefined, mlc::unknown, and mlc::none. ** - ** Type by default. If the programmer forgets to define a type, - ** actually this type should however exists and should be set to - ** undefined_type. + ** \see mlc_typedef */ - class undefined_type { private: undefined_type(); }; + struct not_found : public abstract::flag {}; - // FIXME: document. - class unknown_type { private: unknown_type(); }; - class no_type { private: no_type(); }; - class default_type { private: default_type(); }; - - namespace internal - { - class not_found { private: not_found(); }; - class not_ok { private: not_ok(); }; - } // end of namespace mlc::internal + // FIXME: add corresponding is_* types } // end of namespace mlc -#endif // ! METALIC_TYPES_HH +#endif // ! METALIC_FLAGS_HH Index: metalic/mlc/cmp.hh --- metalic/mlc/cmp.hh (revision 0) +++ metalic/mlc/cmp.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory +// 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 @@ -29,62 +29,44 @@ # define METALIC_CMP_HH # include <mlc/bool.hh> -# include <mlc/types.hh> +# include <mlc/is_a.hh> /// Macros mlc_eq and mlc_neq. -# define mlc_eq(T1, T2) mlc::eq<T1, T2> -# define mlc_neq(T1, T2) mlc::neq<T1, T2> - -# define mlc_is_found(T) mlc::is_found<(T)> -# define mlc_is_not_found(T) mlc::is_not_found<(T)> +# define mlc_eq( T1, T2) mlc::eq_ <T1, T2> +# define mlc_neq(T1, T2) mlc::neq_<T1, T2> namespace mlc { + /// Equality test between a couple of types. template <typename T1, typename T2> - struct eq : public value<bool, false> + struct eq_ : private and_< is_not_value<T1>, is_not_value<T2> >::ensure_type, + public false_ { }; template <typename T> - struct eq <T, T> : public value<bool, true> + struct eq_ <T, T> : private is_not_value<T>::ensure_type, + public true_ { }; + /// Inequality test between a couple of types. template <typename T1, typename T2> - struct neq : public value<bool, true> - { - }; - - template <typename T> - struct neq <T, T> : public value<bool, false> - { - }; - - /// Tests is_found and is_not_found (sugar) upon a type. - - template <typename T> - struct is_found : public neq <T, internal::not_found> + struct neq_ : private and_< is_not_value<T1>, is_not_value<T2> >::ensure_type, + public true_ { }; template <typename T> - struct is_not_found : public eq <T, internal::not_found> - { - }; - - - - template <typename T> - struct is_ok : public and_< and_< neq<T, internal::not_found>, - neq<T, internal::not_ok> >, - neq<T, undefined_type> > + struct neq_ <T, T> : private is_not_value<T>::ensure_type, + public false_ { };
participants (1)
-
Thierry Geraud