Index: ChangeLog
from Simon Odou <simon(a)lrde.epita.fr>
* mlc/is_a.hh: New. Test inheritance between two classes.
* tests/main/tests/is_a1: New. Add test for `is_a'.
* tests/main: New. Add new test suite `main'.
* tests/main/tests: New.
* tests/main/Makefile.am: New.
mlc/is_a.hh | 193 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/main/Makefile.am | 3
tests/main/tests/is_a1 | 33 ++++++++
3 files changed, 229 insertions(+)
Index: tests/main/tests/is_a1
--- tests/main/tests/is_a1 (revision 0)
+++ tests/main/tests/is_a1 (revision 0)
@@ -0,0 +1,33 @@
+#include <mlc/bool.hh>
+#include <mlc/is_a.hh>
+
+using namespace mlc;
+
+class A {};
+class B : public A {};
+class C : public B {};
+
+template <class E> class T_A {};
+template <class T> class T_B : public T_A<T> {};
+
+template <class T>
+void foo()
+{
+ is_false<mlc_is_a(int, bool)::ret>::ensure();
+ is_true<mlc_is_a(B, A)::ret>::ensure();
+ is_true<mlc_is_a(C, A)::ret>::ensure();
+ is_false<mlc_is_a(A, B)::ret>::ensure();
+}
+
+int main()
+{
+ is_false<mlc_is_a_(int, bool)::ret>::ensure();
+ is_true<mlc_is_a_(B, A)::ret>::ensure();
+ is_true<mlc_is_a_(C, A)::ret>::ensure();
+ is_false<mlc_is_a_(A, B)::ret>::ensure();
+
+ is_true<mlc_is_a_(T_B<int>, T_A)::ret>::ensure();
+ is_false<mlc_is_a_(T_A<int>, T_B)::ret>::ensure();
+
+ foo<int>();
+}
Index: tests/main/Makefile.am
--- tests/main/Makefile.am (revision 0)
+++ tests/main/Makefile.am (revision 0)
@@ -0,0 +1,3 @@
+## Process this file with Automake to produce Makefile.in -*- Makefile -*-
+
+include ../check/Makefile.runtests
Index: mlc/is_a.hh
--- mlc/is_a.hh (revision 0)
+++ mlc/is_a.hh (revision 0)
@@ -0,0 +1,193 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 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_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_)
+
+
+namespace mlc
+{
+
+ namespace internal
+ {
+
+ //
+ // 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.
+ //
+
+ 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.
+
+ namespace form
+ {
+ enum {
+ class_ = 1,
+ template_l_class_g_class_ = 2,
+ template_l_class_class_g_class_ = 3
+ // template_l_unsigned_class_g_class_ = 4
+ // ...
+ };
+
+ template<unsigned id>
+ struct desc
+ { char dummy[id]; };
+
+ template<class T>
+ static desc< class_ > get();
+
+ template<template<class> class T>
+ static desc< template_l_class_g_class_ > get();
+
+ template<template<class,class> class T>
+ static desc< template_l_class_class_g_class_ > get();
+
+ // template<template<unsigned,class> class T>
+ // static desc < template_l_unsigned_class_g_class_ > get();
+
+ // ...
+ }
+
+ namespace internal
+ {
+
+ typedef char yes_;
+ struct no_ { char dummy[2]; };
+
+
+ // dev note : below, is_a_<T,id> is a better factorization
+ // but g++ 2.95.4 has some trouble with it
+
+ template<unsigned id>
+ struct is_a_;
+
+ // _class_
+
+
+ template<>
+ struct is_a_< form::class_ >
+ {
+ typedef is_a_< form::class_ > self;
+
+ template<class T, class U>
+ struct helper
+ {
+ static yes_ check(U*);
+ static no_ check(...);
+ static T* makeT();
+ };
+
+ template<class T, class U>
+ struct check
+ : public mlc::returns_bool_<( is_a__check_result_ )>
+ {
+ };
+ };
+
+ // template_l_class_g_class_
+
+ template<>
+ struct is_a_< form::template_l_class_g_class_ >
+ {
+ typedef is_a_< form::template_l_class_g_class_ > self;
+
+ template<class T, template<class> class U>
+ struct helper
+ {
+ template<class V>
+ static yes_ check(U<V>*);
+ static no_ check(...);
+ static T* makeT();
+ };
+
+ template<class T, template<class> class U>
+ struct check
+ : public mlc::returns_bool_<( is_a__check_result_ )>
+ {
+ };
+ };
+
+ // templatee_l_class_class_g_class_
+
+ template<>
+ struct is_a_< form::template_l_class_class_g_class_ >
+ {
+ typedef is_a_< form::template_l_class_class_g_class_ > self;
+
+ template<class T, template<class,class> class U>
+ struct helper
+ {
+ template<class V, class W>
+ static yes_ check(U<V,W>*);
+ static no_ check(...);
+ static T* makeT();
+ };
+
+ template<class T, template<class,class> class U>
+ struct check
+ : public mlc::returns_bool_<( is_a__check_result_ )>
+ {};
+ };
+
+ } // end of internal
+
+} // end of mlc
+
+// 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 >
+
+// client macros
+
+# define id_of_typeform(T) sizeof(mlc::form::get<T >())
+
+template <class T>
+struct id_ { typedef T ret; };
+
+// 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
Index: ChangeLog
from simon odou <simon(a)lrde.epita.fr>
* oln/core/entry.hh: New.
Just a basic and temporary property heredity system.
* oln/core/abstract/images.hh: Likewise.
* oln/core/abstract/image_with_data.hh: Likewiwe.
* oln/core/abstract/image_identity.hh: Likewiwe.
* oln/core/1d/image1d.hh: Likewiwe.
* oln/core/2d/image2d.hh: Likewiwe.
* oln/core/3d/image3d.hh: Likewiwe.
* tests/core/tests/readonly_image: Likewiwe.
* tests/core/tests/readwrite_image: Likewiwe.
* oln/core/tags.hh: Remove.
Old heredity system.
* oln/makefile.src: Remove tags.hh, add entry.hh.
oln/core/1d/image1d.hh | 8 -
oln/core/2d/image2d.hh | 8 -
oln/core/3d/image3d.hh | 8 -
oln/core/abstract/image_identity.hh | 2
oln/core/abstract/image_with_data.hh | 2
oln/core/abstract/images.hh | 2
oln/core/entry.hh | 64 +++++++++++++++
oln/core/tags.hh | 144 -----------------------------------
oln/makefile.src | 2
tests/core/tests/readonly_image | 4
tests/core/tests/readwrite_image | 5 -
11 files changed, 85 insertions(+), 164 deletions(-)
Index: tests/core/tests/readonly_image
--- tests/core/tests/readonly_image (revision 41)
+++ tests/core/tests/readonly_image (working copy)
@@ -24,8 +24,8 @@
typedef mlc_encoding_type_(value_type) value_storage_type;
typedef array2d<value_storage_type> value_container_type;
- typedef tag::readonly constness_tag;
- typedef tag::dimension2 dimension_tag;
+ typedef prop_of<abstract::readonly_image> image_constness;
+ typedef prop_of<abstract::image2d> image_dimension;
typedef mlc::no_type delegated_type;
};
Index: tests/core/tests/readwrite_image
--- tests/core/tests/readwrite_image (revision 41)
+++ tests/core/tests/readwrite_image (working copy)
@@ -17,6 +17,9 @@
struct props <cat::image, dummy_image> :
public default_props < cat::image >
{
+ typedef prop_of<abstract::readwrite_image> image_constness;
+ typedef prop_of<abstract::image2d> image_dimension;
+
typedef size2d size_type;
typedef point2d point_type;
typedef ntg::int_u8 value_type;
@@ -24,8 +27,6 @@
typedef mlc_encoding_type_(value_type) value_storage_type;
typedef array2d<value_storage_type> value_container_type;
- typedef tag::readwrite constness_tag;
- typedef tag::dimension2 dimension_tag;
typedef mlc::no_type delegated_type;
};
Index: oln/makefile.src
--- oln/makefile.src (revision 41)
+++ oln/makefile.src (working copy)
@@ -38,7 +38,7 @@
core/coord.hh \
core/macros.hh \
core/props.hh \
- core/tags.hh \
+ core/entry.hh \
core/value_box.hh \
fancy/iota.hh \
fancy/print.hh \
Index: oln/core/entry.hh
--- oln/core/entry.hh (revision 0)
+++ oln/core/entry.hh (revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2005 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 OLENA_CORE_ENTRY_HH
+# define OLENA_CORE_ENTRY_HH
+
+# include <oln/core/abstract/image_constness.hh>
+# include <oln/core/abstract/image_dimension.hh>
+
+
+namespace oln {
+
+ template <template <typename> class Base>
+ struct prop_of
+ {
+ template <typename E>
+ struct inherits
+ {
+ typedef Base<E> ret;
+ };
+ };
+
+ namespace abstract {
+
+ template <typename E>
+ struct image_entry :
+ public props < cat::image, E >::image_constness::inherits<E>::ret,
+ public props < cat::image, E >::image_dimension::inherits<E>::ret
+ // ...
+ {
+ protected:
+ image_entry() {}
+ };
+
+ }
+
+} // end of namespace oln
+
+
+#endif // ! OLENA_CORE_ENTRY_HH
Index: oln/core/abstract/images.hh
--- oln/core/abstract/images.hh (revision 41)
+++ oln/core/abstract/images.hh (working copy)
@@ -36,7 +36,7 @@
# include <oln/core/abstract/image_constness.hh>
-# include <oln/core/tags.hh>
+# include <oln/core/entry.hh>
#endif // ! OLENA_CORE_ABSTRACT_IMAGES_HH
Index: oln/core/abstract/image_with_data.hh
--- oln/core/abstract/image_with_data.hh (revision 41)
+++ oln/core/abstract/image_with_data.hh (working copy)
@@ -31,7 +31,7 @@
# include <mlc/tracked_ptr.hh>
-# include <oln/core/tags.hh>
+# include <oln/core/entry.hh>
# include <oln/core/macros.hh>
/*! \namespace oln
Index: oln/core/abstract/image_identity.hh
--- oln/core/abstract/image_identity.hh (revision 41)
+++ oln/core/abstract/image_identity.hh (working copy)
@@ -30,7 +30,7 @@
# include <mlc/box.hh>
-# include <oln/core/tags.hh>
+# include <oln/core/entry.hh>
namespace oln {
Index: oln/core/1d/image1d.hh
--- oln/core/1d/image1d.hh (revision 41)
+++ oln/core/1d/image1d.hh (working copy)
@@ -57,6 +57,10 @@
template <typename T>
struct props < cat::image, image1d<T> > : public default_props < cat::image >
{
+ // intrusive properties
+ typedef prop_of<abstract::readwrite_image> image_constness;
+ typedef prop_of<abstract::image1d> image_dimension;
+
typedef mlc::no_type delegated_type;
typedef size1d size_type;
@@ -72,10 +76,6 @@
// FIXME: find a better name...
typedef array1d<value_storage_type> value_container_type;
- // tags
- typedef tag::readwrite constness_tag;
- typedef tag::dimension1 dimension_tag;
-
// functions
template <typename U>
Index: oln/core/2d/image2d.hh
--- oln/core/2d/image2d.hh (revision 41)
+++ oln/core/2d/image2d.hh (working copy)
@@ -61,6 +61,10 @@
template <typename T>
struct props < cat::image, image2d<T> > : public default_props < cat::image >
{
+ // intrusive properties
+ typedef prop_of<abstract::readwrite_image> image_constness;
+ typedef prop_of<abstract::image2d> image_dimension;
+
typedef mlc::no_type delegated_type;
typedef size2d size_type;
@@ -79,10 +83,6 @@
// FIXME: find a better name...
typedef array2d<value_storage_type> value_container_type;
- // tags
- typedef tag::readwrite constness_tag;
- typedef tag::dimension2 dimension_tag;
-
// functions
template <typename U>
Index: oln/core/3d/image3d.hh
--- oln/core/3d/image3d.hh (revision 41)
+++ oln/core/3d/image3d.hh (working copy)
@@ -58,6 +58,10 @@
template <typename T>
struct props < cat::image, image3d<T> > : public default_props < cat::image >
{
+ // intrusive properties
+ typedef prop_of<abstract::readwrite_image> image_constness;
+ typedef prop_of<abstract::image3d> image_dimension;
+
typedef mlc::no_type delegated_type;
typedef size3d size_type;
@@ -73,10 +77,6 @@
// FIXME: find a better name...
typedef array3d<value_storage_type> value_container_type;
- // tags
- typedef tag::readwrite constness_tag;
- typedef tag::dimension3 dimension_tag;
-
// functions
template <typename U>
Index: oln/core/tags.hh
--- oln/core/tags.hh (revision 41)
+++ oln/core/tags.hh (working copy)
@@ -1,144 +0,0 @@
-// Copyright (C) 2005 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 OLENA_CORE_TAGS_HH
-# define OLENA_CORE_TAGS_HH
-
-# include <oln/core/abstract/image_constness.hh>
-# include <oln/core/abstract/image_dimension.hh>
-
-#define oln_tag_decl(TAG) \
- \
-struct TAG \
-{ \
-protected: \
- TAG() {} \
-}
-
-
-#define oln_tag_decl_case(MTAG, TAG, MCLASS) \
- \
-struct TAG : public MTAG \
-{ \
-protected: \
- TAG() {} \
-}; \
- \
-namespace internal { \
- \
- template <typename E> \
- struct image_case < TAG, E > : public MCLASS <E> \
- { \
- protected: \
- image_case() {} \
- }; \
-}
-
-
-#define oln_tag_decl_retrieve_from_props(TAG) \
- \
-template <typename E> \
-struct retrieve < tag::TAG, E > \
-{ \
- typedef typename props<cat::image,E>::TAG##_tag ret; /* FIXME: ok? */ \
- /* static test if ret derives from tag::TAG */ \
-}
-
-
-
-namespace oln {
-
-
- namespace tag {
-
-
- namespace internal {
-
- template <typename TAG, typename E> struct image_case;
- template <typename TAG, typename E> struct retrieve;
-
- } // end of namespace tag::internal
-
-
- oln_tag_decl ( constness );
- oln_tag_decl_case( constness, readonly, abstract::readonly_image )
- oln_tag_decl_case( constness, readwrite, abstract::readwrite_image )
-
- oln_tag_decl ( dimension );
- oln_tag_decl_case( dimension, dimension1, abstract::image1d)
- oln_tag_decl_case( dimension, dimension2, abstract::image2d)
- oln_tag_decl_case( dimension, dimension3, abstract::image3d)
-
- namespace internal {
-
- template <typename E>
- struct retrieve < tag::constness, E >
- {
- typedef typename props<cat::image,E>::constness_tag ret; // FIXME: ok?
- // test if ret derives from constness_tag
- };
-
- template <typename E>
- struct retrieve < tag::dimension, E >
- {
- typedef typename props<cat::image,E>::dimension_tag ret; // FIXME: ok?
- // test if ret derives from constness_tag
- };
-
-
- template <typename TAG, typename E>
- struct image_switch :
- public image_case< typename retrieve<TAG,E>::ret, E>
- {
- protected:
- image_switch() {}
- };
-
-
- } // end of namespace tag::internal
-
- } // end of namespace tag
-
-
- namespace abstract {
-
- template <typename E>
- struct image_entry :
- public tag::internal::image_switch < tag::constness, E >,
- public tag::internal::image_switch < tag::dimension, E >
- // ...
- {
- protected:
- image_entry() {}
- };
-
- }
-
-} // end of namespace oln
-
-
-#endif // ! OLENA_CORE_TAGS_HH