Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:36

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 
0007 // Copyright (c) 2020-2021, Oracle and/or its affiliates.
0008 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0009 
0010 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0011 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0012 
0013 // Use, modification and distribution is subject to the Boost Software License,
0014 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0015 // http://www.boost.org/LICENSE_1_0.txt)
0016 
0017 #ifndef BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
0018 #define BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP
0019 
0020 
0021 #include <boost/iterator/iterator_facade.hpp>
0022 #include <boost/iterator/iterator_categories.hpp>
0023 #include <boost/range/begin.hpp>
0024 #include <boost/range/end.hpp>
0025 #include <boost/range/difference_type.hpp>
0026 #include <boost/range/reference.hpp>
0027 #include <boost/range/value_type.hpp>
0028 
0029 #include <boost/geometry/core/assert.hpp>
0030 
0031 
0032 namespace boost { namespace geometry
0033 {
0034 
0035 /*!
0036 \brief Iterator which iterates through a range, but adds first element at end of the range
0037 \tparam Range range on which this class is based on
0038 \ingroup iterators
0039 \note It's const iterator treating the Range as one containing non-mutable elements.
0040         For both "closing_iterator<Range> and "closing_iterator<Range const>
0041         const reference is always returned when dereferenced.
0042 \note This class is normally used from "closeable_view" if Close==true
0043 */
0044 template <typename Range>
0045 struct closing_iterator
0046     : public boost::iterator_facade
0047     <
0048         closing_iterator<Range>,
0049         typename boost::range_value<Range>::type const,
0050         boost::random_access_traversal_tag,
0051         typename boost::range_reference<Range const>::type,
0052         typename boost::range_difference<Range>::type
0053     >
0054 {
0055 private:
0056     typedef boost::iterator_facade
0057         <
0058             closing_iterator<Range>,
0059             typename boost::range_value<Range>::type const,
0060             boost::random_access_traversal_tag,
0061             typename boost::range_reference<Range const>::type,
0062             typename boost::range_difference<Range>::type
0063         > base_type;
0064 
0065 public:
0066     typedef typename base_type::reference reference;
0067     typedef typename base_type::difference_type difference_type;
0068 
0069     /// Constructor including the range it is based on
0070     explicit inline closing_iterator(Range const& range)
0071         : m_iterator(boost::begin(range))
0072         , m_begin(boost::begin(range))
0073         , m_end(boost::end(range))
0074         , m_size(m_end - m_begin)
0075         , m_index(0)
0076     {}
0077 
0078     /// Constructor to indicate the end of a range
0079     explicit inline closing_iterator(Range const& range, bool)
0080         : m_iterator(boost::end(range))
0081         , m_begin(boost::begin(range))
0082         , m_end(boost::end(range))
0083         , m_size(m_end - m_begin)
0084         , m_index((m_size == 0) ? 0 : m_size + 1)
0085     {}
0086 
0087     /// Default constructor
0088     inline closing_iterator()
0089         : m_size(0)
0090         , m_index(0)
0091     {}
0092 
0093     template
0094     <
0095         typename OtherRange,
0096         std::enable_if_t
0097             <
0098                 std::is_convertible
0099                     <
0100                         typename boost::range_iterator<OtherRange const>::type,
0101                         typename boost::range_iterator<Range const>::type
0102                     >::value,
0103                 int
0104             > = 0
0105     >
0106     inline closing_iterator(closing_iterator<OtherRange> const& other)
0107         : m_iterator(other.m_iterator)
0108         , m_begin(other.m_begin)
0109         , m_end(other.m_end)
0110         , m_size(other.m_size)
0111         , m_index(other.m_index)
0112     {}
0113 
0114 private:
0115     template <typename OtherRange> friend struct closing_iterator;
0116     friend class boost::iterator_core_access;
0117 
0118     inline reference dereference() const
0119     {
0120         return *m_iterator;
0121     }
0122 
0123     inline difference_type distance_to(closing_iterator<Range> const& other) const
0124     {
0125         return other.m_index - this->m_index;
0126     }
0127 
0128     inline bool equal(closing_iterator<Range> const& other) const
0129     {
0130         BOOST_GEOMETRY_ASSERT(m_begin == other.m_begin && m_end == other.m_end);
0131         return this->m_index == other.m_index;
0132     }
0133 
0134     inline void increment()
0135     {
0136         if (++m_index < m_size)
0137         {
0138             ++m_iterator;
0139         }
0140         else
0141         {
0142             update_iterator();
0143         }
0144     }
0145 
0146     inline void decrement()
0147     {
0148         if (m_index-- < m_size)
0149         {
0150             --m_iterator;
0151         }
0152         else
0153         {
0154             update_iterator();
0155         }
0156     }
0157 
0158     inline void advance(difference_type n)
0159     {
0160         if (m_index < m_size && m_index + n < m_size)
0161         {
0162             m_index += n;
0163             m_iterator += n;
0164         }
0165         else
0166         {
0167             m_index += n;
0168             update_iterator();
0169         }
0170     }
0171 
0172     inline void update_iterator()
0173     {
0174         this->m_iterator = m_index <= m_size
0175             ? m_begin + (m_index % m_size)
0176             : m_end
0177             ;
0178     }
0179 
0180     typename boost::range_iterator<Range const>::type m_iterator;
0181     typename boost::range_iterator<Range const>::type m_begin;
0182     typename boost::range_iterator<Range const>::type m_end;
0183     difference_type m_size;
0184     difference_type m_index;
0185 };
0186 
0187 
0188 }} // namespace boost::geometry
0189 
0190 
0191 #endif // BOOST_GEOMETRY_ITERATORS_CLOSING_ITERATOR_HPP