1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2014, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 6 7 // Licensed under the Boost Software License version 1.0. 8 // http://www.boost.org/users/license.html 9 10 #ifndef BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP 11 #define BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP 12 13 #include <boost/mpl/assert.hpp> 14 #include <boost/type_traits/is_convertible.hpp> 15 #include <boost/iterator/iterator_facade.hpp> 16 #include <boost/iterator/iterator_categories.hpp> 17 18 19 namespace boost { namespace geometry 20 { 21 22 23 24 template 25 < 26 typename Iterator1, 27 typename Iterator2, 28 typename Value, 29 typename Reference = Value& 30 > 31 class concatenate_iterator 32 : public boost::iterator_facade 33 < 34 concatenate_iterator<Iterator1, Iterator2, Value, Reference>, 35 Value, 36 boost::bidirectional_traversal_tag, 37 Reference 38 > 39 { 40 private: 41 Iterator1 m_it1, m_end1; 42 Iterator2 m_begin2, m_it2; 43 44 public: 45 typedef Iterator1 first_iterator_type; 46 typedef Iterator2 second_iterator_type; 47 48 // default constructor concatenate_iterator()49 concatenate_iterator() {} 50 51 // for begin concatenate_iterator(Iterator1 it1,Iterator1 end1,Iterator2 begin2,Iterator2 it2)52 concatenate_iterator(Iterator1 it1, Iterator1 end1, 53 Iterator2 begin2, Iterator2 it2) 54 : m_it1(it1), m_end1(end1), m_begin2(begin2), m_it2(it2) 55 {} 56 57 // for end concatenate_iterator(Iterator1 end1,Iterator2 begin2,Iterator2 end2)58 concatenate_iterator(Iterator1 end1, Iterator2 begin2, Iterator2 end2) 59 : m_it1(end1), m_end1(end1), m_begin2(begin2), m_it2(end2) 60 {} 61 62 template 63 < 64 typename OtherIt1, 65 typename OtherIt2, 66 typename OtherValue, 67 typename OtherReference 68 > concatenate_iterator(concatenate_iterator<OtherIt1,OtherIt2,OtherValue,OtherReference> const & other)69 concatenate_iterator(concatenate_iterator 70 < 71 OtherIt1, 72 OtherIt2, 73 OtherValue, 74 OtherReference 75 > const& other) 76 : m_it1(other.m_it1) 77 , m_end1(other.m_end1) 78 , m_begin2(other.m_begin2) 79 , m_it2(other.m_it2) 80 { 81 static const bool are_conv 82 = boost::is_convertible<OtherIt1, Iterator1>::value 83 && boost::is_convertible<OtherIt2, Iterator2>::value; 84 85 BOOST_MPL_ASSERT_MSG((are_conv), 86 NOT_CONVERTIBLE, 87 (types<OtherIt1, OtherIt2>)); 88 } 89 90 private: 91 friend class boost::iterator_core_access; 92 93 template <typename It1, typename It2, typename V, typename R> 94 friend class concatenate_iterator; 95 dereference() const96 inline Reference dereference() const 97 { 98 if ( m_it1 == m_end1 ) 99 { 100 return *m_it2; 101 } 102 return *m_it1; 103 } 104 105 template 106 < 107 typename OtherIt1, 108 typename OtherIt2, 109 typename OtherValue, 110 typename OtherReference 111 > equal(concatenate_iterator<OtherIt1,OtherIt2,OtherValue,OtherReference> const & other) const112 inline bool equal(concatenate_iterator 113 < 114 OtherIt1, 115 OtherIt2, 116 OtherValue, 117 OtherReference 118 > const& other) const 119 { 120 return m_it1 == other.m_it1 && m_it2 == other.m_it2; 121 } 122 increment()123 inline void increment() 124 { 125 if ( m_it1 == m_end1 ) 126 { 127 ++m_it2; 128 } 129 else 130 { 131 ++m_it1; 132 } 133 } 134 decrement()135 inline void decrement() 136 { 137 if ( m_it2 == m_begin2 ) 138 { 139 --m_it1; 140 } 141 else 142 { 143 --m_it2; 144 } 145 } 146 }; 147 148 149 150 }} // namespace boost::geometry 151 152 #endif // BOOST_GEOMETRY_ITERATORS_CONCATENATE_ITERATOR_HPP 153