Skip to content

Commit

Permalink
deprecated apply_operation in favour of variant2::visit for any_image
Browse files Browse the repository at this point in the history
  • Loading branch information
marco-langer committed May 1, 2022
1 parent c063d1c commit 8cd1fc3
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 31 deletions.
33 changes: 18 additions & 15 deletions include/boost/gil/extension/dynamic_image/algorithm.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright 2005-2007 Adobe Systems Incorporated
// Copyright 2022 Marco Langer <langer.m86 at gmail dot com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
Expand All @@ -12,6 +13,8 @@

#include <boost/gil/algorithm.hpp>

#include <boost/variant2/variant.hpp>

#include <functional>

////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -43,31 +46,31 @@ struct equal_pixels_fn : binary_operation_obj<equal_pixels_fn, bool>
/// \tparam Types Model Boost.MP11-compatible list of models of ImageViewConcept
/// \tparam View Model MutableImageViewConcept
template <typename ...Types, typename View>
bool equal_pixels(any_image_view<Types...> const& src, View const& dst)
auto equal_pixels(any_image_view<Types...> const& src, View const& dst) -> bool
{
return apply_operation(
src,
std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst));
return variant2::visit(
std::bind(detail::equal_pixels_fn(), std::placeholders::_1, dst),
src);
}

/// \ingroup ImageViewSTLAlgorithmsEqualPixels
/// \tparam View Model ImageViewConcept
/// \tparam Types Model Boost.MP11-compatible list of models of MutableImageViewConcept
template <typename View, typename ...Types>
bool equal_pixels(View const& src, any_image_view<Types...> const& dst)
auto equal_pixels(View const& src, any_image_view<Types...> const& dst) -> bool
{
return apply_operation(
dst,
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1));
return variant2::visit(
std::bind(detail::equal_pixels_fn(), src, std::placeholders::_1),
dst);
}

/// \ingroup ImageViewSTLAlgorithmsEqualPixels
/// \tparam Types1 Model Boost.MP11-compatible list of models of ImageViewConcept
/// \tparam Types2 Model Boost.MP11-compatible list of models of MutableImageViewConcept
template <typename ...Types1, typename ...Types2>
bool equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
auto equal_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst) -> bool
{
return apply_operation(src, dst, detail::equal_pixels_fn());
return variant2::visit(detail::equal_pixels_fn(), src, dst);
}

namespace detail {
Expand All @@ -90,7 +93,7 @@ struct copy_pixels_fn : public binary_operation_obj<copy_pixels_fn>
template <typename ...Types, typename View>
void copy_pixels(any_image_view<Types...> const& src, View const& dst)
{
apply_operation(src, std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst));
variant2::visit(std::bind(detail::copy_pixels_fn(), std::placeholders::_1, dst), src);
}

/// \ingroup ImageViewSTLAlgorithmsCopyPixels
Expand All @@ -99,7 +102,7 @@ void copy_pixels(any_image_view<Types...> const& src, View const& dst)
template <typename ...Types, typename View>
void copy_pixels(View const& src, any_image_view<Types...> const& dst)
{
apply_operation(dst, std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1));
variant2::visit(std::bind(detail::copy_pixels_fn(), src, std::placeholders::_1), dst);
}

/// \ingroup ImageViewSTLAlgorithmsCopyPixels
Expand All @@ -108,7 +111,7 @@ void copy_pixels(View const& src, any_image_view<Types...> const& dst)
template <typename ...Types1, typename ...Types2>
void copy_pixels(any_image_view<Types1...> const& src, any_image_view<Types2...> const& dst)
{
apply_operation(src, dst, detail::copy_pixels_fn());
variant2::visit(detail::copy_pixels_fn(), src, dst);
}

//forward declaration for default_color_converter (see full definition in color_convert.hpp)
Expand Down Expand Up @@ -227,7 +230,7 @@ struct fill_pixels_fn
template <typename ...Types, typename Value>
void fill_pixels(any_image_view<Types...> const& view, Value const& val)
{
apply_operation(view, detail::fill_pixels_fn<Value>(val));
variant2::visit(detail::fill_pixels_fn<Value>(val), view);
}

