2 Copyright 2005-2007 Adobe Systems Incorporated
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).
8 See http://opensource.adobe.com/gil for most recent version including documentation.
11 /*************************************************************************************************/
13 #ifndef GIL_PIXEL_ITERATOR_ADAPTOR_H
14 #define GIL_PIXEL_ITERATOR_ADAPTOR_H
16 ////////////////////////////////////////////////////////////////////////////////////////
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
23 ////////////////////////////////////////////////////////////////////////////////////////
26 #include <boost/iterator/iterator_facade.hpp>
27 #include "gil_config.hpp"
28 #include "gil_concept.hpp"
29 #include "pixel_iterator.hpp"
31 namespace boost
{ namespace gil
{
34 /// \defgroup PixelIteratorModelDerefPtr dereference_iterator_adaptor
35 /// \ingroup PixelIteratorModel
36 /// \brief An iterator that invokes a provided function object upon dereference. Models: IteratorAdaptorConcept, PixelIteratorConcept
39 /// \ingroup PixelIteratorModelDerefPtr PixelBasedModel
40 /// \brief An adaptor over an existing iterator that provides for custom filter on dereferencing the object. Models: IteratorAdaptorConcept, PixelIteratorConcept
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
>,
46 typename
DFn::value_type
,
48 typename
DFn::reference
,
52 typedef iterator_adaptor
<dereference_iterator_adaptor
<Iterator
,DFn
>,
54 typename
DFn::value_type
,
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
;
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
);}
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(); }
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
; }
85 template <typename Iterator1
, typename DFn1
>
86 friend class dereference_iterator_adaptor
;
87 friend class boost::iterator_core_access
;
89 reference
dereference() const { return _deref_fn(*(this->base_reference())); }
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
;
97 template <typename I
, typename DFn
>
98 struct iterator_is_mutable
<dereference_iterator_adaptor
<I
,DFn
> > : public mpl::bool_
<DFn::is_mutable
> {};
101 template <typename I
, typename DFn
>
102 struct is_iterator_adaptor
<dereference_iterator_adaptor
<I
,DFn
> > : public mpl::true_
{};
104 template <typename I
, typename DFn
>
105 struct iterator_adaptor_get_base
<dereference_iterator_adaptor
<I
,DFn
> > {
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
;
114 /////////////////////////////
116 /////////////////////////////
118 template <typename I
, typename DFn
>
119 struct color_space_type
<dereference_iterator_adaptor
<I
,DFn
> > : public color_space_type
<typename
DFn::value_type
> {};
121 template <typename I
, typename DFn
>
122 struct channel_mapping_type
<dereference_iterator_adaptor
<I
,DFn
> > : public channel_mapping_type
<typename
DFn::value_type
> {};
124 template <typename I
, typename DFn
>
125 struct is_planar
<dereference_iterator_adaptor
<I
,DFn
> > : public is_planar
<typename
DFn::value_type
> {};
127 template <typename I
, typename DFn
>
128 struct channel_type
<dereference_iterator_adaptor
<I
,DFn
> > : public channel_type
<typename
DFn::value_type
> {};
131 /////////////////////////////
132 // MemoryBasedIteratorConcept
133 /////////////////////////////
135 template <typename Iterator
, typename DFn
>
136 struct byte_to_memunit
<dereference_iterator_adaptor
<Iterator
,DFn
> > : public byte_to_memunit
<Iterator
> {};
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());
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());
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
);
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());
165 template <typename Iterator
, typename DFn
>
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
);
173 /////////////////////////////
174 // HasDynamicXStepTypeConcept
175 /////////////////////////////
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
;
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
)
188 typedef dereference_iterator_adaptor
<Iterator
, Deref
> type
;
190 static type
make(const Iterator
& it
, const Deref
& d
) { return type(it
,d
); }
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)
199 typedef dereference_iterator_adaptor
<Iterator
, deref_compose
<Deref
,PREV_DEREF
> > type
;
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()));
206 } } // namespace boost::gil