Commit dc530938 authored by Michaël Roynard's avatar Michaël Roynard
Browse files

Correct const-ness of pixel reference type through writable traits

parent b24d354a
Pipeline #12368 passed with stages
in 16 minutes and 23 seconds
......@@ -81,13 +81,14 @@ namespace mln::archetypes
{
using new_pixel_type = OutputPixel;
struct OutputPixelRange final
{
using value_type = image_pixel_t<OutputImage>;
using reference = image_pixel_t<OutputImage>&;
new_pixel_type* begin();
new_pixel_type* end();
value_type* begin();
value_type* end();
};
OutputPixelRange new_pixels();
......@@ -124,7 +125,7 @@ namespace mln::archetypes
using indexable = std::true_type;
image_reference_t<IndexableImage> operator[](image_index_t<IndexableImage>) const;
image_point_t<IndexableImage> point_of_index(image_index_t<IndexableImage>) const;
image_point_t<IndexableImage> new_point_of_index(image_index_t<IndexableImage>) const;
image_index_t<IndexableImage> index_at_point(image_point_t<IndexableImage>) const;
image_index_t<IndexableImage> delta_index(image_point_t<IndexableImage>) const;
};
......@@ -137,13 +138,29 @@ namespace mln::archetypes
struct OutputIndexableImage final : IndexableImage
{
using IndexableImage:: operator[];
using new_pixel_type = OutputPixel;
using reference = pixel_reference_t<OutputPixel>;
image_reference_t<OutputIndexableImage> operator[](image_index_t<OutputIndexableImage>) const;
image_reference_t<OutputIndexableImage> operator[](image_index_t<OutputIndexableImage>);
struct OutputPixelRange final
{
using value_type = image_pixel_t<OutputIndexableImage>;
using reference = image_pixel_t<OutputIndexableImage>&;
value_type* begin();
value_type* end();
};
OutputPixelRange new_pixels();
};
#ifdef PYLENE_CONCEPT_TS_ENABLED
static_assert(mln::concepts::IndexableImage<OutputIndexableImage> && mln::concepts::OutputImage<OutputIndexableImage>,
"OutputIndexableImage archetype does not model the OutputImage concept!");
"OutputIndexableImage archetype does not model the OutputImageconcept!");
#endif // PYLENE_CONCEPT_TS_ENABLED
......@@ -165,14 +182,32 @@ namespace mln::archetypes
struct OutputAccessibleImage final : AccessibleImage
{
using AccessibleImage:: operator();
image_reference_t<OutputAccessibleImage> operator[](image_point_t<OutputAccessibleImage>);
using new_pixel_type = OutputPixel;
using reference = pixel_reference_t<OutputPixel>;
image_reference_t<OutputAccessibleImage> operator()(image_point_t<OutputAccessibleImage>) const;
image_reference_t<OutputAccessibleImage> operator()(image_point_t<OutputAccessibleImage>);
using AccessibleImage::at;
image_reference_t<OutputAccessibleImage> at(image_point_t<OutputAccessibleImage>) const;
image_reference_t<OutputAccessibleImage> at(image_point_t<OutputAccessibleImage>);
image_pixel_t<OutputAccessibleImage> new_pixel(image_point_t<OutputAccessibleImage>) const;
image_pixel_t<OutputAccessibleImage> new_pixel_at(image_point_t<OutputAccessibleImage>) const;
struct OutputPixelRange final
{
using value_type = image_pixel_t<OutputAccessibleImage>;
using reference = image_pixel_t<OutputAccessibleImage>&;
value_type* begin();
value_type* end();
};
OutputPixelRange new_pixels();
};
#ifdef PYLENE_CONCEPT_TS_ENABLED
static_assert(mln::concepts::AccessibleImage<OutputAccessibleImage> &&
mln::concepts::OutputImage<OutputAccessibleImage>,
"OutputAccessibleImage archetype does not model the OutputImage concept!");
......@@ -199,6 +234,7 @@ namespace mln::archetypes
};
#ifdef PYLENE_CONCEPT_TS_ENABLED
static_assert(mln::concepts::BidirectionalImage<BidirectionalImage>,
"BidirectionalImage archetype does not model the BidirectionalImage concept!");
#endif // PYLENE_CONCEPT_TS_ENABLED
......@@ -207,14 +243,15 @@ namespace mln::archetypes
struct OutputBidirectionalImage : BidirectionalImage
{
using new_pixel_type = OutputPixel;
using reference = pixel_reference_t<OutputPixel>;
struct OutputPixelRange
{
using value_type = image_pixel_t<OutputBidirectionalImage>;
using reference = image_pixel_t<OutputBidirectionalImage>&;
new_pixel_type* begin();
new_pixel_type* end();
value_type* begin();
value_type* end();
};
struct ReversibleOutputPixelRange final : OutputPixelRange
......@@ -240,7 +277,7 @@ namespace mln::archetypes
using accessible = std::true_type;
image_reference_t<RawImage> operator[](image_index_t<RawImage>) const;
image_point_t<RawImage> point_of_index(image_index_t<RawImage>) const;
image_point_t<RawImage> new_point_of_index(image_index_t<RawImage>) const;
image_index_t<RawImage> index_at_point(image_point_t<RawImage>) const;
image_index_t<RawImage> delta_index(image_point_t<RawImage>) const;
......@@ -270,6 +307,7 @@ namespace mln::archetypes
};
#ifdef PYLENE_CONCEPT_TS_ENABLED
static_assert(mln::concepts::RawImage<RawImage>, "RawImage archetype does not model the RawImage concept!");
#endif // PYLENE_CONCEPT_TS_ENABLED
......@@ -277,14 +315,15 @@ namespace mln::archetypes
struct OutputRawImage final : RawImage
{
using new_pixel_type = OutputPixel;
using reference = pixel_reference_t<OutputPixel>;
using RawImage:: operator[];
image_reference_t<OutputRawImage> operator[](image_index_t<OutputRawImage>) const;
image_reference_t<OutputRawImage> operator[](image_index_t<OutputRawImage>);
using RawImage:: operator();
image_reference_t<OutputRawImage> operator[](image_point_t<OutputRawImage>);
image_reference_t<OutputRawImage> operator()(image_point_t<OutputRawImage>) const;
image_reference_t<OutputRawImage> operator()(image_point_t<OutputRawImage>);
using RawImage::at;
image_reference_t<OutputRawImage> at(image_point_t<OutputRawImage>) const;
image_reference_t<OutputRawImage> at(image_point_t<OutputRawImage>);
// Need to be redefined as pixel_type has changed
......@@ -297,8 +336,8 @@ namespace mln::archetypes
using value_type = image_pixel_t<OutputRawImage>;
using reference = image_pixel_t<OutputRawImage>&;
new_pixel_type* begin();
new_pixel_type* end();
value_type* begin();
value_type* end();
};
struct ReversibleOutputPixelRange final : OutputPixelRange
......
......@@ -12,7 +12,7 @@ namespace mln::archetypes
{
using value_type = Value;
using point_type = Point;
using reference = Value&;
using reference = const value_type&;
point_type point() const;
reference val() const;
......@@ -28,8 +28,9 @@ namespace mln::archetypes
struct OutputPixel final : Pixel
{
using Pixel::val;
reference val();
using reference = value_type&;
reference val() const;
};
#ifdef PYLENE_CONCEPT_TS_ENABLED
......
......@@ -52,16 +52,16 @@ namespace mln::concepts
Point<image_point_t<Ima>> &&
Value<image_value_t<Ima>> &&
Domain<image_domain_t<Ima>> &&
stl::Same<image_point_t<Ima>, pixel_point_t<image_pixel_t<Ima>>> &&
stl::Same<image_value_t<Ima>, pixel_value_t<image_pixel_t<Ima>>> &&
stl::Same<image_reference_t<Ima>, pixel_reference_t<image_pixel_t<Ima>>> &&
stl::Same<pixel_point_t<image_pixel_t<Ima>>, image_point_t<Ima>> &&
stl::Same<pixel_value_t<image_pixel_t<Ima>>, image_value_t<Ima>> &&
stl::ConvertibleTo<pixel_reference_t<image_pixel_t<Ima>>, image_reference_t<Ima>> &&
stl::CommonReference<image_reference_t<Ima>&&, image_value_t<Ima>&> &&
stl::CommonReference<image_reference_t<Ima>&&, image_value_t<Ima>&&> &&
stl::CommonReference<image_value_t<Ima>&&, const image_value_t<Ima>&> &&
requires(Ima ima, const Ima cima, image_domain_t<Ima> d, image_point_t<Ima> p) {
{ cima.template ch_value<mln::archetypes::Value>() }
-> stl::ConvertibleTo<image_ch_value_t<Ima, mln::archetypes::Value>>&&; // Image builder (FIXME: improve builder design)
{ cima.concretize() } -> stl::ConvertibleTo<image_concrete_t<Ima>>&&; // Image builder (FIXME: improve builder design)
{ cima.concretize() } -> stl::ConvertibleTo<image_concrete_t<Ima>>&&; // Image builder (FIXME: improve builder design)
{ cima.domain() } -> image_domain_t<Ima>;
{ ima.new_pixels() } -> stl::ForwardRange&&;
{ ima.new_values() } -> stl::ForwardRange&&;
......@@ -78,6 +78,7 @@ namespace mln::concepts
template<typename WIma>
concept WritableImage =
Image<WIma> &&
OutputPixel<image_pixel_t<WIma>> &&
requires(WIma ima) {
{ ima.new_values() } -> stl::OutputRange<image_value_t<WIma>>&&;
// Check Writability of each pixel of the range
......@@ -106,10 +107,10 @@ namespace mln::concepts
} &&
image_indexable_v<Ima> &&
requires (const Ima cima, image_index_t<Ima> k, image_point_t<Ima> p) {
{ cima[k] } -> image_reference_t<Ima>;
{ cima.point_of_index(k) } -> image_point_t<Ima>;
{ cima.index_at_point(p) } -> image_index_t<Ima>;
{ cima.delta_index(p) } -> image_index_t<Ima>;
{ cima[k] } -> image_reference_t<Ima>;
{ cima.new_point_of_index(k) } -> image_point_t<Ima>;
{ cima.index_at_point(p) } -> image_index_t<Ima>;
{ cima.delta_index(p) } -> image_index_t<Ima>;
};
......@@ -122,7 +123,7 @@ namespace mln::concepts
WritableImage<WIma> &&
IndexableImage<WIma> &&
requires(WIma ima, image_index_t<WIma> k, image_value_t<WIma> v) {
{ ima[k] = v };
{ ima[k] = v } -> image_reference_t<WIma>;
};
} // namespace detail
......@@ -150,8 +151,8 @@ namespace mln::concepts
detail::WritableImage<WIma> &&
AccessibleImage<WIma> &&
requires(WIma ima, image_point_t<WIma> p, image_value_t<WIma> v) {
{ ima(p) = v };
{ ima.at(p) = v };
{ ima(p) = v } -> image_reference_t<WIma>;
{ ima.at(p) = v } -> image_reference_t<WIma>;
};
} // namespace detail
......@@ -205,6 +206,7 @@ namespace mln::concepts
WritableBidirectionalImage<WIma> &&
RawImage<WIma> &&
requires(WIma ima, image_value_t<WIma> v) {
{ ima.data() } -> stl::ConvertibleTo<image_value_t<WIma>*>&&;
{ *(ima.data()) = v };
};
......
......@@ -41,8 +41,8 @@ namespace mln::concepts
template <typename Pix>
concept WritablePixel =
Pixel<Pix> &&
requires(Pix pix, pixel_value_t<Pix> v) {
{ pix.val() = v };
requires(const Pix cpix, pixel_value_t<Pix> v) {
{ cpix.val() = v }; // Not deep-const, view-semantic.
};
} // namespace mln::concepts::detail
......
......@@ -16,15 +16,15 @@ namespace mln::concepts
{
// RangeValueSame
template <typename Rng, typename V>
template <typename Rng, typename Val>
concept RangeValueTypeSameAs =
stl::Same<stl::iter_value_t<stl::iterator_t<Rng>>, V>;
stl::Same< stl::iter_value_t<stl::iterator_t<Rng>>, Val>;
// RangeValueConvertibleTo
template <typename Rng, typename V>
template <typename Rng, typename Val>
concept RangeValueTypeConvertibleTo =
stl::ConvertibleTo<stl::iter_value_t<stl::iterator_t<Rng>>, V>;
stl::ConvertibleTo<stl::iter_value_t<stl::iterator_t<Rng>>, Val>;
}
......
......@@ -332,7 +332,8 @@ namespace mln
size_type index_of_point(const point_type& p) const;
/// \copydoc image::point_at_index(size_type i) const
point_type point_at_index(size_type i) const;
[[deprecated]] point_type point_at_index(size_type i) const;
new_point_type new_point_at_index(index_type i) const;
/// \copydoc image::delta_index(const point_type&) const
difference_type delta_index(const point_type& p) const;
......
......@@ -32,7 +32,7 @@ namespace mln::details
using value_type = std::remove_const_t<T>;
using reference = T&;
T& val() const { return m_lineptr[m_point[N - 1]]; }
reference val() const { return m_lineptr[m_point[N - 1]]; }
point_type point() const { return m_point; }
T* m_lineptr;
......
#include <mln/core/concept/new/images.hpp>
#include <mln/core/concept/new/archetype/image.hpp>
#include <gtest/gtest.h>
#include <tuple>
#include <type_traits>
namespace concepts = mln::concepts;
struct mock_image;
struct mock_image
{
struct mock_domain
{
struct mock_point
{
int x;
};
using value_type = mock_point;
using reference = mock_point&;
mock_point* begin();
mock_point* end();
bool has(value_type) const;
bool empty() const;
unsigned size() const;
};
struct mock_pixel
{
using point_type = mock_domain::value_type;
using value_type = double;
using reference = double&;
point_type point() const { return pnt; }
reference val() const { return *v; }
private:
point_type pnt;
value_type* v;
};
using new_pixel_type = mock_pixel;
using value_type = mock_pixel::value_type;
using reference = mock_pixel::reference;
using new_point_type = mock_domain::value_type;
using domain_type = mock_domain;
using category_type = mln::forward_image_tag;
using concrete_type = mock_image;
template <concepts::Value Val>
using ch_value_type = mock_image;
// additional traits
using extension_category = mln::extension::none_extension_tag;
using indexable = std::false_type;
using accessible = std::false_type;
using bidirectional = std::false_type;
using raw = std::false_type;
template <concepts::Value Val>
ch_value_type<Val> ch_value() const;
concrete_type concretize() const;
domain_type domain() const;
struct mock_pixel_rng
{
using value_type = new_pixel_type;
using reference = new_pixel_type&;
new_pixel_type* begin();
new_pixel_type* end();
};
mock_pixel_rng new_pixels();
struct mock_value_rng
{
using value_type = mock_image::value_type;
using reference = mock_image::reference;
mock_image::value_type* begin();
mock_image::value_type* end();
};
mock_value_rng new_values();
};
bool operator==(const mock_image::mock_domain::mock_point& lhs, const mock_image::mock_domain::mock_point& rhs)
{
return lhs.x == rhs.x;
}
bool operator!=(const mock_image::mock_domain::mock_point& lhs, const mock_image::mock_domain::mock_point& rhs)
{
return !(lhs == rhs);
}
bool operator<(const mock_image::mock_domain::mock_point& lhs, const mock_image::mock_domain::mock_point& rhs)
{
return lhs.x < rhs.x;
}
bool operator>(const mock_image::mock_domain::mock_point& lhs, const mock_image::mock_domain::mock_point& rhs)
{
return rhs < lhs;
}
bool operator<=(const mock_image::mock_domain::mock_point& lhs, const mock_image::mock_domain::mock_point& rhs)
{
return !(lhs > rhs);
}
bool operator>=(const mock_image::mock_domain::mock_point& lhs, const mock_image::mock_domain::mock_point& rhs)
{
return !(lhs < rhs);
}
bool operator==(const mock_image::mock_pixel& lhs, const mock_image::mock_pixel& rhs)
{
return lhs.point() == rhs.point() && lhs.val() == rhs.val();
}
bool operator!=(const mock_image::mock_pixel& lhs, const mock_image::mock_pixel& rhs)
{
return !(lhs == rhs);
}
template <typename Ima>
requires concepts::Image<Ima> void foo(Ima)
{
}
namespace concepts = mln::concepts;
namespace archetypes = mln::archetypes;
TEST(Core, Concept_Image)
{
static_assert(concepts::Domain<mock_image::mock_domain>);
static_assert(concepts::Pixel<mock_image::mock_pixel>);
static_assert(concepts::stl::ForwardRange<mock_image::mock_pixel_rng>);
static_assert(concepts::stl::ForwardRange<mock_image::mock_value_rng>);
static_assert(concepts::Image<mock_image>);
static_assert(concepts::Image<archetypes::Image>);
}
// TODO check all images properties
#include <mln/core/concept/new/archetype/pixel.hpp>
#include <mln/core/concept/new/pixels.hpp>
#include <tuple>
......@@ -5,40 +6,25 @@
#include <gtest/gtest.h>
namespace concepts = mln::concepts;
namespace concepts = mln::concepts;
namespace archetypes = mln::archetypes;
struct A
{
};
struct Pix
{
using value_type = int;
using point_type = int;
using reference = int&;
point_type point() const { return pnt; }
reference val() const { return *v; }
private:
int pnt;
int* v;
};
bool operator==(const Pix& lhs, const Pix& rhs)
{
return std::tie(lhs.pnt, *lhs.v) == std::tie(rhs.pnt, *rhs.v);
}
bool operator!=(const Pix& lhs, const Pix& rhs)
{
return !(lhs == rhs);
}
TEST(Core, Concept_Pixel)
{
static_assert(!concepts::Pixel<int>);
static_assert(!concepts::Pixel<A>);
static_assert(concepts::Pixel<Pix>);
static_assert(concepts::Pixel<archetypes::Pixel>);
}
TEST(Core, Concept_OutputPixel)
{
static_assert(!concepts::OutputPixel<int>);
static_assert(!concepts::OutputPixel<A>);
static_assert(!concepts::OutputPixel<archetypes::Pixel>);
static_assert(concepts::OutputPixel<archetypes::OutputPixel>);
}
......@@ -10,11 +10,25 @@
namespace concepts = mln::concepts;
#ifdef PYLENE_CONCEPT_TS_ENABLED
template <concepts::Image Ima>
void foo(Ima)
{
}
#endif // PYLENE_CONCEPT_TS_ENABLED
TEST(Core, Image_Image2D)
{
#ifdef PYLENE_CONCEPT_TS_ENABLED
foo(mln::image2d<int>{});
static_assert(concepts::Image<mln::image2d<int>>);
// static_assert(concepts::IndexableImage<mln::image2d<int>>);
// static_assert(concepts::AccessibleImage<mln::image2d<int>>);
// static_assert(concepts::BidirectionalImage<mln::image2d<int>>);
// static_assert(concepts::RawImage<mln::image2d<int>>);
#endif // PYLENE_CONCEPT_TS_ENABLED
}
......@@ -22,6 +36,6 @@ TEST(Core, Image_Image2D)
TEST(Core, Image_Image3D)
{
#ifdef PYLENE_CONCEPT_TS_ENABLED
static_assert(concepts::Image<mln::image3d<int>>);
// static_assert(concepts::Image<mln::image3d<int>>);
#endif // PYLENE_CONCEPT_TS_ENABLED
}
Supports Markdown
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