/usr/include/boost/gil/step_iterator.hpp is in libboost1.55-dev 1.55.0+dfsg-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | /*
Copyright 2005-2007 Adobe Systems Incorporated
Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
See http://opensource.adobe.com/gil for most recent version including documentation.
*/
/*************************************************************************************************/
#ifndef GIL_STEP_ITERATOR_H
#define GIL_STEP_ITERATOR_H
////////////////////////////////////////////////////////////////////////////////////////
/// \file
/// \brief pixel step iterator
/// \author Lubomir Bourdev and Hailin Jin \n
/// Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on September 18, 2007
///
////////////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>
#include "gil_config.hpp"
#include "utilities.hpp"
#include "pixel_iterator.hpp"
#include "pixel_iterator_adaptor.hpp"
namespace boost { namespace gil {
/// \defgroup PixelIteratorModelStepPtr step iterators
/// \ingroup PixelIteratorModel
/// \brief Iterators that allow for specifying the step between two adjacent values
namespace detail {
/// \ingroup PixelIteratorModelStepPtr
/// \brief An adaptor over an existing iterator that changes the step unit
///
/// (i.e. distance(it,it+1)) by a given predicate. Instead of calling base's
/// operators ++, --, +=, -=, etc. the adaptor is using the passed policy object SFn
/// for advancing and for computing the distance between iterators.
template <typename Derived, // type of the derived class
typename Iterator, // Models Iterator
typename SFn> // A policy object that can compute the distance between two iterators of type Iterator
// and can advance an iterator of type Iterator a given number of Iterator's units
class step_iterator_adaptor : public iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type> {
public:
typedef iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type> parent_t;
typedef typename std::iterator_traits<Iterator>::difference_type base_difference_type;
typedef typename SFn::difference_type difference_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
step_iterator_adaptor() {}
step_iterator_adaptor(const Iterator& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {}
difference_type step() const { return _step_fn.step(); }
protected:
SFn _step_fn;
private:
friend class boost::iterator_core_access;
void increment() { _step_fn.advance(this->base_reference(),1); }
void decrement() { _step_fn.advance(this->base_reference(),-1); }
void advance(base_difference_type d) { _step_fn.advance(this->base_reference(),d); }
difference_type distance_to(const step_iterator_adaptor& it) const { return _step_fn.difference(this->base_reference(),it.base_reference()); }
};
// although iterator_adaptor defines these, the default implementation computes distance and compares for zero.
// it is often faster to just apply the relation operator to the base
template <typename D,typename Iterator,typename SFn> inline
bool operator>(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()> p2.base() : p1.base()< p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator<(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()< p2.base() : p1.base()> p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator>=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()>=p2.base() : p1.base()<=p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator<=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.step()>0 ? p1.base()<=p2.base() : p1.base()>=p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator==(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.base()==p2.base();
}
template <typename D,typename Iterator,typename SFn> inline
bool operator!=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
return p1.base()!=p2.base();
}
} // namespace detail
////////////////////////////////////////////////////////////////////////////////////////
/// MEMORY-BASED STEP ITERATOR
////////////////////////////////////////////////////////////////////////////////////////
/// \class memory_based_step_iterator
/// \ingroup PixelIteratorModelStepPtr PixelBasedModel
/// \brief Iterator with dynamically specified step in memory units (bytes or bits). Models StepIteratorConcept, IteratorAdaptorConcept, MemoryBasedIteratorConcept, PixelIteratorConcept, HasDynamicXStepTypeConcept
///
/// A refinement of step_iterator_adaptor that uses a dynamic parameter for the step
/// which is specified in memory units, such as bytes or bits
///
/// Pixel step iterators are used to provide iteration over non-adjacent pixels.
/// Common use is a vertical traversal, where the step is the row stride.
///
/// Another application is as a sub-channel view. For example, a red intensity image over
/// interleaved RGB data would use a step iterator adaptor with step sizeof(channel_t)*3
/// In the latter example the step size could be fixed at compile time for efficiency.
/// Compile-time fixed step can be implemented by providing a step function object that takes the step as a template
////////////////////////////////////////////////////////////////////////////////////////
/// \ingroup PixelIteratorModelStepPtr
/// \brief function object that returns the memory unit distance between two iterators and advances a given iterator a given number of mem units (bytes or bits)
template <typename Iterator>
struct memunit_step_fn {
typedef std::ptrdiff_t difference_type;
memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {}
difference_type difference(const Iterator& it1, const Iterator& it2) const { return memunit_distance(it1,it2)/_step; }
void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); }
difference_type step() const { return _step; }
void set_step(std::ptrdiff_t step) { _step=step; }
private:
GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
difference_type _step;
};
template <typename Iterator>
class memory_based_step_iterator : public detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
Iterator,
memunit_step_fn<Iterator> > {
GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
public:
typedef detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
Iterator,
memunit_step_fn<Iterator> > parent_t;
typedef typename parent_t::reference reference;
typedef typename parent_t::difference_type difference_type;
typedef Iterator x_iterator;
memory_based_step_iterator() : parent_t(Iterator()) {}
memory_based_step_iterator(Iterator it, std::ptrdiff_t memunit_step) : parent_t(it, memunit_step_fn<Iterator>(memunit_step)) {}
template <typename I2>
memory_based_step_iterator(const memory_based_step_iterator<I2>& it)
: parent_t(it.base(), memunit_step_fn<Iterator>(it.step())) {}
/// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
/// We require our own reference because it is registered in iterator_traits
reference operator[](difference_type d) const { return *(*this+d); }
void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); }
x_iterator& base() { return parent_t::base_reference(); }
x_iterator const& base() const { return parent_t::base_reference(); }
};
template <typename Iterator>
struct const_iterator_type<memory_based_step_iterator<Iterator> > {
typedef memory_based_step_iterator<typename const_iterator_type<Iterator>::type> type;
};
template <typename Iterator>
struct iterator_is_mutable<memory_based_step_iterator<Iterator> > : public iterator_is_mutable<Iterator> {};
/////////////////////////////
// IteratorAdaptorConcept
/////////////////////////////
template <typename Iterator>
struct is_iterator_adaptor<memory_based_step_iterator<Iterator> > : public mpl::true_{};
template <typename Iterator>
struct iterator_adaptor_get_base<memory_based_step_iterator<Iterator> > {
typedef Iterator type;
};
template <typename Iterator, typename NewBaseIterator>
struct iterator_adaptor_rebind<memory_based_step_iterator<Iterator>,NewBaseIterator> {
typedef memory_based_step_iterator<NewBaseIterator> type;
};
/////////////////////////////
// PixelBasedConcept
/////////////////////////////
template <typename Iterator>
struct color_space_type<memory_based_step_iterator<Iterator> > : public color_space_type<Iterator> {};
template <typename Iterator>
struct channel_mapping_type<memory_based_step_iterator<Iterator> > : public channel_mapping_type<Iterator> {};
template <typename Iterator>
struct is_planar<memory_based_step_iterator<Iterator> > : public is_planar<Iterator> {};
template <typename Iterator>
struct channel_type<memory_based_step_iterator<Iterator> > : public channel_type<Iterator> {};
/////////////////////////////
// MemoryBasedIteratorConcept
/////////////////////////////
template <typename Iterator>
struct byte_to_memunit<memory_based_step_iterator<Iterator> > : public byte_to_memunit<Iterator> {};
template <typename Iterator>
inline std::ptrdiff_t memunit_step(const memory_based_step_iterator<Iterator>& p) { return p.step(); }
template <typename Iterator>
inline std::ptrdiff_t memunit_distance(const memory_based_step_iterator<Iterator>& p1,
const memory_based_step_iterator<Iterator>& p2) {
return memunit_distance(p1.base(),p2.base());
}
template <typename Iterator>
inline void memunit_advance(memory_based_step_iterator<Iterator>& p,
std::ptrdiff_t diff) {
memunit_advance(p.base(), diff);
}
template <typename Iterator>
inline memory_based_step_iterator<Iterator>
memunit_advanced(const memory_based_step_iterator<Iterator>& p,
std::ptrdiff_t diff) {
return memory_based_step_iterator<Iterator>(memunit_advanced(p.base(), diff),p.step());
}
template <typename Iterator>
inline typename std::iterator_traits<Iterator>::reference
memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p,
std::ptrdiff_t diff) {
return memunit_advanced_ref(p.base(), diff);
}
/////////////////////////////
// HasDynamicXStepTypeConcept
/////////////////////////////
template <typename Iterator>
struct dynamic_x_step_type<memory_based_step_iterator<Iterator> > {
typedef memory_based_step_iterator<Iterator> type;
};
// For step iterators, pass the function object to the base
template <typename Iterator, typename Deref>
struct iterator_add_deref<memory_based_step_iterator<Iterator>,Deref> {
GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
typedef memory_based_step_iterator<typename iterator_add_deref<Iterator, Deref>::type> type;
static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d) { return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step()); }
};
////////////////////////////////////////////////////////////////////////////////////////
/// make_step_iterator
////////////////////////////////////////////////////////////////////////////////////////
template <typename I> typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step);
namespace detail {
// if the iterator is a plain base iterator (non-adaptor), wraps it in memory_based_step_iterator
template <typename I>
typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::false_) {
return memory_based_step_iterator<I>(it, step);
}
// If the iterator is compound, put the step in its base
template <typename I>
typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::true_) {
return make_step_iterator(it.base(), step);
}
// If the iterator is memory_based_step_iterator, change the step
template <typename BaseIt>
memory_based_step_iterator<BaseIt> make_step_iterator_impl(const memory_based_step_iterator<BaseIt>& it, std::ptrdiff_t step, mpl::true_) {
return memory_based_step_iterator<BaseIt>(it.base(), step);
}
}
/// \brief Constructs a step iterator from a base iterator and a step.
///
/// To construct a step iterator from a given iterator Iterator and a given step, if Iterator does not
/// already have a dynamic step, we wrap it in a memory_based_step_iterator. Otherwise we
/// do a compile-time traversal of the chain of iterator adaptors to locate the step iterator
/// and then set it step to the new one.
///
/// The step iterator of Iterator is not always memory_based_step_iterator<Iterator>. For example, Iterator may
/// already be a memory_based_step_iterator, in which case it will be inefficient to stack them;
/// we can obtain the same result by multiplying their steps. Note that for Iterator to be a
/// step iterator it does not necessarily have to have the form memory_based_step_iterator<J>.
/// The step iterator can be wrapped inside another iterator. Also, it may not have the
/// type memory_based_step_iterator, but it could be a user-provided type.
template <typename I> // Models MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step) {
return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor<I>::type());
}
} } // namespace boost::gil
#endif
|