]>
Commit | Line | Data |
---|---|---|
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_PIXEL_ITERATOR_ADAPTOR_HPP | |
9 | #define BOOST_GIL_PIXEL_ITERATOR_ADAPTOR_HPP | |
10 | ||
11 | #include <boost/gil/concepts.hpp> | |
12 | #include <boost/gil/pixel_iterator.hpp> | |
7c673cae | 13 | |
7c673cae | 14 | #include <boost/iterator/iterator_facade.hpp> |
7c673cae | 15 | |
92f5a8d4 | 16 | #include <iterator> |
7c673cae | 17 | |
92f5a8d4 | 18 | namespace boost { namespace gil { |
7c673cae FG |
19 | |
20 | /// \defgroup PixelIteratorModelDerefPtr dereference_iterator_adaptor | |
21 | /// \ingroup PixelIteratorModel | |
22 | /// \brief An iterator that invokes a provided function object upon dereference. Models: IteratorAdaptorConcept, PixelIteratorConcept | |
23 | ||
7c673cae FG |
24 | /// \ingroup PixelIteratorModelDerefPtr PixelBasedModel |
25 | /// \brief An adaptor over an existing iterator that provides for custom filter on dereferencing the object. Models: IteratorAdaptorConcept, PixelIteratorConcept | |
26 | ||
27 | template <typename Iterator, // Models Iterator | |
28 | typename DFn> // Models Returns the result of dereferencing a given iterator of type Iterator | |
29 | class dereference_iterator_adaptor : public iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>, | |
30 | Iterator, | |
31 | typename DFn::value_type, | |
32 | typename std::iterator_traits<Iterator>::iterator_category, | |
33 | typename DFn::reference, | |
34 | use_default> { | |
35 | DFn _deref_fn; | |
36 | public: | |
92f5a8d4 | 37 | using parent_t = iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>, |
7c673cae FG |
38 | Iterator, |
39 | typename DFn::value_type, | |
40 | typename std::iterator_traits<Iterator>::iterator_category, | |
41 | typename DFn::reference, | |
92f5a8d4 TL |
42 | use_default>; |
43 | using reference = typename DFn::result_type; | |
44 | using difference_type = typename std::iterator_traits<Iterator>::difference_type; | |
45 | using dereference_fn = DFn; | |
7c673cae FG |
46 | |
47 | dereference_iterator_adaptor() {} | |
92f5a8d4 | 48 | template <typename Iterator1> |
7c673cae FG |
49 | dereference_iterator_adaptor(const dereference_iterator_adaptor<Iterator1,DFn>& dit) : parent_t(dit.base()), _deref_fn(dit._deref_fn) {} |
50 | dereference_iterator_adaptor(Iterator it, DFn deref_fn=DFn()) : parent_t(it), _deref_fn(deref_fn) {} | |
92f5a8d4 | 51 | template <typename Iterator1, typename DFn1> |
7c673cae FG |
52 | dereference_iterator_adaptor(const dereference_iterator_adaptor<Iterator1,DFn1>& it) : parent_t(it.base()), _deref_fn(it._deref_fn) {} |
53 | /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference | |
54 | /// We require our own reference because it is registered in iterator_traits | |
55 | reference operator[](difference_type d) const { return *(*this+d);} | |
56 | ||
57 | // although iterator_adaptor defines these, the default implementation computes distance and compares for zero. | |
58 | // it is often faster to just apply the relation operator to the base | |
59 | bool operator> (const dereference_iterator_adaptor& p) const { return this->base_reference()> p.base_reference(); } | |
60 | bool operator< (const dereference_iterator_adaptor& p) const { return this->base_reference()< p.base_reference(); } | |
61 | bool operator>=(const dereference_iterator_adaptor& p) const { return this->base_reference()>=p.base_reference(); } | |
62 | bool operator<=(const dereference_iterator_adaptor& p) const { return this->base_reference()<=p.base_reference(); } | |
63 | bool operator==(const dereference_iterator_adaptor& p) const { return this->base_reference()==p.base_reference(); } | |
64 | bool operator!=(const dereference_iterator_adaptor& p) const { return this->base_reference()!=p.base_reference(); } | |
65 | ||
66 | Iterator& base() { return this->base_reference(); } | |
67 | const Iterator& base() const { return this->base_reference(); } | |
68 | const DFn& deref_fn() const { return _deref_fn; } | |
69 | private: | |
92f5a8d4 | 70 | template <typename Iterator1, typename DFn1> |
7c673cae FG |
71 | friend class dereference_iterator_adaptor; |
72 | friend class boost::iterator_core_access; | |
73 | ||
74 | reference dereference() const { return _deref_fn(*(this->base_reference())); } | |
75 | }; | |
76 | ||
92f5a8d4 TL |
77 | template <typename I, typename DFn> |
78 | struct const_iterator_type<dereference_iterator_adaptor<I,DFn> > { | |
79 | using type = dereference_iterator_adaptor<typename const_iterator_type<I>::type,typename DFn::const_t>; | |
7c673cae FG |
80 | }; |
81 | ||
92f5a8d4 TL |
82 | template <typename I, typename DFn> |
83 | struct iterator_is_mutable<dereference_iterator_adaptor<I, DFn>> | |
84 | : std::integral_constant<bool, DFn::is_mutable> | |
85 | {}; | |
7c673cae FG |
86 | |
87 | ||
88 | template <typename I, typename DFn> | |
92f5a8d4 | 89 | struct is_iterator_adaptor<dereference_iterator_adaptor<I, DFn>> : std::true_type {}; |
7c673cae FG |
90 | |
91 | template <typename I, typename DFn> | |
92f5a8d4 TL |
92 | struct iterator_adaptor_get_base<dereference_iterator_adaptor<I, DFn>> |
93 | { | |
94 | using type = I; | |
7c673cae FG |
95 | }; |
96 | ||
97 | template <typename I, typename DFn, typename NewBaseIterator> | |
98 | struct iterator_adaptor_rebind<dereference_iterator_adaptor<I,DFn>,NewBaseIterator> { | |
92f5a8d4 | 99 | using type = dereference_iterator_adaptor<NewBaseIterator,DFn>; |
7c673cae FG |
100 | }; |
101 | ||
102 | ///////////////////////////// | |
103 | // PixelBasedConcept | |
104 | ///////////////////////////// | |
105 | ||
106 | template <typename I, typename DFn> | |
107 | struct color_space_type<dereference_iterator_adaptor<I,DFn> > : public color_space_type<typename DFn::value_type> {}; | |
108 | ||
109 | template <typename I, typename DFn> | |
110 | struct channel_mapping_type<dereference_iterator_adaptor<I,DFn> > : public channel_mapping_type<typename DFn::value_type> {}; | |
111 | ||
112 | template <typename I, typename DFn> | |
113 | struct is_planar<dereference_iterator_adaptor<I,DFn> > : public is_planar<typename DFn::value_type> {}; | |
114 | ||
115 | template <typename I, typename DFn> | |
116 | struct channel_type<dereference_iterator_adaptor<I,DFn> > : public channel_type<typename DFn::value_type> {}; | |
117 | ||
118 | ||
119 | ///////////////////////////// | |
120 | // MemoryBasedIteratorConcept | |
121 | ///////////////////////////// | |
122 | ||
123 | template <typename Iterator, typename DFn> | |
124 | struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : public byte_to_memunit<Iterator> {}; | |
125 | ||
126 | template <typename Iterator, typename DFn> | |
92f5a8d4 TL |
127 | inline typename std::iterator_traits<Iterator>::difference_type |
128 | memunit_step(const dereference_iterator_adaptor<Iterator,DFn>& p) { | |
7c673cae FG |
129 | return memunit_step(p.base()); |
130 | } | |
131 | ||
132 | template <typename Iterator, typename DFn> | |
92f5a8d4 TL |
133 | inline typename std::iterator_traits<Iterator>::difference_type |
134 | memunit_distance(const dereference_iterator_adaptor<Iterator,DFn>& p1, | |
135 | const dereference_iterator_adaptor<Iterator,DFn>& p2) { | |
136 | return memunit_distance(p1.base(),p2.base()); | |
7c673cae FG |
137 | } |
138 | ||
139 | template <typename Iterator, typename DFn> | |
92f5a8d4 TL |
140 | inline void memunit_advance(dereference_iterator_adaptor<Iterator,DFn>& p, |
141 | typename std::iterator_traits<Iterator>::difference_type diff) { | |
7c673cae FG |
142 | memunit_advance(p.base(), diff); |
143 | } | |
144 | ||
145 | template <typename Iterator, typename DFn> | |
92f5a8d4 TL |
146 | inline dereference_iterator_adaptor<Iterator,DFn> |
147 | memunit_advanced(const dereference_iterator_adaptor<Iterator,DFn>& p, | |
148 | typename std::iterator_traits<Iterator>::difference_type diff) { | |
149 | return dereference_iterator_adaptor<Iterator,DFn>(memunit_advanced(p.base(), diff), p.deref_fn()); | |
7c673cae FG |
150 | } |
151 | ||
152 | ||
153 | template <typename Iterator, typename DFn> | |
92f5a8d4 TL |
154 | inline |
155 | typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference | |
156 | memunit_advanced_ref(const dereference_iterator_adaptor<Iterator,DFn>& p, | |
157 | typename std::iterator_traits<Iterator>::difference_type diff) { | |
7c673cae FG |
158 | return *memunit_advanced(p, diff); |
159 | } | |
160 | ||
161 | ///////////////////////////// | |
162 | // HasDynamicXStepTypeConcept | |
163 | ///////////////////////////// | |
164 | ||
165 | template <typename Iterator, typename DFn> | |
166 | struct dynamic_x_step_type<dereference_iterator_adaptor<Iterator,DFn> > { | |
92f5a8d4 | 167 | using type = dereference_iterator_adaptor<typename dynamic_x_step_type<Iterator>::type,DFn>; |
7c673cae FG |
168 | }; |
169 | ||
170 | /// \brief Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor upon dereferencing | |
171 | /// \ingroup PixelIteratorModelDerefPtr | |
172 | template <typename Iterator, typename Deref> | |
173 | struct iterator_add_deref { | |
174 | GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) | |
175 | ||
92f5a8d4 | 176 | using type = dereference_iterator_adaptor<Iterator, Deref>; |
7c673cae FG |
177 | |
178 | static type make(const Iterator& it, const Deref& d) { return type(it,d); } | |
179 | }; | |
180 | ||
181 | /// \ingroup PixelIteratorModelDerefPtr | |
182 | /// \brief For dereference iterator adaptors, compose the new function object after the old one | |
183 | template <typename Iterator, typename PREV_DEREF, typename Deref> | |
184 | struct iterator_add_deref<dereference_iterator_adaptor<Iterator, PREV_DEREF>,Deref> { | |
185 | // GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) | |
186 | ||
92f5a8d4 | 187 | using type = dereference_iterator_adaptor<Iterator, deref_compose<Deref,PREV_DEREF>>; |
7c673cae | 188 | |
92f5a8d4 TL |
189 | static type make(const dereference_iterator_adaptor<Iterator, PREV_DEREF>& it, const Deref& d) { |
190 | return type(it.base(),deref_compose<Deref,PREV_DEREF>(d,it.deref_fn())); | |
7c673cae FG |
191 | } |
192 | }; | |
193 | ||
92f5a8d4 | 194 | }} // namespace boost::gil |
7c673cae FG |
195 | |
196 | #endif |