Skip to content

Commit

Permalink
Add pmr image typedefs (#529)
Browse files Browse the repository at this point in the history
* Add pmr image typedefs

* Swap allocators only if it propagate on container

* Do not call propagate_on_container_swap for C++14

Co-authored-by: Mateusz Łoskot <mateusz@loskot.net>
  • Loading branch information
sdebionne and mloskot authored Jun 28, 2022
1 parent ef9b89a commit 4dbf35a
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 60 deletions.
7 changes: 7 additions & 0 deletions include/boost/gil/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,14 @@ class image
swap(_align_in_bytes, img._align_in_bytes);
swap(_memory, img._memory);
swap(_view, img._view);
#ifdef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
swap(_alloc, img._alloc);
#else
if constexpr (std::allocator_traits<Alloc>::propagate_on_container_swap::value)
swap(_alloc, img._alloc);
else
BOOST_ASSERT(_alloc == img._alloc);
#endif
swap(_allocated_bytes, img._allocated_bytes );
}

Expand Down
147 changes: 88 additions & 59 deletions include/boost/gil/typedefs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,71 +18,100 @@

#include <cstdint>
#include <memory>
#if !defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
# include <memory_resource>
#endif //!defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)

// B - bits size/signedness, CM - channel model, CS - colour space, LAYOUT - pixel layout
// Example: B = '8', CM = 'uint8_t', CS = 'bgr, LAYOUT='bgr_layout_t'
#define BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, LAYOUT) \
template <typename, typename> struct pixel; \
template <typename, typename> struct planar_pixel_reference; \
template <typename, typename> struct planar_pixel_iterator; \
template <typename> class memory_based_step_iterator; \
template <typename> class point; \
template <typename> class memory_based_2d_locator; \
template <typename> class image_view; \
template <typename, bool, typename> class image; \
using CS##B##_pixel_t = pixel<CM, LAYOUT>; \
using CS##B##c_pixel_t = pixel<CM, LAYOUT> const; \
using CS##B##_ref_t = pixel<CM, LAYOUT>&; \
using CS##B##c_ref_t = pixel<CM, LAYOUT> const&; \
using CS##B##_ptr_t = CS##B##_pixel_t*; \
using CS##B##c_ptr_t = CS##B##c_pixel_t*; \
using CS##B##_step_ptr_t = memory_based_step_iterator<CS##B##_ptr_t>; \
using CS##B##c_step_ptr_t = memory_based_step_iterator<CS##B##c_ptr_t>; \
using CS##B##_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_ptr_t>>; \
using CS##B##c_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_ptr_t>>; \
using CS##B##_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_step_ptr_t>>; \
using CS##B##c_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_step_ptr_t>>; \
using CS##B##_view_t = image_view<CS##B##_loc_t>; \
using CS##B##c_view_t = image_view<CS##B##c_loc_t>; \
using CS##B##_step_view_t = image_view<CS##B##_step_loc_t>; \
using CS##B##c_step_view_t = image_view<CS##B##c_step_loc_t>; \
#define BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, LAYOUT) \
template <typename, typename> \
struct pixel; \
template <typename, typename> \
struct planar_pixel_reference; \
template <typename, typename> \
struct planar_pixel_iterator; \
template <typename> \
class memory_based_step_iterator; \
template <typename> \
class point; \
template <typename> \
class memory_based_2d_locator; \
template <typename> \
class image_view; \
template <typename, bool, typename> \
class image; \
using CS##B##_pixel_t = pixel<CM, LAYOUT>; \
using CS##B##c_pixel_t = pixel<CM, LAYOUT> const; \
using CS##B##_ref_t = pixel<CM, LAYOUT>&; \
using CS##B##c_ref_t = pixel<CM, LAYOUT> const&; \
using CS##B##_ptr_t = CS##B##_pixel_t*; \
using CS##B##c_ptr_t = CS##B##c_pixel_t*; \
using CS##B##_step_ptr_t = memory_based_step_iterator<CS##B##_ptr_t>; \
using CS##B##c_step_ptr_t = memory_based_step_iterator<CS##B##c_ptr_t>; \
using CS##B##_loc_t = memory_based_2d_locator<memory_based_step_iterator<CS##B##_ptr_t>>; \
using CS##B##c_loc_t = memory_based_2d_locator<memory_based_step_iterator<CS##B##c_ptr_t>>; \
using CS##B##_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_step_ptr_t>>; \
using CS##B##c_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_step_ptr_t>>; \
using CS##B##_view_t = image_view<CS##B##_loc_t>; \
using CS##B##c_view_t = image_view<CS##B##c_loc_t>; \
using CS##B##_step_view_t = image_view<CS##B##_step_loc_t>; \
using CS##B##c_step_view_t = image_view<CS##B##c_step_loc_t>; \
using CS##B##_image_t = image<CS##B##_pixel_t, false, std::allocator<unsigned char>>;

