You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
157 lines
4.0 KiB
157 lines
4.0 KiB
// Boost.Geometry (aka GGL, Generic Geometry Library) |
|
|
|
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands. |
|
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France. |
|
// Copyright (c) 2009-2011 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
|
|
|