1
1
/* ******************************************************************************
2
2
* Author : Angus Johnson *
3
3
* Date : 12 May 2024 *
4
- * Website : http ://www.angusj.com *
4
+ * Website : https ://www.angusj.com *
5
5
* Copyright : Angus Johnson 2010-2024 *
6
6
* Purpose : Core Clipper Library structures and functions *
7
- * License : http ://www.boost.org/LICENSE_1_0.txt *
7
+ * License : https ://www.boost.org/LICENSE_1_0.txt *
8
8
*******************************************************************************/
9
9
10
10
#ifndef CLIPPER_CORE_H
11
11
#define CLIPPER_CORE_H
12
12
13
+ #include " clipper2/clipper.version.h"
13
14
#include < cstdint>
14
- #include < cstdlib>
15
- #include < cmath>
16
15
#include < vector>
17
16
#include < string>
18
17
#include < iostream>
19
18
#include < algorithm>
20
- #include < climits>
21
19
#include < numeric>
22
- #include < optional>
23
- #include " clipper2/clipper.version.h"
20
+ #include < cmath>
24
21
25
22
#define CLIPPER2_THROW (exception ) std::abort()
26
23
@@ -33,7 +30,7 @@ namespace Clipper2Lib
33
30
public:
34
31
explicit Clipper2Exception (const char * description) :
35
32
m_descr(description) {}
36
- virtual const char * what () const throw() override { return m_descr.c_str (); }
33
+ virtual const char * what () const noexcept override { return m_descr.c_str (); }
37
34
private:
38
35
std::string m_descr;
39
36
};
@@ -90,6 +87,9 @@ namespace Clipper2Lib
90
87
CLIPPER2_THROW (Clipper2Exception (undefined_error));
91
88
case range_error_i:
92
89
CLIPPER2_THROW (Clipper2Exception (range_error));
90
+ // Should never happen, but adding this to stop a compiler warning
91
+ default :
92
+ CLIPPER2_THROW (Clipper2Exception (" Unknown error" ));
93
93
}
94
94
#else
95
95
if (error_code) {}; // only to stop compiler 'parameter not used' warning
@@ -109,17 +109,21 @@ namespace Clipper2Lib
109
109
// https://en.wikipedia.org/wiki/Nonzero-rule
110
110
enum class FillRule { EvenOdd, NonZero, Positive, Negative };
111
111
112
+ #ifdef USINGZ
113
+ using z_type = int64_t ;
114
+ #endif
115
+
112
116
// Point ------------------------------------------------------------------------
113
117
114
118
template <typename T>
115
119
struct Point {
116
120
T x;
117
121
T y;
118
122
#ifdef USINGZ
119
- int64_t z;
123
+ z_type z;
120
124
121
125
template <typename T2>
122
- inline void Init (const T2 x_ = 0 , const T2 y_ = 0 , const int64_t z_ = 0 )
126
+ inline void Init (const T2 x_ = 0 , const T2 y_ = 0 , const z_type z_ = 0 )
123
127
{
124
128
if constexpr (std::is_integral_v<T> &&
125
129
is_round_invocable<T2>::value && !std::is_integral_v<T2>)
@@ -139,7 +143,7 @@ namespace Clipper2Lib
139
143
explicit Point () : x(0 ), y(0 ), z(0 ) {};
140
144
141
145
template <typename T2>
142
- Point (const T2 x_, const T2 y_, const int64_t z_ = 0 )
146
+ Point (const T2 x_, const T2 y_, const z_type z_ = 0 )
143
147
{
144
148
Init (x_, y_);
145
149
z = z_;
@@ -152,7 +156,7 @@ namespace Clipper2Lib
152
156
}
153
157
154
158
template <typename T2>
155
- explicit Point (const Point <T2>& p, int64_t z_)
159
+ explicit Point (const Point <T2>& p, z_type z_)
156
160
{
157
161
Init (p.x , p.y , z_);
158
162
}
@@ -162,7 +166,7 @@ namespace Clipper2Lib
162
166
return Point (x * scale, y * scale, z);
163
167
}
164
168
165
- void SetZ (const int64_t z_value) { z = z_value; }
169
+ void SetZ (const z_type z_value) { z = z_value; }
166
170
167
171
friend std::ostream& operator <<(std::ostream& os, const Point & point)
168
172
{
@@ -326,10 +330,10 @@ namespace Clipper2Lib
326
330
{
327
331
Path<T> result;
328
332
result.reserve (4 );
329
- result.push_back ( Point <T>( left, top) );
330
- result.push_back ( Point <T>( right, top) );
331
- result.push_back ( Point <T>( right, bottom) );
332
- result.push_back ( Point <T>( left, bottom) );
333
+ result.emplace_back ( left, top);
334
+ result.emplace_back ( right, top);
335
+ result.emplace_back ( right, bottom);
336
+ result.emplace_back ( left, bottom);
333
337
return result;
334
338
}
335
339
@@ -364,6 +368,22 @@ namespace Clipper2Lib
364
368
top == other.top && bottom == other.bottom ;
365
369
}
366
370
371
+ Rect <T>& operator +=(const Rect <T>& other)
372
+ {
373
+ left = (std::min)(left, other.left );
374
+ top = (std::min)(top, other.top );
375
+ right = (std::max)(right, other.right );
376
+ bottom = (std::max)(bottom, other.bottom );
377
+ return *this ;
378
+ }
379
+
380
+ Rect <T> operator +(const Rect <T>& other) const
381
+ {
382
+ Rect <T> result = *this ;
383
+ result += other;
384
+ return result;
385
+ }
386
+
367
387
friend std::ostream& operator <<(std::ostream& os, const Rect <T>& rect) {
368
388
os << " (" << rect.left << " ," << rect.top << " ," << rect.right << " ," << rect.bottom << " ) " ;
369
389
return os;
@@ -597,13 +617,13 @@ namespace Clipper2Lib
597
617
result.reserve (path.size ());
598
618
typename Path<T>::const_iterator path_iter = path.cbegin ();
599
619
Point <T> first_pt = *path_iter++, last_pt = first_pt;
600
- result.push_back (first_pt);
620
+ result.emplace_back (first_pt);
601
621
for (; path_iter != path.cend (); ++path_iter)
602
622
{
603
623
if (!NearEqual (*path_iter, last_pt, max_dist_sqrd))
604
624
{
605
625
last_pt = *path_iter;
606
- result.push_back (last_pt);
626
+ result.emplace_back (last_pt);
607
627
}
608
628
}
609
629
if (!is_closed_path) return result;
@@ -621,7 +641,7 @@ namespace Clipper2Lib
621
641
for (typename Paths<T>::const_iterator paths_citer = paths.cbegin ();
622
642
paths_citer != paths.cend (); ++paths_citer)
623
643
{
624
- result.push_back ( StripNearEqual (*paths_citer, max_dist_sqrd, is_closed_path));
644
+ result.emplace_back ( std::move ( StripNearEqual (*paths_citer, max_dist_sqrd, is_closed_path) ));
625
645
}
626
646
return result;
627
647
}
@@ -697,11 +717,11 @@ namespace Clipper2Lib
697
717
{
698
718
// Work around LLVM issue: https://github.com/llvm/llvm-project/issues/16778
699
719
// Details: https://github.com/godotengine/godot/pull/95964#issuecomment-2306581804
700
- // #if (defined(__clang__) || defined(__GNUC__)) && UINTPTR_MAX >= UINT64_MAX
701
- // const auto ab = static_cast<__int128_t>(a) * static_cast<__int128_t>(b);
702
- // const auto cd = static_cast<__int128_t>(c) * static_cast<__int128_t>(d);
703
- // return ab == cd;
704
- // #else
720
+ // #if (defined(__clang__) || defined(__GNUC__)) && UINTPTR_MAX >= UINT64_MAX
721
+ // const auto ab = static_cast<__int128_t>(a) * static_cast<__int128_t>(b);
722
+ // const auto cd = static_cast<__int128_t>(c) * static_cast<__int128_t>(d);
723
+ // return ab == cd;
724
+ // #else
705
725
// nb: unsigned values needed for calculating overflow carry
706
726
const auto abs_a = static_cast <uint64_t >(std::abs (a));
707
727
const auto abs_b = static_cast <uint64_t >(std::abs (b));
@@ -768,7 +788,7 @@ namespace Clipper2Lib
768
788
const Point <T>& line1, const Point <T>& line2)
769
789
{
770
790
// perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²)
771
- // see http ://en.wikipedia.org/wiki/Perpendicular_distance
791
+ // see https ://en.wikipedia.org/wiki/Perpendicular_distance
772
792
double a = static_cast <double >(pt.x - line1.x );
773
793
double b = static_cast <double >(pt.y - line1.y );
774
794
double c = static_cast <double >(line2.x - line1.x );
0 commit comments