namespace detail {
Expand All @@ -236,7 +239,7 @@ template <typename F>
struct for_each_pixel_fn
{
for_each_pixel_fn(F&& fun) : fun_(std::move(fun)) {}

template <typename View>
auto operator()(View const& view) -> F
{
Expand Down
11 changes: 5 additions & 6 deletions include/boost/gil/extension/dynamic_image/any_image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#define BOOST_GIL_EXTENSION_DYNAMIC_IMAGE_ANY_IMAGE_HPP

#include <boost/gil/extension/dynamic_image/any_image_view.hpp>
#include <boost/gil/extension/dynamic_image/apply_operation.hpp>

#include <boost/gil/image.hpp>
#include <boost/gil/detail/mp11.hpp>
Expand Down Expand Up @@ -121,7 +120,7 @@ class any_image : public variant2::variant<Images...>

void recreate(const point_t& dims, unsigned alignment=1)
{
apply_operation(*this, detail::recreate_image_fnobj(dims, alignment));
variant2::visit(detail::recreate_image_fnobj(dims, alignment), *this);
}

void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1)
Expand All @@ -131,12 +130,12 @@ class any_image : public variant2::variant<Images...>

std::size_t num_channels() const
{
return apply_operation(*this, detail::any_type_get_num_channels());
return variant2::visit(detail::any_type_get_num_channels(), *this);
}

point_t dimensions() const
{
return apply_operation(*this, detail::any_type_get_dimensions());
return variant2::visit(detail::any_type_get_dimensions(), *this);
}

x_coord_t width() const { return dimensions().x; }
Expand All @@ -156,7 +155,7 @@ BOOST_FORCEINLINE
auto view(any_image<Images...>& img) -> typename any_image<Images...>::view_t
{
using view_t = typename any_image<Images...>::view_t;
return apply_operation(img, detail::any_image_get_view<view_t>());
return variant2::visit(detail::any_image_get_view<view_t>(), img);
}

/// \brief Returns the constant-pixel view of any image. The returned view is any view.
Expand All @@ -166,7 +165,7 @@ BOOST_FORCEINLINE
auto const_view(any_image<Images...> const& img) -> typename any_image<Images...>::const_view_t
{
using view_t = typename any_image<Images...>::const_view_t;
return apply_operation(img, detail::any_image_get_const_view<view_t>());
return variant2::visit(detail::any_image_get_const_view<view_t>(), img);
}
///@}

Expand Down
8 changes: 4 additions & 4 deletions include/boost/gil/extension/dynamic_image/any_image_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct any_type_get_size
/// Other requirements, such as access to the pixels, would be inefficient to provide. Thus \p any_image_view does not fully model ImageViewConcept.
/// However, many algorithms provide overloads taking runtime specified views and thus in many cases \p any_image_view can be used in places taking a view.
///
/// To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling \p apply_operation(runtime_view, algorithm_fn);
/// To perform an algorithm on any_image_view, put the algorithm in a function object and invoke it by calling \p variant2::visit(algorithm_fn, runtime_view);
////////////////////////////////////////////////////////////////////////////////////////

template <typename ...Views>
Expand Down Expand Up @@ -105,9 +105,9 @@ class any_image_view : public variant2::variant<Views...>
return *this;
}

std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); }
point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); }
size_type size() const { return apply_operation(*this, detail::any_type_get_size()); }
std::size_t num_channels() const { return variant2::visit(detail::any_type_get_num_channels(), *this); }
point_t dimensions() const { return variant2::visit(detail::any_type_get_dimensions(), *this); }
size_type size() const { return variant2::visit(detail::any_type_get_size(), *this); }
x_coord_t width() const { return dimensions().x; }
y_coord_t height() const { return dimensions().y; }
};
Expand Down
4 changes: 4 additions & 0 deletions test/extension/dynamic_image/algorithm/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@

import testing ;

run copy_and_convert_pixels.cpp ;
run copy_pixels.cpp ;
run equal_pixels.cpp ;
run fill_pixels.cpp ;
run for_each_pixel.cpp ;
104 changes: 104 additions & 0 deletions test/extension/dynamic_image/algorithm/copy_and_convert_pixels.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// Copyright (c) 2022 Marco Langer <langer.m86 at gmail dot com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/gil/extension/dynamic_image/any_image.hpp>
#include <boost/gil/extension/dynamic_image/algorithm.hpp>

#include <boost/core/lightweight_test.hpp>

#include <utility>

#include "../test_fixture.hpp"
#include "core/image/test_fixture.hpp"

namespace gil = boost::gil;
namespace fixture = boost::gil::test::fixture;

struct test_copy_and_convert_pixels
{
template <typename ImageLhs, typename ImageRhs>
void operator()(std::pair<ImageLhs, ImageRhs> const&)
{
// TODO
#if 0
using image_lhs_t = ImageLhs;
using image_rhs_t = ImageRhs;
using image_view_lhs_t = typename image_lhs_t::view_t;
using image_view_rhs_t = typename image_rhs_t::view_t;

{
// dynamic_image -> image
fixture::dynamic_image dyn_image_lhs(fixture::create_image<image_lhs_t>(2, 2, 128));
image_lhs_t image_lhs(2, 2);
image_rhs_t image_rhs(2, 2);

BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs), gil::view(image_lhs)));

if (gil::views_are_compatible<image_view_lhs_t, image_view_rhs_t>::value)
{
BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs), gil::view(image_rhs)));
}
else
{
BOOST_TEST_THROWS(gil::copy_pixels(gil::const_view(dyn_image_lhs), gil::view(image_rhs)), std::bad_cast);
}
}
{
// image -> dynamic_image
image_lhs_t image_lhs = fixture::create_image<image_lhs_t>(2, 2, 128);
image_rhs_t image_rhs = fixture::create_image<image_rhs_t>(2, 2, 128);
fixture::dynamic_image dyn_image_rhs(image_rhs_t(2, 2));

BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(image_rhs), gil::view(dyn_image_rhs)));

