]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/polygon/example/gtl_custom_polygon_set.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / polygon / example / gtl_custom_polygon_set.cpp
1 /*
2 Copyright 2008 Intel Corporation
3
4 Use, modification and distribution are subject to the Boost Software License,
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 */
8 #include <boost/polygon/polygon.hpp>
9 #include <list>
10 #include <time.h>
11 #include <cassert>
12 #include <deque>
13 #include <iostream>
14 namespace gtl = boost::polygon;
15 using namespace boost::polygon::operators;
16
17 //once again we make our usage of the library generic
18 //and parameterize it on the polygon set type
19 template <typename PolygonSet>
20 void test_polygon_set() {
21 using namespace gtl;
22 PolygonSet ps;
23 ps += rectangle_data<int>(0, 0, 10, 10);
24 PolygonSet ps2;
25 ps2 += rectangle_data<int>(5, 5, 15, 15);
26 PolygonSet ps3;
27 assign(ps3, ps * ps2);
28 PolygonSet ps4;
29 ps4 += ps + ps2;
30 assert(area(ps4) == area(ps) + area(ps2) - area(ps3));
31 assert(equivalence((ps + ps2) - (ps * ps2), ps ^ ps2));
32 rectangle_data<int> rect;
33 assert(extents(rect, ps ^ ps2));
34 assert(area(rect) == 225);
35 assert(area(rect ^ (ps ^ ps2)) == area(rect) - area(ps ^ ps2));
36 }
37
38 //first thing is first, lets include all the code from previous examples
39
40 //the CPoint example
41 struct CPoint {
42 int x;
43 int y;
44 };
45
46 namespace boost { namespace polygon {
47 template <>
48 struct geometry_concept<CPoint> { typedef point_concept type; };
49 template <>
50 struct point_traits<CPoint> {
51 typedef int coordinate_type;
52
53 static inline coordinate_type get(const CPoint& point,
54 orientation_2d orient) {
55 if(orient == HORIZONTAL)
56 return point.x;
57 return point.y;
58 }
59 };
60
61 template <>
62 struct point_mutable_traits<CPoint> {
63 typedef int coordinate_type;
64
65 static inline void set(CPoint& point, orientation_2d orient, int value) {
66 if(orient == HORIZONTAL)
67 point.x = value;
68 else
69 point.y = value;
70 }
71 static inline CPoint construct(int x_value, int y_value) {
72 CPoint retval;
73 retval.x = x_value;
74 retval.y = y_value;
75 return retval;
76 }
77 };
78 } }
79
80 //the CPolygon example
81 typedef std::list<CPoint> CPolygon;
82
83 //we need to specialize our polygon concept mapping in boost polygon
84 namespace boost { namespace polygon {
85 //first register CPolygon as a polygon_concept type
86 template <>
87 struct geometry_concept<CPolygon>{ typedef polygon_concept type; };
88
89 template <>
90 struct polygon_traits<CPolygon> {
91 typedef int coordinate_type;
92 typedef CPolygon::const_iterator iterator_type;
93 typedef CPoint point_type;
94
95 // Get the begin iterator
96 static inline iterator_type begin_points(const CPolygon& t) {
97 return t.begin();
98 }
99
100 // Get the end iterator
101 static inline iterator_type end_points(const CPolygon& t) {
102 return t.end();
103 }
104
105 // Get the number of sides of the polygon
106 static inline std::size_t size(const CPolygon& t) {
107 return t.size();
108 }
109
110 // Get the winding direction of the polygon
111 static inline winding_direction winding(const CPolygon& t) {
112 return unknown_winding;
113 }
114 };
115
116 template <>
117 struct polygon_mutable_traits<CPolygon> {
118 //expects stl style iterators
119 template <typename iT>
120 static inline CPolygon& set_points(CPolygon& t,
121 iT input_begin, iT input_end) {
122 t.clear();
123 while(input_begin != input_end) {
124 t.push_back(CPoint());
125 gtl::assign(t.back(), *input_begin);
126 ++input_begin;
127 }
128 return t;
129 }
130
131 };
132 } }
133
134 //OK, finally we get to declare our own polygon set type
135 typedef std::deque<CPolygon> CPolygonSet;
136
137 //deque isn't automatically a polygon set in the library
138 //because it is a standard container there is a shortcut
139 //for mapping it to polygon set concept, but I'll do it
140 //the long way that you would use in the general case.
141 namespace boost { namespace polygon {
142 //first we register CPolygonSet as a polygon set
143 template <>
144 struct geometry_concept<CPolygonSet> { typedef polygon_set_concept type; };
145
146 //next we map to the concept through traits
147 template <>
148 struct polygon_set_traits<CPolygonSet> {
149 typedef int coordinate_type;
150 typedef CPolygonSet::const_iterator iterator_type;
151 typedef CPolygonSet operator_arg_type;
152
153 static inline iterator_type begin(const CPolygonSet& polygon_set) {
154 return polygon_set.begin();
155 }
156
157 static inline iterator_type end(const CPolygonSet& polygon_set) {
158 return polygon_set.end();
159 }
160
161 //don't worry about these, just return false from them
162 static inline bool clean(const CPolygonSet& polygon_set) { return false; }
163 static inline bool sorted(const CPolygonSet& polygon_set) { return false; }
164 };
165
166 template <>
167 struct polygon_set_mutable_traits<CPolygonSet> {
168 template <typename input_iterator_type>
169 static inline void set(CPolygonSet& polygon_set, input_iterator_type input_begin, input_iterator_type input_end) {
170 polygon_set.clear();
171 //this is kind of cheesy. I am copying the unknown input geometry
172 //into my own polygon set and then calling get to populate the
173 //deque
174 polygon_set_data<int> ps;
175 ps.insert(input_begin, input_end);
176 ps.get(polygon_set);
177 //if you had your own odd-ball polygon set you would probably have
178 //to iterate through each polygon at this point and do something
179 //extra
180 }
181 };
182 } }
183
184 int main() {
185 long long c1 = clock();
186 for(int i = 0; i < 1000; ++i)
187 test_polygon_set<CPolygonSet>();
188 long long c2 = clock();
189 for(int i = 0; i < 1000; ++i)
190 test_polygon_set<gtl::polygon_set_data<int> >();
191 long long c3 = clock();
192 long long diff1 = c2 - c1;
193 long long diff2 = c3 - c2;
194 if(diff1 > 0 && diff2)
195 std::cout << "library polygon_set_data is " << float(diff1)/float(diff2) << "X faster than custom polygon set deque of CPolygon" << std::endl;
196 else
197 std::cout << "operation was too fast" << std::endl;
198 return 0;
199 }
200
201 //Now you know how to map your own data type to polygon set concept
202 //Now you also know how to make your application code that operates on geometry
203 //data type agnostic from point through polygon set