1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 // Unit Test 3 4 // Copyright (c) 2015, Oracle and/or its affiliates. 5 6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle 7 8 // Licensed under the Boost Software License version 1.0. 9 // http://www.boost.org/users/license.html 10 11 #ifndef GEOMETRY_TEST_TEST_GEOMETRIES_COPY_ON_DEREFERENCE_GEOMETRIES_HPP 12 #define GEOMETRY_TEST_TEST_GEOMETRIES_COPY_ON_DEREFERENCE_GEOMETRIES_HPP 13 14 #include <cstddef> 15 #include <iterator> 16 #include <vector> 17 18 #include <boost/iterator/iterator_facade.hpp> 19 #include <boost/iterator/iterator_categories.hpp> 20 21 #include <boost/geometry/core/tag.hpp> 22 23 24 template <typename RandomAccessIterator> 25 class copy_on_dereference_iterator 26 : public boost::iterator_facade 27 < 28 copy_on_dereference_iterator<RandomAccessIterator>, 29 typename std::iterator_traits<RandomAccessIterator>::value_type, 30 boost::random_access_traversal_tag, 31 typename std::iterator_traits<RandomAccessIterator>::value_type, 32 typename std::iterator_traits<RandomAccessIterator>::difference_type 33 > 34 { 35 private: 36 typedef boost::iterator_facade 37 < 38 copy_on_dereference_iterator<RandomAccessIterator>, 39 typename std::iterator_traits<RandomAccessIterator>::value_type, 40 boost::random_access_traversal_tag, 41 typename std::iterator_traits<RandomAccessIterator>::value_type, 42 typename std::iterator_traits<RandomAccessIterator>::difference_type 43 > base_type; 44 45 public: 46 typedef typename base_type::reference reference; 47 typedef typename base_type::difference_type difference_type; 48 copy_on_dereference_iterator()49 copy_on_dereference_iterator() {} copy_on_dereference_iterator(RandomAccessIterator it)50 copy_on_dereference_iterator(RandomAccessIterator it) : m_it(it) {} 51 52 template <typename OtherRAI> copy_on_dereference_iterator(copy_on_dereference_iterator<OtherRAI> const & other)53 copy_on_dereference_iterator 54 (copy_on_dereference_iterator<OtherRAI> const& other) 55 : m_it(other.m_it) 56 {} 57 58 private: 59 friend class boost::iterator_core_access; 60 61 template <typename OtherRAI> 62 friend class copy_on_dereference_iterator; 63 dereference() const64 inline reference dereference() const { return *m_it; } increment()65 inline void increment() { ++m_it; } decrement()66 inline void decrement() { --m_it; } advance(difference_type n)67 inline void advance(difference_type n) { m_it += n; } 68 69 template <typename OtherRAI> equal(copy_on_dereference_iterator<OtherRAI> const & other) const70 inline bool equal(copy_on_dereference_iterator<OtherRAI> const& other) const 71 { 72 return m_it == other.m_it; 73 } 74 75 template <typename OtherRAI> 76 inline difference_type distance_to(copy_on_dereference_iterator<OtherRAI> const & other) const77 distance_to(copy_on_dereference_iterator<OtherRAI> const& other) const 78 { 79 return std::distance(m_it, other.m_it); 80 } 81 82 private: 83 RandomAccessIterator m_it; 84 }; 85 86 87 template <typename Value> 88 class range_copy_on_dereference : private std::vector<Value> 89 { 90 private: 91 typedef std::vector<Value> base_type; 92 93 public: 94 typedef typename base_type::size_type size_type; 95 96 typedef copy_on_dereference_iterator 97 < 98 typename base_type::const_iterator 99 > const_iterator; 100 101 typedef const_iterator iterator; 102 begin()103 inline iterator begin() 104 { 105 return iterator(base_type::begin()); 106 } 107 end()108 inline iterator end() 109 { 110 return iterator(base_type::end()); 111 } 112 begin() const113 inline const_iterator begin() const 114 { 115 return const_iterator(base_type::begin()); 116 } 117 end() const118 inline const_iterator end() const 119 { 120 return const_iterator(base_type::end()); 121 } 122 clear()123 inline void clear() 124 { 125 base_type::clear(); 126 } 127 push_back(Value const & value)128 inline void push_back(Value const& value) 129 { 130 base_type::push_back(value); 131 } 132 resize(std::size_t n)133 inline void resize(std::size_t n) 134 { 135 base_type::resize(n); 136 } 137 size() const138 inline size_type size() const 139 { 140 return base_type::size(); 141 } 142 }; 143 144 145 template <typename Point> 146 struct multipoint_copy_on_dereference : range_copy_on_dereference<Point> 147 {}; 148 149 template <typename Point> 150 struct linestring_copy_on_dereference : range_copy_on_dereference<Point> 151 {}; 152 153 154 namespace boost { namespace geometry 155 { 156 157 namespace traits 158 { 159 160 template <typename Point> 161 struct tag< multipoint_copy_on_dereference<Point> > 162 { 163 typedef multi_point_tag type; 164 }; 165 166 template <typename Point> 167 struct tag< linestring_copy_on_dereference<Point> > 168 { 169 typedef linestring_tag type; 170 }; 171 172 } // namespace traits 173 174 }} // namespace boost::geometry 175 176 177 #endif // GEOMETRY_TEST_TEST_GEOMETRIES_COPY_ON_DEREFERENCE_GEOMETRIES_HPP 178