158 lines
4.0 KiB
C++
158 lines
4.0 KiB
C++
// 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
|