fix doc example typo
[boost.git] / boost / gil / iterator_from_2d.hpp
blob3c232b749a5d62cb8ddfa9d8c6179ca97f52343b
1 /*
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.
9 */
10 /*************************************************************************************************/
12 #ifndef GIL_ITERATOR_FROM_2D_H
13 #define GIL_ITERATOR_FROM_2D_H
15 ////////////////////////////////////////////////////////////////////////////////////////
16 /// \file
17 /// \brief pixel step iterator, pixel image iterator and pixel dereference iterator
18 /// \author Lubomir Bourdev and Hailin Jin \n
19 /// Adobe Systems Incorporated
20 /// \date 2005-2007 \n Last updated on September 18, 2007
21 ///
22 ////////////////////////////////////////////////////////////////////////////////////////
24 #include <cassert>
25 #include <boost/iterator/iterator_facade.hpp>
26 #include "gil_concept.hpp"
27 #include "gil_config.hpp"
28 #include "pixel_iterator.hpp"
29 #include "locator.hpp"
31 namespace boost { namespace gil {
33 ////////////////////////////////////////////////////////////////////////////////////////
34 ///
35 /// ITERATOR FROM 2D ADAPTOR
36 ///
37 ////////////////////////////////////////////////////////////////////////////////////////
40 /// \defgroup PixelIteratorModelFromLocator iterator_from_2d
41 /// \ingroup PixelIteratorModel
42 /// \brief An iterator over two-dimensional locator. Useful for iterating over the pixels of an image view. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
45 /// \ingroup PixelIteratorModelFromLocator PixelBasedModel
46 /// \brief Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
47 ///
48 /// Pixels are traversed from the top to the bottom row and from the left to the right
49 /// within each row
51 template <typename Loc2> // Models PixelLocatorConcept
52 class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
53 typename Loc2::value_type,
54 random_access_traversal_tag,
55 typename Loc2::reference,
56 typename Loc2::coord_t> {
57 GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
58 public:
59 typedef iterator_facade<iterator_from_2d<Loc2>,
60 typename Loc2::value_type,
61 random_access_traversal_tag,
62 typename Loc2::reference,
63 typename Loc2::coord_t> parent_t;
64 typedef typename parent_t::reference reference;
65 typedef typename parent_t::difference_type difference_type;
66 typedef typename Loc2::x_iterator x_iterator;
67 typedef typename Loc2::point_t point_t;
69 std::ptrdiff_t width() const { return _width; } // number of pixels per image row
70 std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
71 std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
73 /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
74 /// We require our own reference because it is registered in iterator_traits
75 reference operator[](difference_type d) const { return *(*this+d); }
77 bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
78 x_iterator& x() { return _p.x(); }
80 iterator_from_2d(){}
81 iterator_from_2d(const Loc2& p, std::ptrdiff_t width, std::ptrdiff_t x=0, std::ptrdiff_t y=0) : _coords(x,y), _width(width), _p(p) {}
82 iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
83 template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
85 private:
86 template <typename Loc> friend class iterator_from_2d;
87 friend class boost::iterator_core_access;
88 reference dereference() const { return *_p; }
89 void increment() {
90 ++_coords.x;
91 ++_p.x();
92 if (_coords.x>=_width) {
93 _coords.x=0;
94 ++_coords.y;
95 _p+=point_t(-_width,1);
98 void decrement() {
99 --_coords.x;
100 --_p.x();
101 if (_coords.x<0) {
102 _coords.x=_width-1;
103 --_coords.y;
104 _p+=point_t(_width,-1);
108 GIL_FORCEINLINE void advance(difference_type d) {
109 if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
110 point_t delta;
111 if (_coords.x+d>=0) { // not going back to a previous row?
112 delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
113 delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
114 } else {
115 delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
116 delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
118 _p+=delta;
119 _coords.x+=delta.x;
120 _coords.y+=delta.y;
123 difference_type distance_to(const iterator_from_2d& it) const {
124 if (_width==0) return 0;
125 return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
128 bool equal(const iterator_from_2d& it) const {
129 assert(_width==it.width()); // they must belong to the same image
130 return _coords==it._coords && _p==it._p;
133 point2<std::ptrdiff_t> _coords;
134 std::ptrdiff_t _width;
135 Loc2 _p;
138 template <typename Loc> // Models PixelLocatorConcept
139 struct const_iterator_type<iterator_from_2d<Loc> > {
140 typedef iterator_from_2d<typename Loc::const_t> type;
143 template <typename Loc> // Models PixelLocatorConcept
144 struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
147 /////////////////////////////
148 // HasDynamicXStepTypeConcept
149 /////////////////////////////
151 template <typename Loc>
152 struct dynamic_x_step_type<iterator_from_2d<Loc> > {
153 typedef iterator_from_2d<typename dynamic_x_step_type<Loc>::type> type;
157 /////////////////////////////
158 // PixelBasedConcept
159 /////////////////////////////
161 template <typename Loc> // Models PixelLocatorConcept
162 struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
164 template <typename Loc> // Models PixelLocatorConcept
165 struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
167 template <typename Loc> // Models PixelLocatorConcept
168 struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
170 template <typename Loc> // Models PixelLocatorConcept
171 struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
173 } } // namespace boost::gil
175 #endif