https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thierry Geraud <theo(a)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_
{
};