• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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