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
31namespace 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
42template <typename Iterator, // Models Iterator
43 typename DFn> // Models Returns the result of dereferencing a given iterator of type Iterator
44class 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;
51public:
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; }
84private:
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
92template <typename I, typename DFn>
93struct 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
97template <typename I, typename DFn>
98struct iterator_is_mutable<dereference_iterator_adaptor<I,DFn> > : public mpl::bool_<DFn::is_mutable> {};
99
100
101template <typename I, typename DFn>
102struct is_iterator_adaptor<dereference_iterator_adaptor<I,DFn> > : public mpl::true_{};
103
104template <typename I, typename DFn>
105struct iterator_adaptor_get_base<dereference_iterator_adaptor<I,DFn> > {
106 typedef I type;
107};
108
109template <typename I, typename DFn, typename NewBaseIterator>
110struct iterator_adaptor_rebind<dereference_iterator_adaptor<I,DFn>,NewBaseIterator> {
111 typedef dereference_iterator_adaptor<NewBaseIterator,DFn> type;
112};
113
114/////////////////////////////
115// PixelBasedConcept
116/////////////////////////////
117
118template <typename I, typename DFn>
119struct color_space_type<dereference_iterator_adaptor<I,DFn> > : public color_space_type<typename DFn::value_type> {};
120
121template <typename I, typename DFn>
122struct channel_mapping_type<dereference_iterator_adaptor<I,DFn> > : public channel_mapping_type<typename DFn::value_type> {};
123
124template <typename I, typename DFn>
125struct is_planar<dereference_iterator_adaptor<I,DFn> > : public is_planar<typename DFn::value_type> {};
126
127template <typename I, typename DFn>
128struct channel_type<dereference_iterator_adaptor<I,DFn> > : public channel_type<typename DFn::value_type> {};
129
130
131/////////////////////////////
132// MemoryBasedIteratorConcept
133/////////////////////////////
134
135template <typename Iterator, typename DFn>
136struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : public byte_to_memunit<Iterator> {};
137
138template <typename Iterator, typename DFn>
139inline typename std::iterator_traits<Iterator>::difference_type
140memunit_step(const dereference_iterator_adaptor<Iterator,DFn>& p) {
141 return memunit_step(p.base());
142}
143
144template <typename Iterator, typename DFn>
145inline typename std::iterator_traits<Iterator>::difference_type
146memunit_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
151template <typename Iterator, typename DFn>
152inline 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
157template <typename Iterator, typename DFn>
158inline dereference_iterator_adaptor<Iterator,DFn>
159memunit_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
165template <typename Iterator, typename DFn>
166inline
167typename std::iterator_traits<dereference_iterator_adaptor<Iterator,DFn> >::reference
168memunit_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
177template <typename Iterator, typename DFn>
178struct 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
184template <typename Iterator, typename Deref>
185struct 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
195template <typename Iterator, typename PREV_DEREF, typename Deref>
196struct 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
209

source code of boost/boost/gil/pixel_iterator_adaptor.hpp