if (gil::views_are_compatible<image_view_lhs_t, image_view_rhs_t>::value)
{
BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(image_lhs), gil::view(dyn_image_rhs)));
}
else
{
BOOST_TEST_THROWS(gil::copy_pixels(gil::const_view(image_lhs), gil::view(dyn_image_rhs)), std::bad_cast);
}
}
{
// dynamic_image -> dynamic_image
fixture::dynamic_image dyn_image_lhs1(fixture::create_image<image_lhs_t>(2, 2, 128));
fixture::dynamic_image dyn_image_lhs2(image_lhs_t(2, 2));
fixture::dynamic_image dyn_image_rhs(image_rhs_t(2, 2));

BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_lhs2)));

if (gil::views_are_compatible<image_view_lhs_t, image_view_rhs_t>::value)
{
BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_rhs)));
}
else
{
BOOST_TEST_THROWS(gil::copy_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_rhs)), std::bad_cast);
}
}
#endif
}

static void run()
{
boost::mp11::mp_for_each
<
boost::mp11::mp_pairwise_fold
<
fixture::image_types, std::pair
>
>(test_copy_and_convert_pixels{});
}
};

int main()
{
test_copy_and_convert_pixels::run();

return ::boost::report_errors();
}
101 changes: 101 additions & 0 deletions test/extension/dynamic_image/algorithm/copy_pixels.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//
// Copyright (c) 2022 Marco Langer <langer.m86 at gmail dot com>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/gil/extension/dynamic_image/any_image.hpp>
#include <boost/gil/extension/dynamic_image/algorithm.hpp>

#include <boost/core/lightweight_test.hpp>

#include <utility>

#include "../test_fixture.hpp"
#include "core/image/test_fixture.hpp"

namespace gil = boost::gil;
namespace fixture = boost::gil::test::fixture;

struct test_copy_pixels
{
template <typename ImageLhs, typename ImageRhs>
void operator()(std::pair<ImageLhs, ImageRhs> const&)
{
using image_lhs_t = ImageLhs;
using image_rhs_t = ImageRhs;
using image_view_lhs_t = typename image_lhs_t::view_t;
using image_view_rhs_t = typename image_rhs_t::view_t;

{
// dynamic_image -> image
fixture::dynamic_image dyn_image_lhs(fixture::create_image<image_lhs_t>(2, 2, 128));
image_lhs_t image_lhs(2, 2);
image_rhs_t image_rhs(2, 2);

BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs), gil::view(image_lhs)));

if (gil::views_are_compatible<image_view_lhs_t, image_view_rhs_t>::value)
{
BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs), gil::view(image_rhs)));
}
else
{
BOOST_TEST_THROWS(gil::copy_pixels(gil::const_view(dyn_image_lhs), gil::view(image_rhs)), std::bad_cast);
}
}
{
// image -> dynamic_image
image_lhs_t image_lhs = fixture::create_image<image_lhs_t>(2, 2, 128);
image_rhs_t image_rhs = fixture::create_image<image_rhs_t>(2, 2, 128);
fixture::dynamic_image dyn_image_rhs(image_rhs_t(2, 2));

BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(image_rhs), gil::view(dyn_image_rhs)));

if (gil::views_are_compatible<image_view_lhs_t, image_view_rhs_t>::value)
{
BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(image_lhs), gil::view(dyn_image_rhs)));
}
else
{
BOOST_TEST_THROWS(gil::copy_pixels(gil::const_view(image_lhs), gil::view(dyn_image_rhs)), std::bad_cast);
}
}
{
// dynamic_image -> dynamic_image
fixture::dynamic_image dyn_image_lhs1(fixture::create_image<image_lhs_t>(2, 2, 128));
fixture::dynamic_image dyn_image_lhs2(image_lhs_t(2, 2));
fixture::dynamic_image dyn_image_rhs(image_rhs_t(2, 2));

BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_lhs2)));

if (gil::views_are_compatible<image_view_lhs_t, image_view_rhs_t>::value)
{
BOOST_TEST_NO_THROW(gil::copy_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_rhs)));
}
else
{
BOOST_TEST_THROWS(gil::copy_pixels(gil::const_view(dyn_image_lhs1), gil::view(dyn_image_rhs)), std::bad_cast);
}
}
}

static void run()
{
boost::mp11::mp_for_each
<
boost::mp11::mp_pairwise_fold
<
fixture::image_types, std::pair
>
>(test_copy_pixels{});
}
};

int main()
{
test_copy_pixels::run();

return ::boost::report_errors();
}
Loading

0 comments on commit 8cd1fc3

Please sign in to comment.