https://svn.lrde.epita.fr/svn/oln/trunk/static
This version of mini-oln needs g++ from ConceptGCC. You can find it there:
/lrde/dev/linux-x86/unstable/conceptgcc-4.1.1-alpha-5/bin/conceptg++
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a first C++0x concept-based version of mini-oln.
* samples/mini-oln/concept-c++/mini-oln.cc: New.
mini-oln.cc | 95 +++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 75 insertions(+), 20 deletions(-)
Index: samples/mini-oln/concept-c++/mini-oln.cc
--- samples/mini-oln/concept-c++/mini-oln.cc (revision 0)
+++ samples/mini-oln/concept-c++/mini-oln.cc (working copy)
@@ -26,14 +26,16 @@
// Public License.
/* \file samples/mini-oln/mini-oln.cc
- \brief A proof of concept of Static using a mini-version of Olena.
+ \brief A proof of concept of Static using a mini-version of Olena, using
+ concepts from C++0x.
Compile with:
- g++ -I../../../{metalic,static,extended,olena} mini-oln.cc
+ conceptg++ -I../../../../{metalic,static,extended,olena} mini-oln.cc
*/
#include <vector>
+#include <iostream>
#include <mlc/case.hh>
#include <stc/any.hh>
@@ -53,6 +55,44 @@
+/*-----------.
+| Concepts. |
+`-----------*/
+
+namespace concepts
+{
+ concept Point2d<typename P> {};
+ concept Point3d<typename P> {};
+
+ auto concept Image<typename I>
+ {
+ typename point_t;
+ typename iter_t;
+ typename value_t;
+
+ // ConceptGCC doesn't support operator signatures yet.
+#if 0
+ value_t& I::operator ()(point_t&);
+#endif
+ bool I::has(const point_t&) const;
+ };
+
+ auto concept Image2d<typename I> : Image<I>
+ {
+ int I::nrows_get() const;
+ int I::ncols_get() const;
+ };
+
+ auto concept Image3d<typename I> : Image<I>
+ {
+ int I::nrows_get() const;
+ int I::ncols_get() const;
+ int I::nslis_get() const;
+ };
+}
+
+
+
/*-------------.
| Mini-Olena. |
`-------------*/
@@ -82,6 +122,12 @@
};
}
+namespace concepts
+{
+ concept_map Point2d<oln::point2d> {};
+ concept_map Point3d<oln::point3d> {};
+}
+
// ---------- //
// Iterator. //
@@ -293,31 +339,40 @@
namespace oln
{
- struct switch_image_base;
+ // Fwd. decl.
+ template <typename E>
+ class image_dimension_switch;
- namespace error
+ // Default version, abort.
+ template <typename E>
+ class image_dimension_switch : mlc::abort_<E>
{
- struct ERROR_image_base;
};
- template <typename I>
- struct case_<switch_image_base, I, 1> :
- public mlc::where_ < mlc::eq_ <I, point2d> >
+ // Concept-based overloading for Image2d.
+ template <typename E> where concepts::Point2d< oln_type_of(E, point) >
+ class image_dimension_switch<E> : public oln::Image2d
{
- typedef Image2d ret;
- };
-
- template <typename I>
- struct case_<switch_image_base, I, 2> :
- public mlc::where_ < mlc::eq_ <I, point3d> >
+ public:
+ image_dimension_switch()
{
- typedef Image3d ret;
+ std::cout << "image_dimension_switch<E> "
+ << "where concepts::Point2d<oln_type_of(E, point)>"
+ << std::endl;
+ }
};
- template <typename I>
- struct default_case_<switch_image_base, I>
+ // Concept-based overloading for Image3d.
+ template <typename E> where concepts::Point3d< oln_type_of(E, point) >
+ class image_dimension_switch<E> : public oln::Image3d
+ {
+ public:
+ image_dimension_switch()
{
- typedef mlc::undefined ret;
+ std::cout << "image_dimension_switch<E> "
+ << "where concepts::Point3d<oln_type_of(E, point)>"
+ << std::endl;
+ }
};
}
@@ -334,7 +389,7 @@
template<typename E>
struct set_super_type< image_base<E> >
{
- typedef typename oln::switch_<switch_image_base, E>::ret ret;
+ typedef typename oln::image_dimension_switch<E> ret;
};
template <typename E>
@@ -346,7 +401,7 @@
};
template <typename E>
- struct image_base : public oln::switch_<switch_image_base, E>::ret
+ struct image_base : public oln::image_dimension_switch<E>
{
typedef oln_type_of(image_base, point) point_t;
typedef oln_type_of(image_base, iter) iter_t;