123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- // Boost.Geometry (aka GGL, Generic Geometry Library)
- // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
- // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
- // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
- // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
- // Use, modification and distribution is 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)
- #ifndef BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
- #define BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
- #include <boost/range.hpp>
- #include <boost/iterator.hpp>
- #include <boost/iterator/iterator_facade.hpp>
- #include <boost/iterator/iterator_categories.hpp>
- namespace boost { namespace geometry
- {
- /*!
- \brief Iterator which iterates through a range, but adds first element at end of the range
- \tparam Range range on which this class is based on
- \ingroup iterators
- \note Use with "closing_iterator<Range> or "closing_iterator<Range const>
- to get non-const / const behaviour
- \note This class is normally used from "closeable_view" if Close==true
- */
- template <typename Range>
- struct closing_iterator
- : public boost::iterator_facade
- <
- closing_iterator<Range>,
- typename boost::range_value<Range>::type const,
- boost::random_access_traversal_tag
- >
- {
- /// Constructor including the range it is based on
- explicit inline closing_iterator(Range& range)
- : m_range(&range)
- , m_iterator(boost::begin(range))
- , m_end(boost::end(range))
- , m_size(boost::size(range))
- , m_index(0)
- {}
- /// Constructor to indicate the end of a range
- explicit inline closing_iterator(Range& range, bool)
- : m_range(&range)
- , m_iterator(boost::end(range))
- , m_end(boost::end(range))
- , m_size(boost::size(range))
- , m_index(m_size + 1)
- {}
- /// Default constructor
- explicit inline closing_iterator()
- : m_range(NULL)
- , m_size(0)
- , m_index(0)
- {}
- inline closing_iterator<Range>& operator=(closing_iterator<Range> const& source)
- {
- m_range = source.m_range;
- m_iterator = source.m_iterator;
- m_end = source.m_end;
- m_size = source.m_size;
- m_index = source.m_index;
- return *this;
- }
- typedef std::ptrdiff_t difference_type;
- private:
- friend class boost::iterator_core_access;
- inline typename boost::range_value<Range>::type const& dereference() const
- {
- return *m_iterator;
- }
- inline difference_type distance_to(closing_iterator<Range> const& other) const
- {
- return other.m_index - this->m_index;
- }
- inline bool equal(closing_iterator<Range> const& other) const
- {
- return this->m_range == other.m_range
- && this->m_index == other.m_index;
- }
- inline void increment()
- {
- if (++m_index < m_size)
- {
- ++m_iterator;
- }
- else
- {
- update_iterator();
- }
- }
- inline void decrement()
- {
- if (m_index-- < m_size)
- {
- --m_iterator;
- }
- else
- {
- update_iterator();
- }
- }
- inline void advance(difference_type n)
- {
- if (m_index < m_size && m_index + n < m_size)
- {
- m_index += n;
- m_iterator += n;
- }
- else
- {
- m_index += n;
- update_iterator();
- }
- }
- inline void update_iterator()
- {
- this->m_iterator = m_index <= m_size
- ? boost::begin(*m_range) + (m_index % m_size)
- : boost::end(*m_range)
- ;
- }
- Range* m_range;
- typename boost::range_iterator<Range>::type m_iterator;
- typename boost::range_iterator<Range>::type m_end;
- difference_type m_size;
- difference_type m_index;
- };
- }} // namespace boost::geometry
- #endif // BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
|