Commit 278a5bb3 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Try to make image2d non-const copy constructible.

parent 6a20ee2b
#ifndef MLN_BOX_HH
# define MLN_BOX_HH
# include <mln/core/image_traits.hpp>
# include <mln/core/point.hpp>
# include <mln/core/image/internal/nested_loop_iterator.hpp>
//# include <mln/core/iterator/fast_reverse_iterator.hpp>
......@@ -65,12 +66,26 @@ namespace mln
point_type pmax;
};
// Aliases
typedef box<short, 1> box1d;
typedef box<float, 1> box1df;
typedef box<short, 2> box2d;
typedef box<float, 2> box2df;
typedef box<short, 3> box3d;
// Image traits specialization
// forward declaration
template <typename V> struct image2d;
template <typename V>
struct image_from_domain<box2d, V>
{
typedef image2d<V> type;
};
template <typename T, unsigned dim>
inline
std::ostream&
......
......@@ -30,10 +30,10 @@ namespace mln {
struct image2d : ndimage_base<T, 2, image2d<T> >
{
private:
typedef ndimage_base<T, 2, image2d<T> > base_type;
typedef ndimage_base<T, 2, image2d<T> > base;
public:
typedef typename base_type::domain_type domain_type;
typedef typename base::domain_type domain_type;
explicit image2d (unsigned border = 3) : ndimage_base<T,2,image2d<T> > (border)
......@@ -51,6 +51,25 @@ namespace mln {
{
}
image2d(image2d<T>&& other)
: base( std::move(other) )
{
}
image2d(image2d<T>& other)
: base( other )
{
}
template <typename U>
image2d(const image2d<U>& other,
typename std::enable_if< std::is_const<T>::value and
std::is_convertible<U*, T*>::value>::type* = NULL)
: base( other )
{
}
unsigned nrows() const { return this->domain_.pmax[0] - this->domain_.pmin[0]; }
unsigned ncols() const { return this->domain_.pmax[1] - this->domain_.pmin[1]; }
......
......@@ -90,6 +90,44 @@ namespace mln
// \{
explicit ndimage_base(unsigned border = 3);
explicit ndimage_base(const domain_type& domain, unsigned border = 3);
// construction from const lvalue or rvalue
template <typename T2, typename E2>
ndimage_base(const ndimage_base<T2, dim, E2>& other,
typename std::enable_if< std::is_const<T>::value and
std::is_convertible<T2*, T*>::value>::type* = NULL)
: domain_ (other.domain_),
strides_ (other.strides_),
data_ (other.data_),
border_ (other.border_),
ptr_ (other.ptr_),
last_ (other.last_)
{
}
// Construction from rvalue
ndimage_base(ndimage_base<T, dim, E>&& other)
: domain_ (std::move(other.domain_)),
strides_ (std::move(other.strides_)),
data_ (std::move(other.data_)),
border_ (std::move(other.border_)),
ptr_ (std::move(other.ptr_)),
last_ (std::move(other.last_))
{
}
// Construction from lvalue
ndimage_base(ndimage_base<T, dim, E>& other)
: domain_ (other.domain_),
strides_ (other.strides_),
data_ (other.data_),
border_ (other.border_),
ptr_ (other.ptr_),
last_ (other.last_)
{
}
// \}
const domain_type& domain() const;
......@@ -161,12 +199,12 @@ namespace mln
friend struct ndimage_pixel<const T, dim, const E>;
template <typename, typename> friend struct ndimage_value_range;
template <typename, typename> friend struct ndimage_pixel_range;
template <typename, unsigned, typename> friend struct ndimage_base;
domain_type domain_; ///< Domain of image
std::array<size_t, dim> strides_; ///< Strides in bytes
std::shared_ptr< internal::ndimage_data<T, dim> > data_;
std::shared_ptr< internal::ndimage_data<typename std::remove_const<T>::type, dim> > data_;
int border_;
char* ptr_; ///< Pointer to the first element
char* last_; ///< Pointer to the last element
......
......@@ -144,6 +144,15 @@ namespace mln
operator() (T& x) const {return static_cast<const T&> (x); }
};
struct meta_add_reference
{
template <typename T> struct apply { typedef typename std::remove_reference<T>::type& type; };
template <typename T>
typename std::remove_const<T>::type &
operator() (T& x) const {return const_cast<typename std::remove_const<T>::type&>( x ); }
};
}
......@@ -167,8 +176,9 @@ namespace mln
typedef boost::tuple<Images...> ImageTuple;
typedef typename internal::tuple_meta_transform<ImageTuple, internal::constify>::type ConstImageTuple;
typedef typename boost::tuples::element<0, ImageTuple>::type Image;
typedef typename internal::tuple_meta_transform<ImageTuple, internal::meta_add_reference>::type ImageTupleRef;
typedef typename internal::tuple_meta_transform<ImageTuple, internal::constify>::type ConstImageTupleRef;
typedef typename boost::tuples::element<0, ImageTuple>::type Image;
typedef typename std::decay<Image>::type VImage;
typedef boost::tuple<Images...> images_t;
......@@ -192,13 +202,13 @@ namespace mln
// typedef boost::iterator_range<value_iterator> value_range;
// typedef boost::iterator_range<const_value_iterator> const_value_range;
typedef zip_image_value_range<typename internal::zip_image_category<ImageTuple>::type, ImageTuple> value_range;
typedef zip_image_value_range<typename internal::zip_image_category<ImageTuple>::type, ConstImageTuple> const_value_range;
typedef zip_image_value_range<typename internal::zip_image_category<ImageTuple>::type, ImageTupleRef> value_range;
typedef zip_image_value_range<typename internal::zip_image_category<ImageTuple>::type, ConstImageTupleRef> const_value_range;
typedef typename value_range::iterator value_iterator;
typedef typename const_value_range::iterator const_value_iterator;
typedef zip_image_pixel_range<typename internal::zip_image_category<ImageTuple>::type, ImageTuple, E> pixel_range;
typedef zip_image_pixel_range<typename internal::zip_image_category<ImageTuple>::type, ConstImageTuple, const E> const_pixel_range;
typedef zip_image_pixel_range<typename internal::zip_image_category<ImageTuple>::type, ImageTupleRef, E> pixel_range;
typedef zip_image_pixel_range<typename internal::zip_image_category<ImageTuple>::type, ConstImageTupleRef, const E> const_pixel_range;
typedef typename pixel_range::iterator pixel_iterator;
typedef typename const_pixel_range::iterator const_pixel_iterator;
typedef typename pixel_iterator::value_type pixel_type;
......@@ -207,11 +217,26 @@ namespace mln
/// \brief Constructor
/// \todo Check that all domain are equals
/// \todo Add concept checking
zip_image(Images&&... imas) :
explicit zip_image(Images&&... imas) :
images_ (std::forward<Images>(imas)...)
{
}
zip_image(zip_image&& other)
: images_ (std::move(other.images_))
{
}
zip_image(const zip_image& other)
: images_ (other.images_)
{
}
zip_image(zip_image& other)
: images_ (other.images_)
{
}
// zip_image(const Images&... imas) :
// images_ (imas...)
// {
......@@ -225,7 +250,7 @@ namespace mln
value_range values()
{
return value_range(images_);
return value_range(internal::tuple_transform(images_, internal::meta_add_reference ()));
// using namespace boost::detail::tuple_impl_specific;
// auto w = tuple_transform(images_, internal::get_image_value_range ());
// value_iterator begin_(tuple_transform(w, internal::get_image_value_iterator_begin ()));
......@@ -245,7 +270,7 @@ namespace mln
pixel_range pixels()
{
return pixel_range(images_, *this);
return pixel_range(internal::tuple_transform(images_, internal::meta_add_reference ()), *this);
// auto x = this->values();
// pixel_iterator begin_(std::begin(this->domain()), std::begin(x), *this);
// pixel_iterator end_(std::end(this->domain()), std::end(x), *this);
......
......@@ -431,7 +431,7 @@ namespace mln
}
private:
ImageTuple imas_;
ImageTuple imas_;
ZipImage& zip_;
};
......
......@@ -22,6 +22,17 @@ namespace mln
template <typename I>
struct image_traits<const volatile I> : image_traits<I> {};
template <typename Domain, typename V>
struct image_from_domain;
template <typename Image, typename V>
struct image_change_value
{
typedef typename image_from_domain<typename Image::domain_type, V>::type type;
};
//{
// Type of image (dynamic or static)
//typedef typename image_traits<I>::category category;
......
add_executable(bench_iterator ../bench_iterator.cpp)
add_executable(bench_zip_iterator ../bench_zip_iterator.cpp)
add_executable(image2d image/image2d.cpp)
add_executable(array std/array.cpp)
add_executable(zip_image image/zip_image.cpp)
......@@ -13,6 +16,7 @@ add_executable(paste algorithm/paste.cpp)
add_executable(equal algorithm/equal.cpp)
add_test(image2d image2d)
add_test(zip_image zip_image)
add_test(image_ops image_ops)
add_test(copy copy)
......
#include <mln/core/image/image2d.hpp>
#define BOOST_TEST_MODULE Core
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(Image2d)
BOOST_AUTO_TEST_CASE(construction)
{
using namespace mln;
image2d<int> a; // default construction
image2d<char> b(5,5); // construction from nrows, ncols
image2d<int> c(box2d{{5,5}, {10,10}}); // construction from domain
image2d<int> d = c; // Copy construction
const image2d<int>& e = a;
image2d<const int> f = a; // Copy construction
image2d<const int> g = e; // Copy construction
// Should work soons
//image2d<int> e = b; // Assignment
}
BOOST_AUTO_TEST_SUITE_END()
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