Commit 5360d7b0 authored by edwin.carlinet's avatar edwin.carlinet
Browse files

Image concept checking. Add mln assertion instead of assert.

  * mln/core/assert.hpp
  * mln/core/concept/image.hpp
  * mln/core/image/ndimage.hpp
  * mln/core/image_traits.hpp
  * mln/core/vec_base.hpp
parent a4ab763e
......@@ -5,13 +5,23 @@
#include <cassert>
#ifndef _MLN_HAS_NDEBUG_FIRST_
# ifdef NDEBUG
# define MLN_NDEBUG
# endif
# define _MLN_HAS_NDEBUG_FIRST_
#endif
#ifndef MLN_NDEBUG
# define mln_assertion(expr) assert(expr)
# define MLN_HAS_DEBUG 1
#
# define MLN_EVAL_IF_DEBUG(expr) expr
#else
# define mln_assertion(expr) (void (0))
# define MLN_HAS_DEBUG 0
# define MLN_EVAL_IF_DEBUG(expr)
#endif
#define mln_precondition(expr) mln_assertion(expr)
......
#ifndef MLN_CORE_CONCEPT_IMAGE_HPP
# define MLN_CORE_CONCEPT_IMAGE_HPP
# include <mln/core/image_traits.hpp>
# include <mln/core/concept/object.hpp>
# include <boost/concept_check.hpp>
# include <boost/range/iterator.hpp>
# include <boost/static_assert.hpp>
namespace mln {
void check(const std::true_type&)
{
}
template <typename I>
struct Image : Object_<I>
{
private:
typedef image_traits<I> traits;
public:
typedef typename traits::accessible accessible;
typedef typename traits::category category;
BOOST_CONCEPT_USAGE(Image)
{
typedef typename I::value_type value;
typedef typename I::reference reference;
typedef typename I::const_reference const_reference;
typedef typename I::pixel_type pixel;
typedef typename I::const_pixel_type const_pixel;
typedef typename I::site_type site_type;
typedef typename I::point_type point_type;
typedef typename I::domain_type domain_type;
const domain_type& (I::*method) () const = &I::domain;
(void) method;
check(std::is_convertible<typename pixel::value_type, value> ());
check(std::is_same<typename pixel::reference, reference> ());
check(std::is_convertible<typename const_pixel::value_type, value> ());
check(std::is_same<typename const_pixel::reference, const_reference> ());
}
};
template <typename I>
struct AccessibleImage : Image<I>
{
public:
typedef typename Image<I>::accessible accessible;
static_assert(accessible::value, "Image must be accessible");
BOOST_CONCEPT_USAGE(AccessibleImage)
{
typedef typename I::point_type point_type;
typedef typename I::reference reference;
typedef typename I::const_reference const_reference;
reference (I::*ptr) (point_type) = &I::operator();
const_reference (I::*ptr2) (point_type) const = &I::operator();
(void) ptr; (void) ptr2;
}
};
template <typename I>
struct IterableImage : Image<I>
{
public:
typedef typename Image<I>::category category;
static_assert(std::is_convertible<category, forward_image_tag>::value,
"Image category must be iterable");
BOOST_CONCEPT_USAGE(IterableImage)
{
typedef typename I::value_type value_type;
typedef typename I::reference reference;
typedef typename I::const_reference const_reference;
typedef typename I::pixel_type pixel_type;
typedef typename I::const_pixel_type const_pixel_type;
typedef typename I::value_range value_range;
typedef typename I::const_value_range const_value_range;
typedef typename I::pixel_range pixel_range;
typedef typename I::const_pixel_range const_pixel_range;
value_range (I::*ptr1) () = &I::values;
const_value_range (I::*ptr2) () const = &I::values;
pixel_range (I::*ptr3) () = &I::pixels;
const_pixel_range (I::*ptr4) () const = &I::pixels;
(void) ptr1;
(void) ptr2;
(void) ptr3;
(void) ptr4;
typedef typename boost::range_iterator<value_range>::type value_iterator;
typedef typename boost::range_iterator<const_value_range>::type const_value_iterator;
typedef typename boost::range_iterator<pixel_range>::type pixel_iterator;
typedef typename boost::range_iterator<const_pixel_range>::type const_pixel_iterator;
check(std::is_convertible<typename std::iterator_traits<value_iterator>::value_type, value_type> ());
// "Iterator's value type is expected to be the image value type.");
check(std::is_same<typename std::iterator_traits<value_iterator>::reference, reference> ());
// "Iterator's reference is expected to be the image reference");
check(std::is_convertible<typename std::iterator_traits<const_value_iterator>::value_type, value_type> ());
// "Iterator's value type is expected to be the image value type");
check(std::is_same<typename std::iterator_traits<const_value_iterator>::reference, const_reference> ());
// "Iterator's reference type is expected to be the image const reference");
check(std::is_const<typename std::remove_reference<const_reference>::type > ());
check(std::is_convertible<typename std::iterator_traits<pixel_iterator>::reference, pixel_type> ());
check(std::is_same<typename std::iterator_traits<pixel_iterator>::value_type, pixel_type> ());
// "Pixel Iterator's value type is expected to be the image pixel type");
check(std::is_convertible<typename std::iterator_traits<const_pixel_iterator>::reference, const_pixel_type> ());
check(std::is_same<typename std::iterator_traits<const_pixel_iterator>::value_type, const_pixel_type> ());
// "Pixel Iterator's value type is expected to be the image const pixel type");
check(std::is_same<typename pixel_type::image_type, I> ());
check(std::is_same<typename const_pixel_type::image_type, const I> ());
}
};
} // end of namespace mln
......
......@@ -66,6 +66,9 @@ namespace mln
ndimage_pixel<const T, dim, const E>
>
{
BOOST_CONCEPT_ASSERT((IterableImage<E>));
BOOST_CONCEPT_ASSERT((AccessibleImage<E>));
private:
typedef ndimage_base<T, dim, E> this_type;
public:
......
......@@ -3,6 +3,7 @@
# include <mln/core/image_category.hpp>
# include <type_traits>
# include <boost/range/iterator.hpp>
namespace mln
{
......@@ -10,7 +11,7 @@ namespace mln
struct image_static_tag {};
template <typename I>
struct image_traits;
struct image_traits : image_traits< typename std::decay<I>::type > {};
template <typename I>
struct image_traits<const I> : image_traits<I> {};
......@@ -55,36 +56,98 @@ namespace mln
};
template <typename Image>
struct image_value { typedef typename Image::value type; };
struct image_value
{
typedef typename std::remove_const<Image>::type::value_type type;
};
template <typename Image>
struct image_pixel
{
typedef typename std::conditional<std::is_const<Image>::value,
typename std::remove_const<Image>::type::const_pixel_type,
typename Image::pixel_type>::type type;
};
template <typename Image>
struct image_pixel { typedef typename Image::pixel type; };
struct image_const_pixel
{
typedef typename std::remove_const<Image>::type::const_pixel_type type;
};
template <typename Image>
struct image_reference { typedef typename Image::reference type; };
struct image_reference
{
typedef typename std::conditional<std::is_const<Image>::value,
typename Image::const_reference,
typename Image::reference>::type type;
};
template <typename Image>
struct image_const_reference { typedef typename Image::const_reference type; };
struct image_const_reference
{
typedef typename Image::const_reference type;
};
template <typename Image>
struct image_value_iterator { typedef typename Image::value_iterator type; };
struct image_value_range
{
typedef typename std::conditional<std::is_const<Image>::value,
typename Image::const_value_range,
typename Image::value_range>::type type;
};
template <typename Image>
struct image_pixel_iterator { typedef typename Image::pixel_iterator type; };
struct image_pixel_range
{
typedef typename std::conditional<std::is_const<Image>::value,
typename Image::const_pixel_range,
typename Image::pixel_range>::type type;
};
template <typename Image>
struct image_const_value_iterator { typedef typename Image::const_value_iterator type; };
struct image_const_value_range
{
typedef typename Image::const_value_range type;
};
template <typename Image>
struct image_const_pixel_iterator { typedef typename Image::const_pixel_iterator type; };
struct image_const_pixel_range
{
typedef typename Image::const_pixel_range type;
};
template <typename Image>
struct image_value_iterator
{
typedef typename boost::range_iterator<typename image_value_range<Image>::type>::type type;
};
template <typename Image>
struct image_pixel_iterator
{
typedef typename boost::range_iterator<typename image_pixel_range<Image>::type>::type type;
};
template <typename Image>
struct image_const_value_iterator
{
typedef typename boost::range_iterator<typename image_const_value_range<Image>::type>::type type;
};
template <typename Image>
struct image_const_pixel_iterator
{
typedef typename boost::range_iterator<typename image_const_pixel_range<Image>::type>::type type;
};
struct image_value_ {
struct image_meta_value {
template <typename Image>
struct apply { typedef typename std::decay<Image>::type::value_type type; };
};
struct image_pixel_ {
struct image_meta_pixel {
template <typename Image>
struct apply { typedef typename std::decay<Image>::type::pixel_type type; };
......@@ -92,7 +155,7 @@ namespace mln
struct apply<const Image&> { typedef typename std::decay<Image>::type::const_pixel_type type; };
};
struct image_const_pixel_ {
struct image_meta_const_pixel {
template <typename Image>
struct apply { typedef typename std::decay<Image>::type::const_pixel_type type; };
};
......
#ifndef MLN_INTERNAL_VEC_BASE_HH
# define MLN_INTERNAL_VEC_BASE_HH
// FIXME:
// replace boost::common_type by c++11 decltype for type broadcasting
// replace boost::enable_if by c++11 std::enable_if
......@@ -16,7 +18,7 @@
#include <boost/utility.hpp>
#include <iostream>
#include <array>
#include <mln/core/assert.hpp>
// Element-wise operator
......@@ -147,6 +149,8 @@ namespace mln
typedef size_t size_type;
typedef ptrdiff_t difference_type;
enum { ndim = dim };
template <typename U>
vec_base&
operator= (const vec_base<U, dim, tag>& other)
......@@ -155,8 +159,8 @@ namespace mln
return *this;
}
T& operator[] (size_type n) { assert(n < dim); return v_[n]; }
const T& operator[] (size_type n) const { assert(n < dim); return v_[n]; }
T& operator[] (size_type n) { mln_precondition(n < dim); return v_[n]; }
const T& operator[] (size_type n) const { mln_precondition(n < dim); return v_[n]; }
T* begin() { return v_; }
T* end() { return v_ + dim; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment