File indexing completed on 2025-01-18 09:35:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
0011 #define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP
0012
0013
0014 #include <type_traits>
0015
0016 #include <boost/iterator/iterator_facade.hpp>
0017 #include <boost/iterator/iterator_categories.hpp>
0018
0019
0020 namespace boost { namespace geometry
0021 {
0022
0023
0024
0025 template
0026 <
0027 typename Iterator1,
0028 typename Iterator2,
0029 typename Value,
0030 typename Reference = Value&
0031 >
0032 class concatenate_iterator
0033 : public boost::iterator_facade
0034 <
0035 concatenate_iterator<Iterator1, Iterator2, Value, Reference>,
0036 Value,
0037 boost::bidirectional_traversal_tag,
0038 Reference
0039 >
0040 {
0041 private:
0042 Iterator1 m_it1, m_end1;
0043 Iterator2 m_begin2, m_it2;
0044
0045 public:
0046 typedef Iterator1 first_iterator_type;
0047 typedef Iterator2 second_iterator_type;
0048
0049
0050 concatenate_iterator() = default;
0051
0052
0053 concatenate_iterator(Iterator1 it1, Iterator1 end1,
0054 Iterator2 begin2, Iterator2 it2)
0055 : m_it1(it1), m_end1(end1), m_begin2(begin2), m_it2(it2)
0056 {}
0057
0058
0059 concatenate_iterator(Iterator1 end1, Iterator2 begin2, Iterator2 end2)
0060 : m_it1(end1), m_end1(end1), m_begin2(begin2), m_it2(end2)
0061 {}
0062
0063 template
0064 <
0065 typename OtherIt1,
0066 typename OtherIt2,
0067 typename OtherValue,
0068 typename OtherReference,
0069 std::enable_if_t
0070 <
0071 std::is_convertible<OtherIt1, Iterator1>::value
0072 && std::is_convertible<OtherIt2, Iterator2>::value,
0073 int
0074 > = 0
0075 >
0076 concatenate_iterator(concatenate_iterator
0077 <
0078 OtherIt1,
0079 OtherIt2,
0080 OtherValue,
0081 OtherReference
0082 > const& other)
0083 : m_it1(other.m_it1)
0084 , m_end1(other.m_end1)
0085 , m_begin2(other.m_begin2)
0086 , m_it2(other.m_it2)
0087 {}
0088
0089 concatenate_iterator(concatenate_iterator const& other) = default;
0090
0091 concatenate_iterator& operator=(concatenate_iterator const& other) = default;
0092
0093 private:
0094 friend class boost::iterator_core_access;
0095
0096 template <typename It1, typename It2, typename V, typename R>
0097 friend class concatenate_iterator;
0098
0099 inline Reference dereference() const
0100 {
0101 if ( m_it1 == m_end1 )
0102 {
0103 return *m_it2;
0104 }
0105 return *m_it1;
0106 }
0107
0108 template
0109 <
0110 typename OtherIt1,
0111 typename OtherIt2,
0112 typename OtherValue,
0113 typename OtherReference
0114 >
0115 inline bool equal(concatenate_iterator
0116 <
0117 OtherIt1,
0118 OtherIt2,
0119 OtherValue,
0120 OtherReference
0121 > const& other) const
0122 {
0123 return m_it1 == other.m_it1 && m_it2 == other.m_it2;
0124 }
0125
0126 inline void increment()
0127 {
0128 if ( m_it1 == m_end1 )
0129 {
0130 ++m_it2;
0131 }
0132 else
0133 {
0134 ++m_it1;
0135 }
0136 }
0137
0138 inline void decrement()
0139 {
0140 if ( m_it2 == m_begin2 )
0141 {
0142 --m_it1;
0143 }
0144 else
0145 {
0146 --m_it2;
0147 }
0148 }
0149 };
0150
0151
0152
0153 }}
0154
0155 #endif