11/* ******************************************************************************
22* Author : Angus Johnson *
33* Date : 12 May 2024 *
4- * Website : http ://www.angusj.com *
4+ * Website : https ://www.angusj.com *
55* Copyright : Angus Johnson 2010-2024 *
66* 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 *
88*******************************************************************************/
99
1010#ifndef CLIPPER_CORE_H
1111#define CLIPPER_CORE_H
1212
13+ #include " clipper2/clipper.version.h"
1314#include < cstdint>
14- #include < cstdlib>
15- #include < cmath>
1615#include < vector>
1716#include < string>
1817#include < iostream>
1918#include < algorithm>
20- #include < climits>
2119#include < numeric>
22- #include < optional>
23- #include " clipper2/clipper.version.h"
20+ #include < cmath>
2421
2522#define CLIPPER2_THROW (exception ) std::abort()
2623
@@ -33,7 +30,7 @@ namespace Clipper2Lib
3330 public:
3431 explicit Clipper2Exception (const char * description) :
3532 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 (); }
3734 private:
3835 std::string m_descr;
3936 };
@@ -90,6 +87,9 @@ namespace Clipper2Lib
9087 CLIPPER2_THROW (Clipper2Exception (undefined_error));
9188 case range_error_i:
9289 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" ));
9393 }
9494#else
9595 if (error_code) {}; // only to stop compiler 'parameter not used' warning
@@ -109,17 +109,21 @@ namespace Clipper2Lib
109109 // https://en.wikipedia.org/wiki/Nonzero-rule
110110 enum class FillRule { EvenOdd, NonZero, Positive, Negative };
111111
112+ #ifdef USINGZ
113+ using z_type = int64_t ;
114+ #endif
115+
112116 // Point ------------------------------------------------------------------------
113117
114118 template <typename T>
115119 struct Point {
116120 T x;
117121 T y;
118122#ifdef USINGZ
119- int64_t z;
123+ z_type z;
120124
121125 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 )
123127 {
124128 if constexpr (std::is_integral_v<T> &&
125129 is_round_invocable<T2>::value && !std::is_integral_v<T2>)
@@ -139,7 +143,7 @@ namespace Clipper2Lib
139143 explicit Point () : x(0 ), y(0 ), z(0 ) {};
140144
141145 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 )
143147 {
144148 Init (x_, y_);
145149 z = z_;
@@ -152,7 +156,7 @@ namespace Clipper2Lib
152156 }
153157
154158 template <typename T2>
155- explicit Point (const Point<T2>& p, int64_t z_)
159+ explicit Point (const Point<T2>& p, z_type z_)
156160 {
157161 Init (p.x , p.y , z_);
158162 }
@@ -162,7 +166,7 @@ namespace Clipper2Lib
162166 return Point (x * scale, y * scale, z);
163167 }
164168
165- void SetZ (const int64_t z_value) { z = z_value; }
169+ void SetZ (const z_type z_value) { z = z_value; }
166170
167171 friend std::ostream& operator <<(std::ostream& os, const Point& point)
168172 {
@@ -326,10 +330,10 @@ namespace Clipper2Lib
326330 {
327331 Path<T> result;
328332 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);
333337 return result;
334338 }
335339
@@ -364,6 +368,22 @@ namespace Clipper2Lib
364368 top == other.top && bottom == other.bottom ;
365369 }
366370
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+
367387 friend std::ostream& operator <<(std::ostream& os, const Rect<T>& rect) {
368388 os << " (" << rect.left << " ," << rect.top << " ," << rect.right << " ," << rect.bottom << " ) " ;
369389 return os;
@@ -597,13 +617,13 @@ namespace Clipper2Lib
597617 result.reserve (path.size ());
598618 typename Path<T>::const_iterator path_iter = path.cbegin ();
599619 Point<T> first_pt = *path_iter++, last_pt = first_pt;
600- result.push_back (first_pt);
620+ result.emplace_back (first_pt);
601621 for (; path_iter != path.cend (); ++path_iter)
602622 {
603623 if (!NearEqual (*path_iter, last_pt, max_dist_sqrd))
604624 {
605625 last_pt = *path_iter;
606- result.push_back (last_pt);
626+ result.emplace_back (last_pt);
607627 }
608628 }
609629 if (!is_closed_path) return result;
@@ -621,7 +641,7 @@ namespace Clipper2Lib
621641 for (typename Paths<T>::const_iterator paths_citer = paths.cbegin ();
622642 paths_citer != paths.cend (); ++paths_citer)
623643 {
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) ));
625645 }
626646 return result;
627647 }
@@ -697,11 +717,11 @@ namespace Clipper2Lib
697717 {
698718// Work around LLVM issue: https://github.com/llvm/llvm-project/issues/16778
699719// 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
705725 // nb: unsigned values needed for calculating overflow carry
706726 const auto abs_a = static_cast <uint64_t >(std::abs (a));
707727 const auto abs_b = static_cast <uint64_t >(std::abs (b));
@@ -768,7 +788,7 @@ namespace Clipper2Lib
768788 const Point<T>& line1, const Point<T>& line2)
769789 {
770790 // 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
772792 double a = static_cast <double >(pt.x - line1.x );
773793 double b = static_cast <double >(pt.y - line1.y );
774794 double c = static_cast <double >(line2.x - line1.x );
0 commit comments