Chris@16: /* Chris@16: Copyright 2005-2007 Adobe Systems Incorporated Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: See http://opensource.adobe.com/gil for most recent version including documentation. Chris@16: */ Chris@16: Chris@16: /*************************************************************************************************/ Chris@16: Chris@16: #ifndef GIL_PIXEL_ITERATOR_ADAPTOR_H Chris@16: #define GIL_PIXEL_ITERATOR_ADAPTOR_H Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file Chris@16: /// \brief pixel step iterator, pixel image iterator and pixel dereference iterator Chris@16: /// \author Lubomir Bourdev and Hailin Jin \n Chris@16: /// Adobe Systems Incorporated Chris@16: /// \date 2005-2007 \n Last updated on February 16, 2007 Chris@16: /// Chris@16: //////////////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include "gil_config.hpp" Chris@16: #include "gil_concept.hpp" Chris@16: #include "pixel_iterator.hpp" Chris@16: Chris@16: namespace boost { namespace gil { Chris@16: Chris@16: Chris@16: /// \defgroup PixelIteratorModelDerefPtr dereference_iterator_adaptor Chris@16: /// \ingroup PixelIteratorModel Chris@16: /// \brief An iterator that invokes a provided function object upon dereference. Models: IteratorAdaptorConcept, PixelIteratorConcept Chris@16: Chris@16: Chris@16: /// \ingroup PixelIteratorModelDerefPtr PixelBasedModel Chris@16: /// \brief An adaptor over an existing iterator that provides for custom filter on dereferencing the object. Models: IteratorAdaptorConcept, PixelIteratorConcept Chris@16: Chris@16: template // Models Returns the result of dereferencing a given iterator of type Iterator Chris@16: class dereference_iterator_adaptor : public iterator_adaptor, Chris@16: Iterator, Chris@16: typename DFn::value_type, Chris@16: typename std::iterator_traits::iterator_category, Chris@16: typename DFn::reference, Chris@16: use_default> { Chris@16: DFn _deref_fn; Chris@16: public: Chris@16: typedef iterator_adaptor, Chris@16: Iterator, Chris@16: typename DFn::value_type, Chris@16: typename std::iterator_traits::iterator_category, Chris@16: typename DFn::reference, Chris@16: use_default> parent_t; Chris@16: typedef typename DFn::result_type reference; Chris@16: typedef typename std::iterator_traits::difference_type difference_type; Chris@16: typedef DFn dereference_fn; Chris@16: Chris@16: dereference_iterator_adaptor() {} Chris@16: template Chris@16: dereference_iterator_adaptor(const dereference_iterator_adaptor& dit) : parent_t(dit.base()), _deref_fn(dit._deref_fn) {} Chris@16: dereference_iterator_adaptor(Iterator it, DFn deref_fn=DFn()) : parent_t(it), _deref_fn(deref_fn) {} Chris@16: template Chris@16: dereference_iterator_adaptor(const dereference_iterator_adaptor& it) : parent_t(it.base()), _deref_fn(it._deref_fn) {} Chris@16: /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference Chris@16: /// We require our own reference because it is registered in iterator_traits Chris@16: reference operator[](difference_type d) const { return *(*this+d);} Chris@16: Chris@16: // although iterator_adaptor defines these, the default implementation computes distance and compares for zero. Chris@16: // it is often faster to just apply the relation operator to the base Chris@16: bool operator> (const dereference_iterator_adaptor& p) const { return this->base_reference()> p.base_reference(); } Chris@16: bool operator< (const dereference_iterator_adaptor& p) const { return this->base_reference()< p.base_reference(); } Chris@16: bool operator>=(const dereference_iterator_adaptor& p) const { return this->base_reference()>=p.base_reference(); } Chris@16: bool operator<=(const dereference_iterator_adaptor& p) const { return this->base_reference()<=p.base_reference(); } Chris@16: bool operator==(const dereference_iterator_adaptor& p) const { return this->base_reference()==p.base_reference(); } Chris@16: bool operator!=(const dereference_iterator_adaptor& p) const { return this->base_reference()!=p.base_reference(); } Chris@16: Chris@16: Iterator& base() { return this->base_reference(); } Chris@16: const Iterator& base() const { return this->base_reference(); } Chris@16: const DFn& deref_fn() const { return _deref_fn; } Chris@16: private: Chris@16: template Chris@16: friend class dereference_iterator_adaptor; Chris@16: friend class boost::iterator_core_access; Chris@16: Chris@16: reference dereference() const { return _deref_fn(*(this->base_reference())); } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct const_iterator_type > { Chris@16: typedef dereference_iterator_adaptor::type,typename DFn::const_t> type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct iterator_is_mutable > : public mpl::bool_ {}; Chris@16: Chris@16: Chris@16: template Chris@16: struct is_iterator_adaptor > : public mpl::true_{}; Chris@16: Chris@16: template Chris@16: struct iterator_adaptor_get_base > { Chris@16: typedef I type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct iterator_adaptor_rebind,NewBaseIterator> { Chris@16: typedef dereference_iterator_adaptor type; Chris@16: }; Chris@16: Chris@16: ///////////////////////////// Chris@16: // PixelBasedConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct color_space_type > : public color_space_type {}; Chris@16: Chris@16: template Chris@16: struct channel_mapping_type > : public channel_mapping_type {}; Chris@16: Chris@16: template Chris@16: struct is_planar > : public is_planar {}; Chris@16: Chris@16: template Chris@16: struct channel_type > : public channel_type {}; Chris@16: Chris@16: Chris@16: ///////////////////////////// Chris@16: // MemoryBasedIteratorConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct byte_to_memunit > : public byte_to_memunit {}; Chris@16: Chris@16: template Chris@16: inline typename std::iterator_traits::difference_type Chris@16: memunit_step(const dereference_iterator_adaptor& p) { Chris@16: return memunit_step(p.base()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename std::iterator_traits::difference_type Chris@16: memunit_distance(const dereference_iterator_adaptor& p1, Chris@16: const dereference_iterator_adaptor& p2) { Chris@16: return memunit_distance(p1.base(),p2.base()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void memunit_advance(dereference_iterator_adaptor& p, Chris@16: typename std::iterator_traits::difference_type diff) { Chris@16: memunit_advance(p.base(), diff); Chris@16: } Chris@16: Chris@16: template Chris@16: inline dereference_iterator_adaptor Chris@16: memunit_advanced(const dereference_iterator_adaptor& p, Chris@16: typename std::iterator_traits::difference_type diff) { Chris@16: return dereference_iterator_adaptor(memunit_advanced(p.base(), diff), p.deref_fn()); Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: inline Chris@16: typename std::iterator_traits >::reference Chris@16: memunit_advanced_ref(const dereference_iterator_adaptor& p, Chris@16: typename std::iterator_traits::difference_type diff) { Chris@16: return *memunit_advanced(p, diff); Chris@16: } Chris@16: Chris@16: ///////////////////////////// Chris@16: // HasDynamicXStepTypeConcept Chris@16: ///////////////////////////// Chris@16: Chris@16: template Chris@16: struct dynamic_x_step_type > { Chris@16: typedef dereference_iterator_adaptor::type,DFn> type; Chris@16: }; Chris@16: Chris@16: /// \brief Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor upon dereferencing Chris@16: /// \ingroup PixelIteratorModelDerefPtr Chris@16: template Chris@16: struct iterator_add_deref { Chris@16: GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) Chris@16: Chris@16: typedef dereference_iterator_adaptor type; Chris@16: Chris@16: static type make(const Iterator& it, const Deref& d) { return type(it,d); } Chris@16: }; Chris@16: Chris@16: /// \ingroup PixelIteratorModelDerefPtr Chris@16: /// \brief For dereference iterator adaptors, compose the new function object after the old one Chris@16: template Chris@16: struct iterator_add_deref,Deref> { Chris@16: // GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept) Chris@16: Chris@16: typedef dereference_iterator_adaptor > type; Chris@16: Chris@16: static type make(const dereference_iterator_adaptor& it, const Deref& d) { Chris@16: return type(it.base(),deref_compose(d,it.deref_fn())); Chris@16: } Chris@16: }; Chris@16: Chris@16: } } // namespace boost::gil Chris@16: Chris@16: #endif