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