// Example: B = '8', CM = 'uint8_t', CS = 'bgr' CS_FULL = 'rgb_t' LAYOUT='bgr_layout_t'
#define BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(B, CM, CS, CS_FULL, LAYOUT) \
BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, LAYOUT) \
using CS##B##_planar_ref_t = planar_pixel_reference<CM&, CS_FULL>; \
using CS##B##c_planar_ref_t = planar_pixel_reference<CM const&, CS_FULL>; \
using CS##B##_planar_ptr_t = planar_pixel_iterator<CM*, CS_FULL>; \
using CS##B##c_planar_ptr_t = planar_pixel_iterator<CM const*, CS_FULL>; \
using CS##B##_planar_step_ptr_t = memory_based_step_iterator<CS##B##_planar_ptr_t>; \
using CS##B##c_planar_step_ptr_t \
= memory_based_step_iterator<CS##B##c_planar_ptr_t>; \
using CS##B##_planar_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_planar_ptr_t>>; \
using CS##B##c_planar_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_planar_ptr_t>>; \
using CS##B##_planar_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_planar_step_ptr_t>>; \
using CS##B##c_planar_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_planar_step_ptr_t>>; \
using CS##B##_planar_view_t = image_view<CS##B##_planar_loc_t>; \
using CS##B##c_planar_view_t = image_view<CS##B##c_planar_loc_t>; \
using CS##B##_planar_step_view_t = image_view<CS##B##_planar_step_loc_t>; \
using CS##B##c_planar_step_view_t = image_view<CS##B##c_planar_step_loc_t>; \
using CS##B##_planar_image_t \
= image<CS##B##_pixel_t, true, std::allocator<unsigned char>>;

#define BOOST_GIL_DEFINE_BASE_TYPEDEFS(B, CM, CS) \
BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, CS##_layout_t)

#define BOOST_GIL_DEFINE_ALL_TYPEDEFS(B, CM, CS) \
BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(B, CM, CS, CS##_t, CS##_layout_t)
#define BOOST_GIL_DEFINE_BASE_PMR_TYPEDEFS_INTERNAL(B, CM, CS, LAYOUT) \
namespace pmr { \
using CS##B##_image_t \
= image<CS##B##_pixel_t, false, std::pmr::polymorphic_allocator<unsigned char>>; \
}

// Example: B = '8', CM = 'uint8_t', CS = 'bgr' CS_FULL = 'rgb_t' LAYOUT='bgr_layout_t'
#define BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(B, CM, CS, CS_FULL, LAYOUT) \
BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, LAYOUT) \
using CS##B##_planar_ref_t = planar_pixel_reference<CM&, CS_FULL>; \
using CS##B##c_planar_ref_t = planar_pixel_reference<CM const&, CS_FULL>; \
using CS##B##_planar_ptr_t = planar_pixel_iterator<CM*, CS_FULL>; \
using CS##B##c_planar_ptr_t = planar_pixel_iterator<CM const*, CS_FULL>; \
using CS##B##_planar_step_ptr_t = memory_based_step_iterator<CS##B##_planar_ptr_t>; \
using CS##B##c_planar_step_ptr_t = memory_based_step_iterator<CS##B##c_planar_ptr_t>; \
using CS##B##_planar_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_planar_ptr_t>>; \
using CS##B##c_planar_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_planar_ptr_t>>; \
using CS##B##_planar_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##_planar_step_ptr_t>>; \
using CS##B##c_planar_step_loc_t \
= memory_based_2d_locator<memory_based_step_iterator<CS##B##c_planar_step_ptr_t>>; \
using CS##B##_planar_view_t = image_view<CS##B##_planar_loc_t>; \
using CS##B##c_planar_view_t = image_view<CS##B##c_planar_loc_t>; \
using CS##B##_planar_step_view_t = image_view<CS##B##_planar_step_loc_t>; \
using CS##B##c_planar_step_view_t = image_view<CS##B##c_planar_step_loc_t>; \
using CS##B##_planar_image_t = image<CS##B##_pixel_t, true, std::allocator<unsigned char>>;

#define BOOST_GIL_DEFINE_ALL_PMR_TYPEDEFS_INTERNAL(B, CM, CS, CS_FULL, LAYOUT) \
BOOST_GIL_DEFINE_BASE_PMR_TYPEDEFS_INTERNAL(B, CM, CS, LAYOUT) \
namespace pmr { \
using CS##B##_planar_image_t \
= image<CS##B##_pixel_t, true, std::pmr::polymorphic_allocator<unsigned char>>; \
}

