1 #pragma once
2 
3 #include <list>
4 
5 #include <mapbox/geometry/point.hpp>
6 
7 #include <mapbox/geometry/wagyu/config.hpp>
8 #include <mapbox/geometry/wagyu/edge.hpp>
9 #include <mapbox/geometry/wagyu/ring.hpp>
10 
11 #ifdef DEBUG
12 #include <iostream>
13 #endif
14 
15 namespace mapbox {
16 namespace geometry {
17 namespace wagyu {
18 
19 template <typename T>
20 struct bound {
21 
22     edge_list<T> edges;
23     edge_list_itr<T> current_edge;
24     edge_list_itr<T> next_edge;
25     mapbox::geometry::point<T> last_point;
26     ring_ptr<T> ring;
27     bound_ptr<T> maximum_bound; // the bound who's maximum connects with this bound
28     double current_x;
29     std::size_t pos;
30     std::int32_t winding_count;
31     std::int32_t winding_count2; // winding count of the opposite polytype
32     std::int8_t winding_delta;   // 1 or -1 depending on winding direction - 0 for linestrings
33     polygon_type poly_type;
34     edge_side side; // side only refers to current side of solution poly
35 
boundmapbox::geometry::wagyu::bound36     bound() noexcept
37         : edges(),
38           current_edge(edges.end()),
39           next_edge(edges.end()),
40           last_point({ 0, 0 }),
41           ring(nullptr),
42           maximum_bound(nullptr),
43           current_x(0.0),
44           pos(0),
45           winding_count(0),
46           winding_count2(0),
47           winding_delta(0),
48           poly_type(polygon_type_subject),
49           side(edge_left) {
50     }
51 
boundmapbox::geometry::wagyu::bound52     bound(bound<T>&& b) noexcept
53         : edges(std::move(b.edges)),
54           current_edge(std::move(b.current_edge)),
55           next_edge(std::move(b.next_edge)),
56           last_point(std::move(b.last_point)),
57           ring(std::move(b.ring)),
58           maximum_bound(std::move(b.maximum_bound)),
59           current_x(std::move(b.current_x)),
60           pos(std::move(b.pos)),
61           winding_count(std::move(b.winding_count)),
62           winding_count2(std::move(b.winding_count2)),
63           winding_delta(std::move(b.winding_delta)),
64           poly_type(std::move(b.poly_type)),
65           side(std::move(b.side)) {
66     }
67 
68     bound(bound<T>const& b) = delete;
69     bound<T>& operator=(bound<T> const&) = delete;
70 
71 };
72 
73 #ifdef DEBUG
74 
75 template <class charT, class traits, typename T>
operator <<(std::basic_ostream<charT,traits> & out,const bound<T> & bnd)76 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& out,
77                                                      const bound<T>& bnd) {
78     out << "    Bound: " << &bnd << std::endl;
79     out << "        current_x: " << bnd.current_x << std::endl;
80     out << "        last_point: " << bnd.last_point.x << ", " << bnd.last_point.y << std::endl;
81     out << *(bnd.current_edge);
82     out << "        winding count: " << bnd.winding_count << std::endl;
83     out << "        winding_count2: " << bnd.winding_count2 << std::endl;
84     out << "        winding_delta: " << static_cast<int>(bnd.winding_delta) << std::endl;
85     out << "        maximum_bound: " << bnd.maximum_bound << std::endl;
86     if (bnd.side == edge_left) {
87         out << "        side: left" << std::endl;
88     } else {
89         out << "        side: right" << std::endl;
90     }
91     out << "        ring: " << bnd.ring << std::endl;
92     if (bnd.ring) {
93         out << "        ring index: " << bnd.ring->ring_index << std::endl;
94     }
95     return out;
96 }
97 
98 #endif
99 }
100 }
101 }
102