Chris@16
|
1 /*
|
Chris@16
|
2 Copyright 2005-2007 Adobe Systems Incorporated
|
Chris@16
|
3
|
Chris@16
|
4 Use, modification and distribution are subject to the Boost Software License,
|
Chris@16
|
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
7
|
Chris@16
|
8 See http://opensource.adobe.com/gil for most recent version including documentation.
|
Chris@16
|
9 */
|
Chris@16
|
10
|
Chris@16
|
11 /*************************************************************************************************/
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef GIL_PIXEL_ITERATOR_ADAPTOR_H
|
Chris@16
|
14 #define GIL_PIXEL_ITERATOR_ADAPTOR_H
|
Chris@16
|
15
|
Chris@16
|
16 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
17 /// \file
|
Chris@16
|
18 /// \brief pixel step iterator, pixel image iterator and pixel dereference iterator
|
Chris@16
|
19 /// \author Lubomir Bourdev and Hailin Jin \n
|
Chris@16
|
20 /// Adobe Systems Incorporated
|
Chris@16
|
21 /// \date 2005-2007 \n Last updated on February 16, 2007
|
Chris@16
|
22 ///
|
Chris@16
|
23 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
24
|
Chris@16
|
25 #include <iterator>
|
Chris@16
|
26 #include <boost/iterator/iterator_facade.hpp>
|
Chris@16
|
27 #include "gil_config.hpp"
|
Chris@16
|
28 #include "gil_concept.hpp"
|
Chris@16
|
29 #include "pixel_iterator.hpp"
|
Chris@16
|
30
|
Chris@16
|
31 namespace boost { namespace gil {
|
Chris@16
|
32
|
Chris@16
|
33
|
Chris@16
|
34 /// \defgroup PixelIteratorModelDerefPtr dereference_iterator_adaptor
|
Chris@16
|
35 /// \ingroup PixelIteratorModel
|
Chris@16
|
36 /// \brief An iterator that invokes a provided function object upon dereference. Models: IteratorAdaptorConcept, PixelIteratorConcept
|
Chris@16
|
37
|
Chris@16
|
38
|
Chris@16
|
39 /// \ingroup PixelIteratorModelDerefPtr PixelBasedModel
|
Chris@16
|
40 /// \brief An adaptor over an existing iterator that provides for custom filter on dereferencing the object. Models: IteratorAdaptorConcept, PixelIteratorConcept
|
Chris@16
|
41
|
Chris@16
|
42 template <typename Iterator, // Models Iterator
|
Chris@16
|
43 typename DFn> // Models Returns the result of dereferencing a given iterator of type Iterator
|
Chris@16
|
44 class dereference_iterator_adaptor : public iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>,
|
Chris@16
|
45 Iterator,
|
Chris@16
|
46 typename DFn::value_type,
|
Chris@16
|
47 typename std::iterator_traits<Iterator>::iterator_category,
|
Chris@16
|
48 typename DFn::reference,
|
Chris@16
|
49 use_default> {
|
Chris@16
|
50 DFn _deref_fn;
|
Chris@16
|
51 public:
|
Chris@16
|
52 typedef iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>,
|
Chris@16
|
53 Iterator,
|
Chris@16
|
54 typename DFn::value_type,
|
Chris@16
|
55 typename std::iterator_traits<Iterator>::iterator_category,
|
Chris@16
|
56 typename DFn::reference,
|
Chris@16
|
57 use_default> parent_t;
|
Chris@16
|
58 typedef typename DFn::result_type reference;
|
Chris@16
|
59 typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
|
Chris@16
|
60 typedef DFn dereference_fn;
|
Chris@16
|
61
|
Chris@16
|
62 dereference_iterator_adaptor() {}
|
Chris@16
|
63 template <typename Iterator1>
|
Chris@16
|
64 dereference_iterator_adaptor(const dereference_iterator_adaptor<Iterator1,DFn>& dit) : parent_t(dit.base()), _deref_fn(dit._deref_fn) {}
|
Chris@16
|
65 dereference_iterator_adaptor(Iterator it, DFn deref_fn=DFn()) : parent_t(it), _deref_fn(deref_fn) {}
|
Chris@16
|
66 template <typename Iterator1, typename DFn1>
|
Chris@16
|
67 dereference_iterator_adaptor(const dereference_iterator_adaptor<Iterator1,DFn1>& it) : parent_t(it.base()), _deref_fn(it._deref_fn) {}
|
Chris@16
|
68 /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference
|
Chris@16
|
69 /// We require our own reference because it is registered in iterator_traits
|
Chris@16
|
70 reference operator[](difference_type d) const { return *(*this+d);}
|
Chris@16
|
71
|
Chris@16
|
72 // although iterator_adaptor defines these, the default implementation computes distance and compares for zero.
|
Chris@16
|
73 // it is often faster to just apply the relation operator to the base
|
Chris@16
|
74 bool operator> (const dereference_iterator_adaptor& p) const { return this->base_reference()> p.base_reference(); }
|
Chris@16
|
75 bool operator< (const dereference_iterator_adaptor& p) const { return this->base_reference()< p.base_reference(); }
|
Chris@16
|
76 bool operator>=(const dereference_iterator_adaptor& p) const { return this->base_reference()>=p.base_reference(); }
|
Chris@16
|
77 bool operator<=(const dereference_iterator_adaptor& p) const { return this->base_reference()<=p.base_reference(); }
|
Chris@16
|
78 bool operator==(const dereference_iterator_adaptor& p) const { return this->base_reference()==p.base_reference(); }
|
Chris@16
|
79 bool operator!=(const dereference_iterator_adaptor& p) const { return this->base_reference()!=p.base_reference(); }
|
Chris@16
|
80
|
Chris@16
|
81 Iterator& base() { return this->base_reference(); }
|
Chris@16
|
82 const Iterator& base() const { return this->base_reference(); }
|
Chris@16
|
83 const DFn& deref_fn() const { return _deref_fn; }
|
Chris@16
|
84 private:
|
Chris@16
|
85 template <typename Iterator1, typename DFn1>
|
Chris@16
|
86 friend class dereference_iterator_adaptor;
|
Chris@16
|
87 friend class boost::iterator_core_access;
|
Chris@16
|
88
|
Chris@16
|
89 reference dereference() const { return _deref_fn(*(this->base_reference())); }
|
Chris@16
|
90 };
|
Chris@16
|
91
|
Chris@16
|
92 template <typename I, typename DFn>
|
Chris@16
|
93 struct const_iterator_type<dereference_iterator_adaptor<I,DFn> > {
|
Chris@16
|
94 typedef dereference_iterator_adaptor<typename const_iterator_type<I>::type,typename DFn::const_t> type;
|
Chris@16
|
95 };
|
Chris@16
|
96
|
Chris@16
|
97 template <typename I, typename DFn>
|
Chris@16
|
98 struct iterator_is_mutable<dereference_iterator_adaptor<I,DFn> > : public mpl::bool_<DFn::is_mutable> {};
|
Chris@16
|
99
|
Chris@16
|
100
|
Chris@16
|
101 template <typename I, typename DFn>
|
Chris@16
|
102 struct is_iterator_adaptor<dereference_iterator_adaptor<I,DFn> > : public mpl::true_{};
|
Chris@16
|
103
|
Chris@16
|
104 template <typename I, typename DFn>
|
Chris@16
|
105 struct iterator_adaptor_get_base<dereference_iterator_adaptor<I,DFn> > {
|
Chris@16
|
106 typedef I type;
|
Chris@16
|
107 };
|
Chris@16
|
108
|
Chris@16
|
109 template <typename I, typename DFn, typename NewBaseIterator>
|
Chris@16
|
110 struct iterator_adaptor_rebind<dereference_iterator_adaptor<I,DFn>,NewBaseIterator> {
|
Chris@16
|
111 typedef dereference_iterator_adaptor<NewBaseIterator,DFn> type;
|
Chris@16
|
112 };
|
Chris@16
|
113
|
Chris@16
|
114 /////////////////////////////
|
Chris@16
|
115 // PixelBasedConcept
|
Chris@16
|
116 /////////////////////////////
|
Chris@16
|
117
|
Chris@16
|
118 template <typename I, typename DFn>
|
Chris@16
|
119 struct color_space_type<dereference_iterator_adaptor<I,DFn> > : public color_space_type<typename DFn::value_type> {};
|
Chris@16
|
120
|
Chris@16
|
121 template <typename I, typename DFn>
|
Chris@16
|
122 struct channel_mapping_type<dereference_iterator_adaptor<I,DFn> > : public channel_mapping_type<typename DFn::value_type> {};
|
Chris@16
|
123
|
Chris@16
|
124 template <typename I, typename DFn>
|
Chris@16
|
125 struct is_planar<dereference_iterator_adaptor<I,DFn> > : public is_planar<typename DFn::value_type> {};
|
Chris@16
|
126
|
Chris@16
|
127 template <typename I, typename DFn>
|
Chris@16
|
128 struct channel_type<dereference_iterator_adaptor<I,DFn> > : public channel_type<typename DFn::value_type> {};
|
Chris@16
|
129
|
Chris@16
|
130
|
Chris@16
|
131 /////////////////////////////
|
Chris@16
|
132 // MemoryBasedIteratorConcept
|
Chris@16
|
133 /////////////////////////////
|
Chris@16
|
134
|
Chris@16
|
135 template <typename Iterator, typename DFn>
|
Chris@16
|
136 struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : public byte_to_memunit<Iterator> {};
|
Chris@16
|
137
|
Chris@16
|
138 template <typename Iterator, typename DFn>
|
Chris@16
|
139 inline typename std::iterator_traits<Iterator>::difference_type
|
Chris@16
|
140 memunit_step(const dereference_iterator_adaptor<Iterator,DFn>& p) {
|
Chris@16
|
141 return memunit_step(p.base());
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 template <typename Iterator, typename DFn>
|
Chris@16
|
145 inline typename std::iterator_traits<Iterator>::difference_type
|
Chris@16
|
146 memunit_distance(const dereference_iterator_adaptor<Iterator,DFn>& p1,
|
Chris@16
|
147 const dereference_iterator_adaptor<Iterator,DFn>& p2) {
|
Chris@16
|
148 return memunit_distance(p1.base(),p2.base());
|
Chris@16
|
149 }
|
Chris@16
|
150
|
Chris@16
|
151 template <typename Iterator, typename DFn>
|
Chris@16
|
152 inline void memunit_advance(dereference_iterator_adaptor<Iterator,DFn>& p,
|
Chris@16
|
153 typename std::iterator_traits<Iterator>::difference_type diff) {
|
Chris@16
|
154 memunit_advance(p.base(), diff);
|
Chris@16
|
155 }
|
Chris@16
|
156
|
Chris@16
|
157 template <typename Iterator, typename DFn>
|
Chris@16
|
158 inline dereference_iterator_adaptor<Iterator,DFn>
|
Chris@16
|
159 memunit_advanced(const dereference_iterator_adaptor<Iterator,DFn>& p,
|
Chris@16
|
160 typename std::iterator_traits<Iterator>::difference_type diff) {
|
Chris@16
|
161 return dereference_iterator_adaptor<Iterator,DFn>(memunit_advanced(p.base(), diff), p.deref_fn());
|
Chris@16
|
162 }
|
Chris@16
|
163
|
Chris@16
|
164
|
Chris@16
|
165 template <typename Iterator, typename DFn>
|
Chris@16
|
166 inline
|
Chris@16
|
167 typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference
|
Chris@16
|
168 memunit_advanced_ref(const dereference_iterator_adaptor<Iterator,DFn>& p,
|
Chris@16
|
169 typename std::iterator_traits<Iterator>::difference_type diff) {
|
Chris@16
|
170 return *memunit_advanced(p, diff);
|
Chris@16
|
171 }
|
Chris@16
|
172
|
Chris@16
|
173 /////////////////////////////
|
Chris@16
|
174 // HasDynamicXStepTypeConcept
|
Chris@16
|
175 /////////////////////////////
|
Chris@16
|
176
|
Chris@16
|
177 template <typename Iterator, typename DFn>
|
Chris@16
|
178 struct dynamic_x_step_type<dereference_iterator_adaptor<Iterator,DFn> > {
|
Chris@16
|
179 typedef dereference_iterator_adaptor<typename dynamic_x_step_type<Iterator>::type,DFn> type;
|
Chris@16
|
180 };
|
Chris@16
|
181
|
Chris@16
|
182 /// \brief Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor upon dereferencing
|
Chris@16
|
183 /// \ingroup PixelIteratorModelDerefPtr
|
Chris@16
|
184 template <typename Iterator, typename Deref>
|
Chris@16
|
185 struct iterator_add_deref {
|
Chris@16
|
186 GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
|
Chris@16
|
187
|
Chris@16
|
188 typedef dereference_iterator_adaptor<Iterator, Deref> type;
|
Chris@16
|
189
|
Chris@16
|
190 static type make(const Iterator& it, const Deref& d) { return type(it,d); }
|
Chris@16
|
191 };
|
Chris@16
|
192
|
Chris@16
|
193 /// \ingroup PixelIteratorModelDerefPtr
|
Chris@16
|
194 /// \brief For dereference iterator adaptors, compose the new function object after the old one
|
Chris@16
|
195 template <typename Iterator, typename PREV_DEREF, typename Deref>
|
Chris@16
|
196 struct iterator_add_deref<dereference_iterator_adaptor<Iterator, PREV_DEREF>,Deref> {
|
Chris@16
|
197 // GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
|
Chris@16
|
198
|
Chris@16
|
199 typedef dereference_iterator_adaptor<Iterator, deref_compose<Deref,PREV_DEREF> > type;
|
Chris@16
|
200
|
Chris@16
|
201 static type make(const dereference_iterator_adaptor<Iterator, PREV_DEREF>& it, const Deref& d) {
|
Chris@16
|
202 return type(it.base(),deref_compose<Deref,PREV_DEREF>(d,it.deref_fn()));
|
Chris@16
|
203 }
|
Chris@16
|
204 };
|
Chris@16
|
205
|
Chris@16
|
206 } } // namespace boost::gil
|
Chris@16
|
207
|
Chris@16
|
208 #endif
|