#if defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
# define BOOST_GIL_DEFINE_BASE_TYPEDEFS(B, CM, CS) \
BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, CS##_layout_t)

# define BOOST_GIL_DEFINE_ALL_TYPEDEFS(B, CM, CS) \
BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(B, CM, CS, CS##_t, CS##_layout_t)
#else
# define BOOST_GIL_DEFINE_BASE_TYPEDEFS(B, CM, CS) \
BOOST_GIL_DEFINE_BASE_TYPEDEFS_INTERNAL(B, CM, CS, CS##_layout_t) \
BOOST_GIL_DEFINE_BASE_PMR_TYPEDEFS_INTERNAL(B, CM, CS, CS##_layout_t)

# define BOOST_GIL_DEFINE_ALL_TYPEDEFS(B, CM, CS) \
BOOST_GIL_DEFINE_ALL_TYPEDEFS_INTERNAL(B, CM, CS, CS##_t, CS##_layout_t) \
BOOST_GIL_DEFINE_ALL_PMR_TYPEDEFS_INTERNAL(B, CM, CS, CS##_t, CS##_layout_t)
#endif //!defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)

namespace boost { namespace gil {

Expand Down
29 changes: 28 additions & 1 deletion test/core/image/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct test_constructor_with_dimensions_pixel
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(test_constructor_with_dimensions_pixel{});
boost::mp11::mp_for_each<fixture::pmr_image_types>(test_constructor_with_dimensions_pixel{});
}
};

Expand All @@ -44,12 +45,13 @@ struct test_constructor_from_other_image
void operator()(Image const &)
{
using image_t = Image;
using allocator_t = typename Image::allocator_type;
gil::point_t const dimensions{256, 128};
using pixel_t = typename image_t::view_t::value_type;
pixel_t const rnd_pixel = fixture::pixel_generator<pixel_t>::random();
{
//constructor interleaved from planar
gil::image<pixel_t, true> image1(dimensions, rnd_pixel);
gil::image<pixel_t, true, allocator_t> image1(dimensions, rnd_pixel);
image_t image2(image1);
BOOST_TEST_EQ(image2.dimensions(), dimensions);
auto v1 = gil::const_view(image1);
Expand Down Expand Up @@ -106,6 +108,27 @@ struct test_constructor_from_view
}
};

struct test_copy_assignement
{
template <typename Image>
void operator()(Image const&)
{
using image_t = Image;
gil::point_t const dimensions{ 256, 128 };
{
image_t image = fixture::create_image<image_t>(dimensions.x, dimensions.y, 0);
image_t image2;
image2 = image;
BOOST_TEST_EQ(image2.dimensions(), dimensions);
}
}
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(test_copy_assignement{});
boost::mp11::mp_for_each<fixture::pmr_image_types>(test_copy_assignement{});
}
};

struct test_move_constructor
{
template <typename Image>
Expand All @@ -124,6 +147,7 @@ struct test_move_constructor
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(test_move_constructor{});
boost::mp11::mp_for_each<fixture::pmr_image_types>(test_move_constructor{});
}
};

Expand All @@ -145,6 +169,7 @@ struct test_move_assignement
static void run()
{
boost::mp11::mp_for_each<fixture::image_types>(test_move_assignement{});
boost::mp11::mp_for_each<fixture::pmr_image_types>(test_move_assignement{});
}
};

Expand All @@ -154,6 +179,8 @@ int main()
test_constructor_from_other_image::run();
test_constructor_from_view::run();

test_copy_assignement::run();

test_move_constructor::run();
test_move_assignement::run();

Expand Down
20 changes: 20 additions & 0 deletions test/core/image/test_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ using image_types = std::tuple
gil::rgba32_image_t
>;

#if defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
using pmr_image_types = std::tuple<>;
#else
using pmr_image_types = std::tuple
<
gil::pmr::gray8_image_t,
gil::pmr::gray16_image_t,
gil::pmr::gray32_image_t,
gil::pmr::bgr8_image_t,
gil::pmr::bgr16_image_t,
gil::pmr::bgr32_image_t,
gil::pmr::rgb8_image_t,
gil::pmr::rgb16_image_t,
gil::pmr::rgb32_image_t,
gil::pmr::rgba8_image_t,
gil::pmr::rgba16_image_t,
gil::pmr::rgba32_image_t
>;
#endif //defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)

using rgb_interleaved_image_types = std::tuple
<
gil::bgr8_image_t,
Expand Down

0 comments on commit 4dbf35a

Please sign in to comment.