File indexing completed on 2025-09-16 08:35:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GEOMETRY_VIEWS_ENUMERATE_VIEW_HPP
0010 #define BOOST_GEOMETRY_VIEWS_ENUMERATE_VIEW_HPP
0011
0012 #include <boost/iterator/iterator_facade.hpp>
0013 #include <boost/iterator/iterator_categories.hpp>
0014 #include <boost/range/begin.hpp>
0015 #include <boost/range/end.hpp>
0016 #include <boost/range/difference_type.hpp>
0017 #include <boost/range/reference.hpp>
0018 #include <boost/range/value_type.hpp>
0019
0020 #include <boost/geometry/util/type_traits_std.hpp>
0021
0022 namespace boost { namespace geometry
0023 {
0024
0025 namespace util
0026 {
0027
0028
0029
0030
0031
0032 template <typename Range>
0033 struct enumerated_view
0034 {
0035
0036 struct value_with_index
0037 {
0038 using type = util::transcribe_const_t
0039 <
0040 Range,
0041 typename boost::range_value<Range>::type
0042 >;
0043
0044
0045 std::size_t const index;
0046
0047
0048 type& value;
0049 };
0050
0051 private:
0052
0053 struct enumerating_iterator
0054 : public boost::iterator_facade
0055 <
0056 enumerating_iterator,
0057 value_with_index const,
0058 boost::random_access_traversal_tag,
0059 value_with_index const,
0060 typename boost::range_difference<Range>::type
0061 >
0062 {
0063 using reference = value_with_index;
0064 using difference_type = typename boost::range_difference<Range>::type;
0065
0066
0067 explicit inline enumerating_iterator(Range& range)
0068 : m_begin(boost::begin(range))
0069 , m_end(boost::end(range))
0070 , m_iterator(boost::begin(range))
0071 {}
0072
0073
0074 explicit inline enumerating_iterator(Range& range, bool)
0075 : m_begin(boost::begin(range))
0076 , m_end(boost::end(range))
0077 , m_iterator(boost::end(range))
0078 {}
0079
0080
0081 enumerating_iterator() = delete;
0082
0083 inline reference dereference() const
0084 {
0085 constexpr difference_type zero = 0;
0086 const std::size_t index = (std::max)(zero, std::distance(m_begin, m_iterator));
0087 const value_with_index result{index, *m_iterator};
0088 return result;
0089 }
0090
0091 inline difference_type distance_to(enumerating_iterator const& other) const
0092 {
0093 return std::distance(other.m_iterator, m_iterator);
0094 }
0095
0096 inline bool equal(enumerating_iterator const& other) const
0097 {
0098 return
0099 m_begin == other.m_begin
0100 && m_end == other.m_end
0101 && m_iterator == other.m_iterator;
0102 }
0103
0104 inline void increment()
0105 {
0106 ++m_iterator;
0107 }
0108
0109 inline void decrement()
0110 {
0111 --m_iterator;
0112 }
0113
0114 inline void advance(difference_type n)
0115 {
0116 std::advance(m_iterator, n);
0117 }
0118
0119 const typename boost::range_iterator<Range>::type m_begin;
0120 const typename boost::range_iterator<Range>::type m_end;
0121
0122 typename boost::range_iterator<Range>::type m_iterator;
0123 };
0124
0125 public:
0126 using iterator = enumerating_iterator;
0127 using const_iterator = enumerating_iterator;
0128
0129 explicit inline enumerated_view(Range& range)
0130 : m_begin(range)
0131 , m_end(range, true)
0132 {}
0133
0134 inline iterator begin() const { return m_begin; }
0135 inline iterator end() const { return m_end; }
0136
0137 private:
0138 const iterator m_begin;
0139 const iterator m_end;
0140 };
0141
0142
0143 template <typename Range>
0144 inline auto enumerate(Range const& range)
0145 {
0146 return util::enumerated_view<Range const>(range);
0147 }
0148
0149
0150 template <typename Range>
0151 inline auto enumerate(Range& range)
0152 {
0153 return util::enumerated_view<Range>(range);
0154 }
0155
0156 }}}
0157
0158
0159 #endif