]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/gil/example/interleaved_ptr.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / gil / example / interleaved_ptr.hpp
CommitLineData
92f5a8d4
TL
1//
2// Copyright 2005-2007 Adobe Systems Incorporated
3//
4// Distributed under the Boost Software License, Version 1.0
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7//
8#ifndef BOOST_GIL_EXAMPLE_INTERLEAVED_PTR_HPP
9#define BOOST_GIL_EXAMPLE_INTERLEAVED_PTR_HPP
10
11#include <boost/gil.hpp>
12#include <boost/mp11.hpp>
13
14#include <type_traits>
15
7c673cae
FG
16#include "interleaved_ref.hpp"
17
92f5a8d4
TL
18// Example on how to create a pixel iterator
19
7c673cae
FG
20namespace boost { namespace gil {
21
92f5a8d4
TL
22// A model of an interleaved pixel iterator. Contains an iterator to the first channel of the current pixel
23//
24// Models:
25// MutablePixelIteratorConcept
26// PixelIteratorConcept
27// boost_concepts::RandomAccessTraversalConcept
28// PixelBasedConcept
29// HomogeneousPixelBasedConcept
30// PixelBasedConcept
31// ByteAdvanceableConcept
32// HasDynamicXStepTypeConcept
7c673cae
FG
33
34template <typename ChannelPtr, // Models Channel Iterator (examples: unsigned char* or const unsigned char*)
35 typename Layout> // A layout (includes the color space and channel ordering)
92f5a8d4
TL
36struct interleaved_ptr : boost::iterator_facade
37 <
38 interleaved_ptr<ChannelPtr, Layout>,
39 pixel<typename std::iterator_traits<ChannelPtr>::value_type, Layout>,
40 boost::random_access_traversal_tag,
41 interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference, Layout> const
42 >
7c673cae
FG
43{
44private:
92f5a8d4
TL
45 using parent_t = boost::iterator_facade
46 <
47 interleaved_ptr<ChannelPtr, Layout>,
48 pixel<typename std::iterator_traits<ChannelPtr>::value_type, Layout>,
49 boost::random_access_traversal_tag,
50 interleaved_ref
51 <
52 typename std::iterator_traits<ChannelPtr>::reference,
53 Layout
54 > const
55 >;
56
57 using channel_t = typename std::iterator_traits<ChannelPtr>::value_type;
58
7c673cae 59public:
92f5a8d4
TL
60 using reference = typename parent_t::reference;
61 using difference_type = typename parent_t::difference_type;
7c673cae
FG
62
63 interleaved_ptr() {}
64 interleaved_ptr(const interleaved_ptr& ptr) : _channels(ptr._channels) {}
65 template <typename CP> interleaved_ptr(const interleaved_ptr<CP,Layout>& ptr) : _channels(ptr._channels) {}
66
67 interleaved_ptr(const ChannelPtr& channels) : _channels(channels) {}
68
69 // Construct from a pointer to the reference type. Not required by concepts but important
70 interleaved_ptr(reference* pix) : _channels(&((*pix)[0])) {}
71 interleaved_ptr& operator=(reference* pix) { _channels=&((*pix)[0]); return *this; }
72
73 /// For some reason operator[] provided by boost::iterator_facade returns a custom class that is convertible to reference
74 /// We require our own reference because it is registered in iterator_traits
75 reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
76
77 // Put this for every iterator whose reference is a proxy type
78 reference operator->() const { return **this; }
79
80 // Channels accessor (not required by any concept)
81 const ChannelPtr& channels() const { return _channels; }
82 ChannelPtr& channels() { return _channels; }
92f5a8d4 83
7c673cae 84 // Not required by concepts but useful
92f5a8d4 85 static const std::size_t num_channels = mp11::mp_size<typename Layout::color_space_t>::value;
7c673cae
FG
86private:
87 ChannelPtr _channels;
88 friend class boost::iterator_core_access;
89 template <typename CP, typename L> friend struct interleaved_ptr;
90
91 void increment() { _channels+=num_channels; }
92 void decrement() { _channels-=num_channels; }
92f5a8d4 93 void advance(std::ptrdiff_t d) { _channels+=num_channels*d; }
7c673cae 94
92f5a8d4 95 std::ptrdiff_t distance_to(const interleaved_ptr& it) const { return (it._channels-_channels)/num_channels; }
7c673cae
FG
96 bool equal(const interleaved_ptr& it) const { return _channels==it._channels; }
97
98 reference dereference() const { return reference(_channels); }
99};
100
101/////////////////////////////
102// PixelIteratorConcept
103/////////////////////////////
104
105// To get from the channel pointer a channel pointer to const, we have to go through the channel traits, which take a model of channel
106// So we can get a model of channel from the channel pointer via iterator_traits. Notice that we take the iterator_traits::reference and not
107// iterator_traits::value_type. This is because sometimes multiple reference and pointer types share the same value type. An example of this is
108// GIL's planar reference and iterator ("planar_pixel_reference" and "planar_pixel_iterator") which share the class "pixel" as the value_type. The
109// class "pixel" is also the value type for interleaved pixel references. Here we are dealing with channels, not pixels, but the principles still apply.
110template <typename ChannelPtr, typename Layout>
92f5a8d4 111struct const_iterator_type<interleaved_ptr<ChannelPtr,Layout>> {
7c673cae 112private:
92f5a8d4
TL
113 using channel_ref_t = typename std::iterator_traits<ChannelPtr>::reference;
114 using channel_const_ptr_t = typename channel_traits<channel_ref_t>::const_pointer;
7c673cae 115public:
92f5a8d4 116 using type = interleaved_ptr<channel_const_ptr_t, Layout>;
7c673cae
FG
117};
118
119template <typename ChannelPtr, typename Layout>
92f5a8d4 120struct iterator_is_mutable<interleaved_ptr<ChannelPtr,Layout>> : std::true_type {};
7c673cae 121template <typename Channel, typename Layout>
92f5a8d4 122struct iterator_is_mutable<interleaved_ptr<const Channel*,Layout>> : std::false_type {};
7c673cae
FG
123
124template <typename ChannelPtr, typename Layout>
92f5a8d4 125struct is_iterator_adaptor<interleaved_ptr<ChannelPtr,Layout>> : std::false_type {};
7c673cae
FG
126
127/////////////////////////////
128// PixelBasedConcept
129/////////////////////////////
130
131template <typename ChannelPtr, typename Layout>
92f5a8d4
TL
132struct color_space_type<interleaved_ptr<ChannelPtr,Layout>>
133{
134 using type = typename Layout::color_space_t;
7c673cae
FG
135};
136
137template <typename ChannelPtr, typename Layout>
92f5a8d4
TL
138struct channel_mapping_type<interleaved_ptr<ChannelPtr,Layout>>
139{
140 using type = typename Layout::channel_mapping_t;
7c673cae
FG
141};
142
143template <typename ChannelPtr, typename Layout>
92f5a8d4 144struct is_planar<interleaved_ptr<ChannelPtr,Layout>> : std::false_type {};
7c673cae
FG
145
146/////////////////////////////
147// HomogeneousPixelBasedConcept
148/////////////////////////////
149
150template <typename ChannelPtr, typename Layout>
92f5a8d4
TL
151struct channel_type<interleaved_ptr<ChannelPtr, Layout>>
152{
153 using type = typename std::iterator_traits<ChannelPtr>::value_type;
7c673cae
FG
154};
155
156/////////////////////////////
157// ByteAdvanceableConcept
158/////////////////////////////
159
160template <typename ChannelPtr, typename Layout>
92f5a8d4 161inline std::ptrdiff_t memunit_step(const interleaved_ptr<ChannelPtr,Layout>&) {
7c673cae
FG
162 return sizeof(typename std::iterator_traits<ChannelPtr>::value_type)* // size of each channel in bytes
163 interleaved_ptr<ChannelPtr,Layout>::num_channels; // times the number of channels
164}
165
166template <typename ChannelPtr, typename Layout>
92f5a8d4
TL
167inline std::ptrdiff_t memunit_distance(const interleaved_ptr<ChannelPtr,Layout>& p1, const interleaved_ptr<ChannelPtr,Layout>& p2) {
168 return memunit_distance(p1.channels(),p2.channels());
7c673cae
FG
169}
170
171template <typename ChannelPtr, typename Layout>
92f5a8d4 172inline void memunit_advance(interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
7c673cae
FG
173 memunit_advance(p.channels(), diff);
174}
175
176template <typename ChannelPtr, typename Layout>
177inline interleaved_ptr<ChannelPtr,Layout> memunit_advanced(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
178 interleaved_ptr<ChannelPtr,Layout> ret=p;
179 memunit_advance(ret, diff);
180 return ret;
181}
182
183template <typename ChannelPtr, typename Layout>
184inline typename interleaved_ptr<ChannelPtr,Layout>::reference memunit_advanced_ref(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
185 interleaved_ptr<ChannelPtr,Layout> ret=p;
186 memunit_advance(ret, diff);
187 return *ret;
188}
189
190/////////////////////////////
191// HasDynamicXStepTypeConcept
192/////////////////////////////
193
194template <typename ChannelPtr, typename Layout>
92f5a8d4
TL
195struct dynamic_x_step_type<interleaved_ptr<ChannelPtr, Layout>>
196{
197 using type = memory_based_step_iterator<interleaved_ptr<ChannelPtr, Layout>>;
7c673cae 198};
7c673cae
FG
199} } // namespace boost::gil
200
201#endif