Commit e1f8c70e authored by Edwin Carlinet's avatar Edwin Carlinet

Change concepts to be C++20 compliant and update range-v3 version.

* Fix namespace ::ranges::view -> ::ranges::views.
* Fix bad concept checking in extensions.
parent fb239cb3
......@@ -45,7 +45,7 @@ class Pylene(ConanFile):
# Requirements part of the INTERFACE
def requirements(self):
self.requires("range-v3/0.9.1@ericniebler/stable")
self.requires("range-v3/0.10.0@ericniebler/stable")
self.requires("fmt/6.0.0")
if self.options.freeimage:
......
......@@ -4,7 +4,7 @@ find_package(Boost 1.58 REQUIRED)
find_package(FreeImage REQUIRED)
find_package(TBB)
find_package(range-v3 0.9.1 REQUIRED CONFIG)
find_package(range-v3 0.10.0 REQUIRED CONFIG)
find_package(fmt 6.0 REQUIRED)
set(PYLENE_USE_TBB YES CACHE BOOL "Set to NO to disable use of TBB and parallelization")
......
include(CMakeFindDependencyMacro)
find_dependency(Boost 1.58)
find_dependency(range-v3 0.9.1 CONFIG)
find_dependency(range-v3 0.10.0 CONFIG)
find_dependency(fmt 6.0)
include("${CMAKE_CURRENT_LIST_DIR}/PyleneTargets.cmake")
......@@ -98,8 +98,8 @@ namespace mln
return size(2);
}
using Impl::cursor;
using Impl::backward_cursor;
using typename Impl::cursor;
using typename Impl::backward_cursor;
using Impl::begin_cursor;
using Impl::end_cursor;
using Impl::rbegin_cursor;
......
......@@ -13,7 +13,7 @@ namespace mln::canvas
template <class SE, class I, class J, class Self = void>
// This concept check makes an ICE with MSVC
#ifndef _MSC_VER
requires concepts::StructuringElement<SE, image_point_t<I>>&& concepts::Image<I>&& concepts::Image<J>
requires concepts::StructuringElement<SE, image_point_t<I>> && concepts::Image<I> && concepts::Image<J>
#endif
class LocalAlgorithm
{
......@@ -101,6 +101,9 @@ namespace mln::canvas
template <class SE, class I, class J, class Self>
#ifndef _MSC_VER
requires concepts::StructuringElement<SE, image_point_t<I>> && concepts::Image<I> && concepts::Image<J>
#endif
void LocalAlgorithm<SE, I, J, Self>::Execute()
{
mln_entering("LocalAlgorithm::Execute (Non-incremental)");
......
......@@ -20,9 +20,9 @@ namespace mln::concepts
mln::ranges::mdrange<Dom> &&
Point<mln::ranges::mdrange_value_t<Dom>> &&
requires(const Dom cdom, mln::ranges::mdrange_value_t<Dom> p) {
{ cdom.has(p) } -> bool;
{ cdom.empty() } -> bool;
{ cdom.dim() } -> int;
{ cdom.has(p) } -> ::concepts::same_as<bool>;
{ cdom.empty() } -> ::concepts::same_as<bool>;
{ cdom.dim() } -> ::concepts::same_as<int>;
};
......@@ -39,7 +39,6 @@ namespace mln::concepts
concept ShapedDomain =
SizedDomain<Dom> &&
requires(const Dom cdom) {
{ cdom.shape() } -> ::ranges::range_value_t<Dom>;
{ cdom.extents() } -> ::ranges::cpp20::forward_range;
};
......
......@@ -73,7 +73,7 @@ namespace mln::concepts
{ cima.template ch_value<mln::archetypes::Value>() }
-> ::concepts::convertible_to<image_ch_value_t<I, mln::archetypes::Value>>;
{ cima.concretize() } -> ::concepts::convertible_to<image_concrete_t<I>>;
{ cima.domain() } -> image_domain_t<I>;
{ cima.domain() } -> ::concepts::convertible_to<image_domain_t<I>>;
{ ima.pixels() } -> mln::ranges::mdrange;
{ ima.values() } -> mln::ranges::mdrange;
requires ::concepts::convertible_to<mln::ranges::mdrange_value_t<decltype(ima.pixels())>, image_pixel_t<I>>;
......@@ -120,7 +120,7 @@ namespace mln::concepts
} &&
image_indexable_v<I> &&
requires (I ima, image_index_t<I> k) {
{ ima[k] } -> image_reference_t<I>; // For concrete image it returns a const_reference
{ ima[k] } -> ::concepts::same_as<image_reference_t<I>>; // For concrete image it returns a const_reference
};
......@@ -133,9 +133,9 @@ namespace mln::concepts
WritableImage<I> &&
IndexableImage<I> &&
requires(I ima, image_index_t<I> k, image_value_t<I> v) {
{ ima[k] = v } -> image_reference_t<I>;
{ ima[k] = v } -> ::concepts::same_as<image_reference_t<I>>;
};
} // namespace detail
......@@ -145,10 +145,10 @@ namespace mln::concepts
Image<I> &&
image_accessible_v<I> &&
requires (I ima, image_point_t<I> p) {
{ ima(p) } -> image_reference_t<I>; // For concrete image it returns a const_reference
{ ima.at(p) } -> image_reference_t<I>; // idem
{ ima.new_pixel(p) } -> image_pixel_t<I>; // For concrete image pixel may propagate constness
{ ima.new_pixel_at(p) } -> image_pixel_t<I>; // idem
{ ima(p) } -> ::concepts::same_as<image_reference_t<I>>; // For concrete image it returns a const_reference
{ ima.at(p) } -> ::concepts::same_as<image_reference_t<I>>; // idem
{ ima.new_pixel(p) } -> ::concepts::same_as<image_pixel_t<I>>; // For concrete image pixel may propagate constness
{ ima.new_pixel_at(p) } -> ::concepts::same_as<image_pixel_t<I>>; // idem
};
......@@ -161,10 +161,10 @@ namespace mln::concepts
detail::WritableImage<I> &&
AccessibleImage<I> &&
requires(I ima, image_point_t<I> p, image_value_t<I> v) {
{ ima(p) = v } -> image_reference_t<I>;
{ ima.at(p) = v } -> image_reference_t<I>;
{ ima(p) = v };
{ ima.at(p) = v };
};
} // namespace detail
......@@ -174,9 +174,9 @@ namespace mln::concepts
IndexableImage<I> &&
AccessibleImage<I> &&
requires (const I cima, image_index_t<I> k, image_point_t<I> p) {
{ cima.point_at_index(k) } -> image_point_t<I>;
{ cima.index_of_point(p) } -> image_index_t<I>;
{ cima.delta_index(p) } -> image_index_t<I>;
{ cima.point_at_index(k) } -> ::concepts::same_as<image_point_t<I>>;
{ cima.index_of_point(p) } -> ::concepts::same_as<image_index_t<I>>;
{ cima.delta_index(p) } -> ::concepts::same_as<image_index_t<I>>;
};
......@@ -222,8 +222,8 @@ namespace mln::concepts
BidirectionalImage<I> &&
::concepts::derived_from<image_category_t<I>, raw_image_tag> &&
requires (I ima, const I cima, int dim) {
{ ima.data() } -> ::concepts::convertible_to<const image_value_t<I>*>; // data() may be proxied by a view
{ cima.stride(dim) } -> std::ptrdiff_t;
{ ima.data() } -> ::concepts::convertible_to<const image_value_t<I>*>; // data() may be proxied by a view
{ cima.stride(dim) } -> ::concepts::same_as<std::ptrdiff_t>;
};
......@@ -238,7 +238,7 @@ namespace mln::concepts
WritableBidirectionalImage<I> &&
RawImage<I> &&
requires(I ima, image_value_t<I> v) {
{ ima.data() } -> ::concepts::convertible_to<image_value_t<I>*>;
{ ima.data() } -> ::concepts::convertible_to<image_value_t<I>*>;
{ *(ima.data()) = v };
};
......@@ -267,7 +267,7 @@ namespace mln::concepts
} &&
not ::concepts::same_as<mln::extension::none_extension_tag, image_extension_category_t<I>> &&
requires (I ima, image_point_t<I> p) {
{ ima.extension() } -> image_extension_t<I>;
{ ima.extension() } -> ::concepts::same_as<image_extension_t<I>>;
};
......
......@@ -49,6 +49,10 @@ namespace mln
template <typename T, template <typename> class Concept>
using is_a = typename internal::is_a_helper<T, Concept>::type;
template <typename T, template <typename> class Concept>
constexpr inline bool is_a_v = is_a<T, Concept>::value;
/*********************/
/* Implementation */
/*********************/
......
......@@ -33,7 +33,7 @@ namespace mln::concepts
!std::is_reference_v<pixel_value_t<Pix>> &&
requires(const Pix cpix, Pix pix, pixel_point_t<Pix> p) {
{ cpix.point() } -> ::concepts::convertible_to<pixel_point_t<Pix>>;
#if (__GNUG__) // see https://stackoverflow.com/questions/55198202/unable-to-deduce-placeholder-type-in-concept
#if (__GNUG__ == 9) // see https://stackoverflow.com/questions/55198202/unable-to-deduce-placeholder-type-in-concept
{ cpix.val() } -> ::concepts::convertible_to<pixel_reference_t<Pix>>&&;
#else
{ cpix.val() } -> ::concepts::convertible_to<pixel_reference_t<Pix>>;
......
......@@ -27,7 +27,7 @@ namespace mln::concepts
template <typename SE>
concept DynamicStructuringElement =
requires (SE se) {
{ se.radial_extent() } -> int;
{ se.radial_extent() } -> ::concepts::same_as<int>;
};
......@@ -73,7 +73,7 @@ namespace mln::concepts
StructuringElement<SE, P> &&
::concepts::convertible_to<typename SE::decomposable, std::true_type> &&
requires(const SE se) {
{ se.is_decomposable() } -> bool;
{ se.is_decomposable() } -> ::concepts::same_as<bool>;
{ se.decompose() } -> ::ranges::cpp20::forward_range;
requires details::RangeOfStructuringElement<decltype(se.decompose()), P>;
};
......@@ -84,7 +84,7 @@ namespace mln::concepts
StructuringElement<SE, P> &&
::concepts::convertible_to<typename SE::separable, std::true_type> &&
requires(const SE se) {
{ se.is_separable() } -> bool;
{ se.is_separable() } -> ::concepts::same_as<bool>;
{ se.separate() } -> ::ranges::cpp20::forward_range;
requires details::RangeOfStructuringElement<decltype(se.separate()), P>;
};
......
......@@ -25,7 +25,7 @@ namespace mln::extension
template <typename SE>
constexpr bool fit(const SE&) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
return true;
}
......
......@@ -37,7 +37,7 @@ namespace mln::extension
template <typename SE>
constexpr bool fit(const SE&) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
// TODO: non-trivial
return true;
......
......@@ -23,7 +23,7 @@ namespace mln::extension
template <typename SE>
constexpr bool fit(const SE&) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
return true;
}
......
......@@ -25,7 +25,7 @@ namespace mln::extension
template <typename SE>
constexpr bool fit(const SE&) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
return true;
}
......
......@@ -30,7 +30,7 @@ namespace mln::extension
template <typename SE>
constexpr bool fit(const SE&) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
return true;
}
......
......@@ -22,7 +22,7 @@ namespace mln::extension
template <typename SE>
constexpr bool fit(const SE& se) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
if constexpr (std::is_base_of_v<mln::dynamic_neighborhood_tag, typename SE::category>)
{
......
......@@ -21,7 +21,7 @@ namespace mln::internal
class __ndbuffer_image_data;
template <>
class __ndbuffer_image_data<void> : public ndbuffer_image_data
class __ndbuffer_image_data<void> final : public ndbuffer_image_data
{
std::allocator<std::byte> m_allocator;
......@@ -33,7 +33,7 @@ namespace mln::internal
};
template <class T>
class __ndbuffer_image_data : public ndbuffer_image_data
class __ndbuffer_image_data final : public ndbuffer_image_data
{
std::allocator<T> m_allocator;
......
......@@ -76,7 +76,7 @@ namespace mln
template <typename SE>
constexpr bool fit(const SE& se) const
{
static_assert(concepts::StructuringElement<SE>, "SE is not a valid Structuring Element!");
static_assert(mln::is_a_v<SE, details::StructuringElement>, "SE is not a valid Structuring Element!");
return std::visit([&se](auto&& ima) { return ima.extension().fit(se); }, *m_adapted_image_ptr);
}
......
......@@ -59,19 +59,19 @@ namespace mln
template <class P>
requires(!mln::is_a<P, mln::details::Pixel>::value) auto operator()(const P& point) const
{
return ::ranges::view::transform(static_cast<const N*>(this)->offsets(), details::add_point<P>{point});
return ::ranges::views::transform(static_cast<const N*>(this)->offsets(), details::add_point<P>{point});
}
template <class P>
requires(!mln::is_a<P, mln::details::Pixel>::value) auto before(const P& point) const
{
return ::ranges::view::transform(static_cast<const N*>(this)->before_offsets(), details::add_point<P>{point});
return ::ranges::views::transform(static_cast<const N*>(this)->before_offsets(), details::add_point<P>{point});
}
template <class P>
requires(!mln::is_a<P, mln::details::Pixel>::value) auto after(const P& point) const
{
return ::ranges::view::transform(static_cast<const N*>(this)->after_offsets(), details::add_point<P>{point});
return ::ranges::views::transform(static_cast<const N*>(this)->after_offsets(), details::add_point<P>{point});
}
};
......@@ -99,19 +99,19 @@ namespace mln
template <class P> requires(!mln::is_a<P, mln::details::Pixel>::value)
auto operator()(const P& point) const
{
return ::ranges::view::transform(static_cast<const N*>(this)->offsets(), details::add_wpoint<P>{point});
return ::ranges::views::transform(static_cast<const N*>(this)->offsets(), details::add_wpoint<P>{point});
}
template <class P> requires(!mln::is_a<P, mln::details::Pixel>::value)
auto before(const P& point) const
{
return ::ranges::view::transform(static_cast<const N*>(this)->before_offsets(), details::add_wpoint<P>{point});
return ::ranges::views::transform(static_cast<const N*>(this)->before_offsets(), details::add_wpoint<P>{point});
}
template <class P> requires(!mln::is_a<P, mln::details::Pixel>::value)
auto after(const P& point) const
{
return ::ranges::view::transform(static_cast<const N*>(this)->after_offsets(), details::add_wpoint<P>{point});
return ::ranges::views::transform(static_cast<const N*>(this)->after_offsets(), details::add_wpoint<P>{point});
}
};
} // namespace mln
......@@ -205,7 +205,7 @@ namespace mln
pcontainer(const pcontainer& other) = default;
// From a span
constexpr pcontainer(int dim, const T* data) noexcept
constexpr pcontainer([[maybe_unused]] int dim, const T* data) noexcept
{
assert(dim == Dim && "Point dimensions mistmatch.");
for (int i = 0; i < Dim; ++i)
......
......@@ -9,10 +9,7 @@ namespace mln
struct bidirectional_image_tag : forward_image_tag
{
};
struct[[deprecated]] random_access_image_tag : bidirectional_image_tag
{
};
struct raw_image_tag : random_access_image_tag
struct raw_image_tag : bidirectional_image_tag
{
};
//clang-format on
......
......@@ -149,7 +149,7 @@ namespace mln::ranges
x[k]--;
}
__back(x) = __back(m_from);
return ::ranges::view::reverse(row_t(x, static_cast<std::size_t>(__back(m_to) - __back(m_from))));
return ::ranges::views::reverse(row_t(x, static_cast<std::size_t>(__back(m_to) - __back(m_from))));
}
......
......@@ -47,7 +47,7 @@ namespace mln::ranges
::ranges::reverse_view<::ranges::span<T>> __read_rrow() const
{
auto line = ::ranges::make_span(m_ptr[Rank - 2] - m_count.back() + 1, m_ptr[Rank - 2] + 1);
return ::ranges::view::reverse(line);
return ::ranges::views::reverse(line);
}
bool __is_at_end(std::size_t k) const { return m_i[k] == m_count[k]; }
......
......@@ -19,7 +19,7 @@ namespace mln::ranges::view
template <::ranges::cpp20::range Rng, class Fun>
[[gnu::always_inline]] inline auto filter(Rng&& rng, Fun&& fun)
{
return ::ranges::view::filter(std::forward<Rng>(rng), std::forward<Fun>(fun));
return ::ranges::views::filter(std::forward<Rng>(rng), std::forward<Fun>(fun));
}
} // namespace mln::ranges::view
......@@ -45,7 +45,7 @@ namespace mln::ranges
requires ::ranges::cpp20::bidirectional_range<R>
auto reverse(R&& rng)
{
return ::ranges::view::reverse(std::forward<R>(rng));
return ::ranges::views::reverse(std::forward<R>(rng));
}
}
......
......@@ -221,13 +221,13 @@ namespace mln::ranges
template <::ranges::cpp20::range Rng, class Fun>
[[gnu::always_inline]] inline auto transform(Rng&& rng, Fun&& fun)
{
return ::ranges::view::transform(std::forward<Rng>(rng), std::forward<Fun>(fun));
return ::ranges::views::transform(std::forward<Rng>(rng), std::forward<Fun>(fun));
}
template <::ranges::cpp20::range Rng1, ::ranges::cpp20::range Rng2, class Fun>
[[gnu::always_inline]] inline auto transform(Rng1&& rng1, Rng2&& rng2, Fun&& fun)
{
return ::ranges::view::transform(std::forward<Rng1>(rng1), std::forward<Rng2>(rng2), std::forward<Fun>(fun));
return ::ranges::views::transform(std::forward<Rng1>(rng1), std::forward<Rng2>(rng2), std::forward<Fun>(fun));
}
} // namespace view
......
......@@ -171,9 +171,9 @@ namespace mln::ranges
static_assert(::ranges::invocable<F, mln::ranges::mdrange_reference_t<Rng>...>);
static_assert(::ranges::predicate<Pred, mln::ranges::mdrange_value_t<Rng>...>);
auto z = ::ranges::view::zip(std::forward<Rng>(ranges)...);
auto f = ::ranges::view::filter(z, [pred = std::move(pred_fn)](auto&& t) { return std::apply(pred, t); });
auto m = ::ranges::view::transform(
auto z = ::ranges::views::zip(std::forward<Rng>(ranges)...);
auto f = ::ranges::views::filter(z, [pred = std::move(pred_fn)](auto&& t) { return std::apply(pred, t); });
auto m = ::ranges::views::transform(
z, [f = std::move(map_fn)](auto&& t) -> decltype(auto) { return std::apply(f, t); });
return m;
......
......@@ -103,9 +103,10 @@ namespace mln::ranges
} // namespace details
template <class F, MDRange... Rng>
template <class F, class... Rng>
struct zip_with_mdview : details::mdview_facade<zip_with_mdview<F, Rng...>>
{
static_assert((... && MDRange<Rng>));
using cursor = details::zip_with_mdcursor<F, ::ranges::detail::begin_cursor_t<Rng>...>;
cursor begin_cursor() const
......@@ -176,7 +177,7 @@ namespace mln::ranges
template <class F, ::ranges::cpp20::range... Rng>
[[gnu::always_inline]] inline auto zip_with(F&& zip_fn, Rng&&... ranges)
{
return ::ranges::view::zip_with(std::forward<F>(zip_fn), std::forward<Rng>(ranges)...);
return ::ranges::views::zip_with(std::forward<F>(zip_fn), std::forward<Rng>(ranges)...);
}
}
......@@ -192,7 +193,7 @@ namespace mln::ranges
template <::ranges::cpp20::range... Rng>
[[gnu::always_inline]] inline auto zip(Rng&&... ranges)
{
return ::ranges::view::zip(std::forward<Rng>(ranges)...);
return ::ranges::views::zip(std::forward<Rng>(ranges)...);
}
}
......
......@@ -25,7 +25,7 @@ namespace mln
template <class P>
requires(!mln::is_a<P, mln::details::Pixel>::value) auto operator()(const P& point) const
{
return ::ranges::view::transform(static_cast<const SE*>(this)->offsets(), details::add_point<P>{point});
return ::ranges::views::transform(static_cast<const SE*>(this)->offsets(), details::add_point<P>{point});
}
};
......
......@@ -25,14 +25,14 @@ namespace mln
template <class P>
requires(mln::is_a<P, mln::details::Pixel>::value) auto operator()(const P& pixel) const
{
return ::ranges::view::filter(details::sliding_pixel_range{pixel, static_cast<const SE*>(this)->offsets()},
return ::ranges::views::filter(details::sliding_pixel_range{pixel, static_cast<const SE*>(this)->offsets()},
[this](auto pix) { return m_pred(pix.point()); });
}
template <class P>
requires(!mln::is_a<P, mln::details::Pixel>::value) auto operator()(const P& point) const
{
return ::ranges::view::filter(::ranges::view::transform(static_cast<const SE*>(this)->offsets(),
return ::ranges::views::filter(::ranges::views::transform(static_cast<const SE*>(this)->offsets(),
[point](P offset) -> P { return point + offset; }),
m_pred);
}
......
......@@ -130,7 +130,7 @@ namespace mln::morpho::canvas
// Forward pass
{
mln_entering("Union-find forward pass");
for (auto p : ::ranges::view::reverse(S))
for (auto p : ::ranges::views::reverse(S))
{
par(p) = p;
viz.on_make_set(p);
......
......@@ -12,8 +12,8 @@ template <class A, class B>
concept Interoperable = ::concepts::equality_comparable_with<A, B>
&& requires(A& a, const A& ca, const B& b)
{
{ ca.includes(b) } -> bool;
{ ca.intersects(b) } -> bool;
{ ca.includes(b) } -> ::concepts::same_as<bool>;
{ ca.intersects(b) } -> ::concepts::same_as<bool>;
{ a.clip(b) };
};
......
......@@ -9,10 +9,10 @@
template <typename U, typename V = U>
concept AddableWith = requires(U a, V b)
{
{ a += b } -> U&;
{ a -= b } -> U&;
{ b += a } -> V&;
{ b -= a } -> V&;
{ a += b } -> ::concepts::same_as<U&>;
{ a -= b } -> ::concepts::same_as<U&>;
{ b += a } -> ::concepts::same_as<V&>;
{ b -= a } -> ::concepts::same_as<V&>;
{ a + b };
{ a - b };
{ b + a};
......
......@@ -111,7 +111,7 @@ TYPED_TEST(MultiSpanTest, forward)
{
typename TestFixture::range_type rng(this->m_data.data(), this->m_count, this->m_stride);
auto ref = ::ranges::to_vector(::ranges::view::indices(int(this->m_size)));
auto ref = ::ranges::to_vector(::ranges::views::indices(int(this->m_size)));
auto vrng = this->rng_to_container(rng);
auto vrng2 = this->rng_to_container_row_wise(rng);
ASSERT_EQ(ref, vrng);
......@@ -123,7 +123,7 @@ TYPED_TEST(MultiSpanTest, backward)
{
typename TestFixture::range_type rng(this->m_data.data(), this->m_count, this->m_stride);
auto ref = ::ranges::to_vector(::ranges::view::reverse(::ranges::view::indices(int(this->m_size))));
auto ref = ::ranges::to_vector(::ranges::views::reverse(::ranges::views::indices(int(this->m_size))));
auto vrng = this->rng_to_container(rng.reversed());
auto vrng2 = this->rng_to_container_row_wise(rng.reversed());
ASSERT_EQ(ref, vrng);
......
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