Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: replace Boost.Iterator with Boost.STLInterfaces #669

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ci/get-boost.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ git submodule --quiet update --init $GIT_SUBMODULE_OPTS \
libs/mp11 \
libs/mpl \
libs/preprocessor \
libs/stl_interfaces \
libs/type_traits \
libs/variant2
# Transitive (of GIL tests too)
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: install packages
run: |
sudo apt update
sudo apt install g++ libpng-dev libjpeg-dev libtiff5-dev libraw-dev lcov python -y
sudo apt install g++ libpng-dev libjpeg-dev libtiff5-dev libraw-dev lcov python-is-python3 -y

- name: Setup Boost
run: |
Expand Down
46 changes: 28 additions & 18 deletions example/interleaved_ptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include <type_traits>

#include <boost/stl_interfaces/iterator_interface.hpp>

#include "interleaved_ref.hpp"

// Example on how to create a pixel iterator
Expand All @@ -34,25 +36,25 @@ namespace boost { namespace gil {

template <typename ChannelPtr, // Models Channel Iterator (examples: unsigned char* or const unsigned char*)
typename Layout> // A layout (includes the color space and channel ordering)
struct interleaved_ptr : boost::iterator_facade
struct interleaved_ptr : stl_interfaces::iterator_interface
<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
interleaved_ptr<ChannelPtr, Layout>,
pixel<typename std::iterator_traits<ChannelPtr>::value_type, Layout>,
boost::random_access_traversal_tag,
#endif
std::random_access_iterator_tag,
pixel<typename std::iterator_traits<ChannelPtr>::value_type, Layout>,
interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference, Layout> const
>
{
private:
using parent_t = boost::iterator_facade
using parent_t = stl_interfaces::iterator_interface
<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
interleaved_ptr<ChannelPtr, Layout>,
#endif
std::random_access_iterator_tag,
pixel<typename std::iterator_traits<ChannelPtr>::value_type, Layout>,
boost::random_access_traversal_tag,
interleaved_ref
<
typename std::iterator_traits<ChannelPtr>::reference,
Layout
> const
interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference, Layout> const
>;

using channel_t = typename std::iterator_traits<ChannelPtr>::value_type;
Expand All @@ -61,6 +63,9 @@ struct interleaved_ptr : boost::iterator_facade
using reference = typename parent_t::reference;
using difference_type = typename parent_t::difference_type;

using parent_t::operator++;
using parent_t::operator--;

interleaved_ptr() {}
interleaved_ptr(const interleaved_ptr& ptr) : _channels(ptr._channels) {}
template <typename CP> interleaved_ptr(const interleaved_ptr<CP,Layout>& ptr) : _channels(ptr._channels) {}
Expand All @@ -71,24 +76,29 @@ struct interleaved_ptr : boost::iterator_facade
interleaved_ptr(reference* pix) : _channels(&((*pix)[0])) {}
interleaved_ptr& operator=(reference* pix) { _channels=&((*pix)[0]); return *this; }

/// For some reason operator[] provided by boost::iterator_facade returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}

// Put this for every iterator whose reference is a proxy type
reference operator->() const { return **this; }

// Channels accessor (not required by any concept)
const ChannelPtr& channels() const { return _channels; }
ChannelPtr& channels() { return _channels; }

// Not required by concepts but useful
static const std::size_t num_channels = mp11::mp_size<typename Layout::color_space_t>::value;

constexpr auto operator*() const noexcept { return dereference(); }

constexpr auto operator+=(difference_type d) -> interleaved_ptr& { advance(d); return *this; }

constexpr auto operator++() noexcept -> interleaved_ptr& { increment(); return *this; }
constexpr auto operator--() noexcept -> interleaved_ptr& { decrement(); return *this; }

constexpr auto operator-(interleaved_ptr other) const noexcept { return -distance_to(other); }

constexpr bool operator==(interleaved_ptr other) const noexcept { return equal(other); }

private:
ChannelPtr _channels;
friend class boost::iterator_core_access;
template <typename CP, typename L> friend struct interleaved_ptr;

friend struct boost::stl_interfaces::access;
void increment() { _channels+=num_channels; }
void decrement() { _channels-=num_channels; }
void advance(std::ptrdiff_t d) { _channels+=num_channels*d; }
Expand Down
6 changes: 5 additions & 1 deletion include/boost/gil/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ namespace detail {
/// \ingroup CopyPixels
template <typename I, typename O>
struct copier_n {
BOOST_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const { std::copy(src,src+n, dst); }
BOOST_FORCEINLINE void operator()(I src, typename std::iterator_traits<I>::difference_type n, O dst) const {
if (n < 0)
return;
std::copy(src, src + n, dst);
}
};

/// Source range is delimited by image iterators
Expand Down
50 changes: 30 additions & 20 deletions include/boost/gil/bit_aligned_pixel_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <boost/gil/pixel_iterator.hpp>

#include <boost/config.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/stl_interfaces/iterator_interface.hpp>

#include <functional>
#include <type_traits>
Expand All @@ -34,20 +34,31 @@ namespace boost { namespace gil {
/// \ingroup PixelIteratorNonAlignedPixelIterator PixelBasedModel

template <typename NonAlignedPixelReference>
struct bit_aligned_pixel_iterator : public iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
typename NonAlignedPixelReference::value_type,
std::random_access_iterator_tag,
const NonAlignedPixelReference,
typename NonAlignedPixelReference::bit_range_t::difference_type> {
class bit_aligned_pixel_iterator : public stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
bit_aligned_pixel_iterator<NonAlignedPixelReference>,
#endif
std::random_access_iterator_tag,
typename NonAlignedPixelReference::value_type,
const NonAlignedPixelReference,
typename NonAlignedPixelReference::value_type*,
typename NonAlignedPixelReference::bit_range_t::difference_type>
{
private:
using parent_t = iterator_facade<bit_aligned_pixel_iterator<NonAlignedPixelReference>,
typename NonAlignedPixelReference::value_type,
std::random_access_iterator_tag,
const NonAlignedPixelReference,
typename NonAlignedPixelReference::bit_range_t::difference_type>;
template <typename Ref> friend struct bit_aligned_pixel_iterator;
using parent_t = stl_interfaces::iterator_interface<
#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
bit_aligned_pixel_iterator<NonAlignedPixelReference>,
#endif
std::random_access_iterator_tag,
typename NonAlignedPixelReference::value_type,
const NonAlignedPixelReference,
typename NonAlignedPixelReference::value_type*,
typename NonAlignedPixelReference::bit_range_t::difference_type>;

template <typename Ref> friend class bit_aligned_pixel_iterator;

using bit_range_t = typename NonAlignedPixelReference::bit_range_t;

public:
using difference_type = typename parent_t::difference_type;
using reference = typename parent_t::reference;
Expand All @@ -61,21 +72,20 @@ struct bit_aligned_pixel_iterator : public iterator_facade<bit_aligned_pixel_ite
bit_aligned_pixel_iterator(reference* ref) : _bit_range(ref->bit_range()) {}
explicit bit_aligned_pixel_iterator(typename bit_range_t::byte_t* data, int bit_offset=0) : _bit_range(data,bit_offset) {}

/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
auto operator[](difference_type d) const -> reference { bit_aligned_pixel_iterator it=*this; it.advance(d); return *it; }
constexpr auto operator*() const noexcept -> reference { return dereference(); }

constexpr auto operator+=(difference_type i) noexcept -> bit_aligned_pixel_iterator& { advance(i); return *this; }

constexpr auto operator-(bit_aligned_pixel_iterator other) const noexcept { return -distance_to(other); }

auto operator->() const -> reference { return **this; }
auto bit_range() const -> bit_range_t const& { return _bit_range; }
auto bit_range() -> bit_range_t& { return _bit_range; }
auto bit_range() -> bit_range_t& { return _bit_range; }

private:
bit_range_t _bit_range;
static constexpr int bit_size = NonAlignedPixelReference::bit_size;

friend class boost::iterator_core_access;
auto dereference() const -> reference { return NonAlignedPixelReference(_bit_range); }
void increment() { ++_bit_range; }
void decrement() { --_bit_range; }
void advance(difference_type d) { _bit_range.bit_advance(d*bit_size); }

auto distance_to(bit_aligned_pixel_iterator const& it) const -> difference_type { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
Expand Down
16 changes: 8 additions & 8 deletions include/boost/gil/concepts/image_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ struct RandomAccessNDImageViewConcept
static const std::size_t N=View::num_dimensions;

gil_function_requires<RandomAccessNDLocatorConcept<locator>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator>>();
gil_function_requires<RandomAccessIterator<iterator>>();
gil_function_requires<RandomAccessIterator<reverse_iterator>>();

using first_it_type = typename View::template axis<0>::iterator;
using last_it_type = typename View::template axis<N-1>::iterator;
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
gil_function_requires<RandomAccessIterator<first_it_type>>();
gil_function_requires<RandomAccessIterator<last_it_type>>();

// static_assert(typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value, "");
// static_assert(typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value, "");
Expand Down Expand Up @@ -399,19 +399,19 @@ struct RandomAccessNDImageViewIsMutableConcept
{
gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator>>();

gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator>>();
gil_function_requires<Mutable_RandomAccessIterator<typename View::iterator>>();

gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
gil_function_requires<Mutable_RandomAccessIterator
<
typename View::reverse_iterator
>>();

gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
gil_function_requires<Mutable_RandomAccessIterator
<
typename View::template axis<0>::iterator
>>();

gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
gil_function_requires<Mutable_RandomAccessIterator
<
typename View::template axis<View::num_dimensions - 1>::iterator
>>();
Expand Down
Loading
Loading