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

Migrate rangev3 cmcstl2 @HEAD

parent 29921abb
......@@ -22,7 +22,7 @@ before_script:
- cmake --build apps --config $PYLENE_CONFIGURATION
- cmake --build tests --config $PYLENE_CONFIGURATION
- cmake --build bench/tests --config $PYLENE_CONFIGURATION
- ctest -L UnitTests --schedule-random --output-on-failure
- ctest -L UnitTests -V --schedule-random --output-on-failure
dependencies: []
artifacts:
reports:
......
......@@ -39,8 +39,8 @@ class Pylene(ConanFile):
# Requirements part of the INTERFACE
def requirements(self):
self.requires("range-v3/0.4.0@ericniebler/stable")
self.requires("cmcstl2/0.1@dutiona/testing")
self.requires("range-v3/head@dutiona/patched")
self.requires("cmcstl2/head@dutiona/testing")
if self.options.freeimage:
self.requires("freeimage/3.18.0@dutiona/stable")
......
......@@ -147,7 +147,5 @@ int main(int argc, char** argv)
auto d_stretched = mln::data::stretch<float>(d);
mln::io::imsave(mln::transform(d_stretched, heat_lut), argv[2]);
// FIXME: migrate rangev3 @HEAD
// mln::io::experimental::imsave(mln::transform(output, regions_lut), argv[3]);
mln::io::experimental::imsave(mln::transform(output, regions_lut), argv[3]);
}
#include <mln/core/image/image2d.hpp>
#include <mln/core/image/private/image_operators.hpp>
#include <mln/core/neighb2d.hpp>
#include <mln/core/se/utility.hpp>
#include <mln/io/imread.hpp>
......@@ -9,6 +10,8 @@
int main(int argc, char** argv)
{
using namespace mln::experimental::ops;
if (argc < 7)
{
std::cerr << "Usage: " << argv[0] << " markers1.pbm markers2.pbm markers.pbm all.pbm lines.pbm\n";
......@@ -31,7 +34,7 @@ int main(int argc, char** argv)
auto se_miss = mln::se::make_se(se_miss_data);
auto output = mln::morpho::hit_or_miss(input, se_hit, se_miss);
markers1 = output;
mln::io::imsave(mln::lnot(markers1), argv[2]);
mln::io::experimental::imsave(not markers1, argv[2]);
}
{
......@@ -41,15 +44,18 @@ int main(int argc, char** argv)
auto se_miss = mln::se::make_se(se_miss_data);
auto output = mln::morpho::hit_or_miss(input, se_hit, se_miss);
markers2 = output;
mln::io::imsave(mln::lnot(markers2), argv[3]);
mln::io::experimental::imsave(not markers2, argv[3]);
}
auto markers = mln::lor(markers1, markers2);
mln::io::imsave(mln::lnot(markers), argv[4]);
auto markers = markers1 || markers2;
mln::io::experimental::imsave(not markers, argv[4]);
auto all_touching = mln::morpho::opening_by_reconstruction(input, markers, mln::c4);
// FIXME: add experimental version
auto markers_ = mln::lor(markers1, markers2);
auto all_touching = mln::morpho::opening_by_reconstruction(input, markers_, mln::c4);
mln::io::imsave(mln::lnot(all_touching), argv[5]);
auto lines_only = mln::morpho::opening_by_reconstruction(input, markers, mln::c2_h);
auto lines_only = mln::morpho::opening_by_reconstruction(input, markers_, mln::c2_h);
mln::io::imsave(mln::lnot(lines_only), argv[6]);
}
......@@ -57,7 +57,6 @@ if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.2)
find_package(cmcstl2 REQUIRED)
target_link_libraries(Pylene PUBLIC stl2)
target_compile_definitions(Pylene PUBLIC PYLENE_CONCEPT_TS_ENABLED)
target_compile_definitions(Pylene PUBLIC concept="concept bool")
endif()
......
......@@ -2,9 +2,11 @@
#include <mln/core/image/image.hpp>
#include <mln/core/rangev3/rows.hpp>
#include <range/v3/algorithm/all_of.hpp>
#include <range/v3/utility/functional.hpp>
namespace mln
{
template <class InputImage>
......
......@@ -2,9 +2,11 @@
#include <mln/core/image/image.hpp>
#include <mln/core/rangev3/rows.hpp>
#include <range/v3/algorithm/any_of.hpp>
#include <range/v3/utility/functional.hpp>
namespace mln
{
template <class InputImage, class UnaryPredicate>
......
......@@ -8,6 +8,12 @@
namespace mln
{
// FIXME: to remove once circular dependency between image/clone/copy is resolved
namespace experimental
{
template <class InputImage, class OutputImage>
void copy(InputImage src, OutputImage dest);
} // namespace experimental
/// \ingroup Algorithms
/// \brief Make and return a deep copy of an image.
......
......@@ -19,7 +19,7 @@ namespace mln
/******************/
template <class InputImage, class Value>
std::ptrdiff_t count(InputImage input, const Value& v)
std::ptrdiff_t count(InputImage input, const Value& val)
{
static_assert(mln::is_a<InputImage, Image>());
......@@ -27,7 +27,7 @@ namespace mln
std::ptrdiff_t k = 0;
for (auto r : ranges::rows(vals))
k += ::ranges::count(r, v);
k += ::ranges::count(r, val);
return k;
}
......
......@@ -39,6 +39,10 @@ namespace mln
auto&& lhs_vals = lhs.new_values();
auto&& rhs_vals = rhs.new_values();
using RngLhs = ::ranges::iterator_t<decltype(lhs_vals)>;
using RngRhs = ::ranges::iterator_t<decltype(rhs_vals)>;
static_assert(::ranges::Comparable<RngLhs, RngRhs, ::ranges::equal_to, ::ranges::ident, ::ranges::ident>());
for (auto [lhs_r, rhs_r] : ranges::view::zip(ranges::rows(lhs_vals), ranges::rows(rhs_vals)))
// FIXME: with std::equal you gain performances over ranges::equal here
if (!::ranges::equal(lhs_r, rhs_r))
......
......@@ -2,9 +2,11 @@
#include <mln/core/image/image.hpp>
#include <mln/core/rangev3/rows.hpp>
#include <range/v3/algorithm/none_of.hpp>
#include <range/v3/utility/functional.hpp>
namespace mln
{
......
#pragma once
/* DO NOT REMOVE */
// stl2/meta and ranges-v3/meta are not the same but have the same header guard (><)!!.
// stl2 works with ranges-v3/meta, but ranges-v3 doesn't work with stl2/meta
// here we force the usage of ranges-v3/meta
// stl2/meta is in <stl2/meta/meta.hpp>
#include <meta/meta.hpp>
#ifdef PYLENE_CONCEPT_TS_ENABLED
#ifdef concept
#define __concept_bool
#undef concept
#endif
#include <stl2/concepts.hpp>
#ifdef __concept_bool
#define concept concept bool
#undef __concept_bool
#endif
namespace mln::concepts::stl
{
using namespace __stl2;
}
// Dirty hack to allow proper conversion from ranges iterator iterator tags to __stl2 iterator tags
#include <range/v3/utility/iterator_concepts.hpp>
......@@ -80,4 +60,6 @@ namespace std::experimental::ranges
} // namespace v1
} // namespace std::experimental::ranges
#define concept META_CONCEPT
#endif // PYLENE_CONCEPT_TS_ENABLED
......@@ -13,6 +13,15 @@
#include <type_traits>
namespace mln
{
// FIXME: to remove once circular dependency between image/clone/copy is resolved
template <typename InputImage, typename OutputImage>
[[deprecated]] OutputImage& copy(const Image<InputImage>& input, Image<OutputImage>& output);
template <typename InputImage, typename OutputImage>
[[deprecated]] OutputImage&& copy(const Image<InputImage>& input, Image<OutputImage>&& output);
} // namespace mln
// FIXME:
namespace to_migrate
{
......@@ -48,7 +57,6 @@ namespace to_migrate
namespace mln
{
/// \defgroup free_functions Free functions
/// \ingroup image
/// \{
......
......@@ -98,8 +98,9 @@ namespace mln::experimental
{
auto operator()(const ICond& cond, ITrue iftrue, IFalse iffalse) const
{
auto g = [](auto tuple_ternary_expr) -> decltype(auto) {
return (std::get<0>(tuple_ternary_expr)) ? std::get<1>(tuple_ternary_expr) : std::get<2>(tuple_ternary_expr);
auto g = [](auto&& tuple_ternary_expr) -> decltype(auto) {
auto&& [im_c, im_t, im_f] = std::forward<decltype(tuple_ternary_expr)>(tuple_ternary_expr);
return im_c ? im_t : im_f;
};
return view::transform(view::zip(cond, iftrue, iffalse), g);
......
......@@ -15,8 +15,12 @@ namespace mln::ranges::view
struct filter_fn
{
template <typename Rng, typename Pred>
using Constraint =
::meta::and_<::ranges::InputRange<Rng>, ::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>>>;
using Constraint = ::meta::and_<::ranges::InputRange<Rng>, ::ranges::CopyConstructible<Pred>,
::ranges::Predicate<Pred, ::ranges::reference_t<::ranges::iterator_t<Rng>>>
// FIXME: IndirectPredicate is bugged, see issue #1077
// https://github.com/ericniebler/range-v3/issues/1077
//, ::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>>
>;
template <typename Rng, typename Pred, CONCEPT_REQUIRES_(Constraint<Rng, Pred>())>
// clang-format off
......@@ -24,7 +28,7 @@ namespace mln::ranges::view
requires mln::concepts::stl::InputRange<Rng> &&
mln::concepts::stl::IndirectUnaryPredicate<Pred, ::ranges::iterator_t<Rng>>
#endif
remove_if_view<::ranges::view::all_t<Rng>, ::ranges::logical_negate<Pred>> operator()(Rng&& rng, Pred pred) const
remove_if_view<::ranges::view::all_t<Rng>, ::ranges::logical_negate<Pred>> operator()(Rng&& rng, Pred pred) const
// clang-format on
{
return {::ranges::view::all(static_cast<Rng&&>(rng)), ::ranges::not_fn(std::move(pred))};
......@@ -35,7 +39,12 @@ namespace mln::ranges::view
{
CONCEPT_ASSERT_MSG(::ranges::InputRange<Rng>(), "The first argument to view::remove_if must be a model of the "
"InputRange concept");
CONCEPT_ASSERT_MSG(::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>>(),
CONCEPT_ASSERT_MSG(::meta::and_<::ranges::CopyConstructible<Pred>,
::ranges::Predicate<Pred, ::ranges::reference_t<::ranges::iterator_t<Rng>>>
// FIXME: IndirectPredicate is bugged, see issue #1077
// https://github.com/ericniebler/range-v3/issues/1077
//::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>
>(),
"The second argument to view::remove_if must be callable with "
"a value of the range, and the return type must be convertible "
"to bool");
......
......@@ -84,8 +84,12 @@ namespace mln::ranges
public:
template <typename Rng, typename Pred>
using Constraint =
::meta::and_<::ranges::InputRange<Rng>, ::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>>>;
using Constraint = ::meta::and_<::ranges::InputRange<Rng>,
::ranges::Predicate<Pred, ::ranges::reference_t<::ranges::iterator_t<Rng>>>
// FIXME: IndirectPredicate is bugged, see issue #1077
// https://github.com/ericniebler/range-v3/issues/1077
// ::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>>
>;
template <typename Rng, typename Pred, CONCEPT_REQUIRES_(Constraint<Rng, Pred>())>
#ifdef PYLENE_CONCEPT_TS_ENABLED
......@@ -103,7 +107,12 @@ namespace mln::ranges
{
CONCEPT_ASSERT_MSG(::ranges::InputRange<Rng>(), "The first argument to view::remove_if must be a model of the "
"InputRange concept");
CONCEPT_ASSERT_MSG(::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>>(),
CONCEPT_ASSERT_MSG(::meta::and_<::ranges::CopyConstructible<Pred>,
::ranges::Predicate<Pred, ::ranges::reference_t<::ranges::iterator_t<Rng>>>
// FIXME: IndirectPredicate is bugged, see issue #1077
// https://github.com/ericniebler/range-v3/issues/1077
//::ranges::IndirectPredicate<Pred, ::ranges::iterator_t<Rng>
>(),
"The second argument to view::remove_if must be callable with "
"a value of the range, and the return type must be convertible "
"to bool");
......
......@@ -50,6 +50,7 @@ namespace mln::ranges
using fun_ref_ = ::ranges::semiregular_ref_or_val_t<Fun, true>;
fun_ref_ fun_;
std::tuple<::ranges::iterator_t<Rngs>...> begins_;
static inline constexpr const bool are_bidir_rngs_ = (::ranges::BidirectionalRange<Rngs>() && ...);
public:
cursor() = default;
......@@ -89,21 +90,34 @@ namespace mln::ranges
std::apply([](auto&... rng_it) { (++rng_it, ...); }, begins_);
}
/*
#ifdef PYLENE_CONCEPT_TS_ENABLED
// clang-format off
void prev() requires (mln::concepts::stl::BidirectionalRange<Rngs> && ...)
// clang-format on
{
std::apply([](auto&... rng_it) { (--rng_it, ...); }, begins_);
}
#else
// Clunky SFINAE doesn't work
/*
template <typename U = void, typename = std::enable_if_t<(::ranges::BidirectionalRange<Rngs>() && ...)>>
void prev()
#endif
{
std::apply([](auto&... rng_it) { (--rng_it, ...); }, begins_);
}
*/
void prev()
{
std::apply([](auto&... rng_it) { (--rng_it, ...); }, begins_);
if constexpr (are_bidir_rngs_)
{
std::apply([](auto&... rng_it) { (--rng_it, ...); }, begins_);
}
else
{
static_assert(are_bidir_rngs_, "Cannot traverse non-bidirectional range backward");
}
}
#endif
};
cursor begin_cursor()
......@@ -250,7 +264,7 @@ namespace mln::ranges
}
template <typename Fun, typename... Rngs>
template <typename Fun, typename... Rngs>
#ifdef PYLENE_CONCEPT_TS_ENABLED
// clang-format off
auto zip_with_view<Fun, Rngs...>::rows() requires (mln::concepts::SegmentedRange<Rngs> && ...)
......
#pragma once
#include <mln/accu/accumulators/min.hpp>
#include <mln/core/algorithm/all_of.hpp>
#include <mln/core/image/image.hpp>
#include <mln/core/image/view/transform.hpp>
#include <mln/core/image/view/zip.hpp>
#include <mln/core/neighborhood/neighborhood.hpp>
#include <mln/morpho/canvas/unionfind.hpp>
......@@ -63,9 +66,11 @@ namespace mln
const J& markers = exact(markers_);
// assert that f <= markers
mln_precondition(all(imtransform(imzip(f, markers), [cmp](std::tuple<mln_value(I), mln_value(J)> v) {
return not cmp(std::get<1>(v), std::get<0>(v));
})));
// FIXME:
// mln_precondition(all_of(view::transform(view::zip(f, markers), [cmp](std::tuple<mln_value(I), mln_value(J)> v)
// {
// return not cmp(std::get<1>(v), std::get<0>(v));
// })));
mln_concrete(I) out = clone(f);
mln_ch_value(I, accu_t) accus;
......
......@@ -26,6 +26,7 @@ namespace mln
"Images f and marker must have the same point type.");
mln_entering("mln::morpho::opening_by_reconstruction");
// FIXME: add experimental version
return closing_by_reconstruction(f, markers, nbh, std::greater<mln_value(I)>());
}
} // namespace morpho
......
#include <mln/core/se/disc.hpp>
#include <mln/core/assert.hpp>
#include <stdexcept>
#include <stdexcept>
#include <array>
......
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