Skip to content

Commit

Permalink
Add move semantic to image
Browse files Browse the repository at this point in the history
  • Loading branch information
sdebionne committed Mar 26, 2020
1 parent bf709e6 commit c965b30
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
55 changes: 55 additions & 0 deletions include/boost/gil/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,19 @@ class image {
allocate_and_copy(img.dimensions(),img._view);
}

// TODO Optimization: use noexcept (requires _view to be nothrow copy constructible)
image(image&& img) :
_view(img._view),
_memory(img._memory),
_align_in_bytes(img._align_in_bytes),
_alloc(std::move(img._alloc)),
_allocated_bytes(img._allocated_bytes) {
img._view = view_t();
img._memory = nullptr;
img._align_in_bytes = 0;
img._allocated_bytes = 0;
}

image& operator=(const image& img) {
if (dimensions() == img.dimensions())
copy_pixels(img._view,_view);
Expand All @@ -122,6 +135,48 @@ class image {
return *this;
}

private:
using equal_allocators = std::true_type;
using no_propagate_allocators = std::false_type;

template <class Allocator>
// TODO: Use std::allocator_traits<Allocator>::is_always_equal if available
using move_policy = typename std::is_empty<Allocator>::type;

void move_assign(image& img, equal_allocators) {
destruct_pixels(_view);
deallocate();

// TODO Use std::exchange
_view = img._view;
_memory = img._memory;
_align_in_bytes = img._align_in_bytes;
_allocated_bytes = img._allocated_bytes;

img._view = view_t();
img._memory = nullptr;
img._align_in_bytes = 0;
img._allocated_bytes = 0;
}

void move_assign(image& img, no_propagate_allocators) {
if (_alloc == img._alloc) {
move_assign(img, equal_allocators{});
} else {
// Fallback to copy
image tmp(img);
swap(tmp);
}
}

public:
image& operator=(image&& img) {
if (this != std::addressof(img))
move_assign(img, move_policy<Alloc>{});

return *this;
}

~image() {
destruct_pixels(_view);
deallocate();
Expand Down
23 changes: 23 additions & 0 deletions test/core/image/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,26 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(constructor_with_dimensions_pixel, Image, fixture:
}
}
}

BOOST_AUTO_TEST_CASE_TEMPLATE(move_constructor, Image, fixture::image_types)
{
gil::point_t const dimensions{256, 128};
{
Image image(fixture::create_image<Image>(dimensions.x, dimensions.y, 0));

Image image2(std::move(image));
BOOST_CHECK_EQUAL(image2.dimensions(), dimensions);
BOOST_CHECK_EQUAL(image.dimensions(), gil::point_t{});
}
}

BOOST_AUTO_TEST_CASE_TEMPLATE(move_assignement, Image, fixture::image_types)
{
gil::point_t const dimensions{256, 128};
{
Image image = fixture::create_image<Image>(dimensions.x, dimensions.y, 0);
Image image2 = std::move(image);
BOOST_CHECK_EQUAL(image2.dimensions(), dimensions);
BOOST_CHECK_EQUAL(image.dimensions(), gil::point_t{});
}
}

0 comments on commit c965b30

Please sign in to comment.