20namespace pgl::detail {
23inline void hashCombine(std::size_t& seed,
const T& value) {
24#if defined(__SIZEOF_INT128__)
28 if constexpr (std::is_same_v<T, __int128_t> || std::is_same_v<T, __uint128_t>) {
29 const auto bits =
static_cast<__uint128_t
>(value);
30 hashCombine(seed,
static_cast<std::uint64_t
>(bits));
31 hashCombine(seed,
static_cast<std::uint64_t
>(bits >> 64));
35 seed ^= std::hash<T>{}(value) + 0x9e3779b9u + (seed << 6u) + (seed >> 2u);
47 template <
class Number,
class Label>
48 struct hash<pgl::
Point<Number, Label>> {
49 std::size_t operator()(
const pgl::Point<Number, Label>& point)
const {
50 std::size_t seed = pgl::detail::shapeRank<pgl::Point<Number, Label>>;
51 pgl::detail::hashCombine(seed, point.
x());
52 pgl::detail::hashCombine(seed, point.
y());
70 pgl::detail::hashCombine(seed, reduced.
numerator());
71 pgl::detail::hashCombine(seed, reduced.
denominator());
80 struct hash<pgl::BigInt> {
81 std::size_t operator()(
const pgl::BigInt& b)
const noexcept {
82 std::size_t seed = 15;
83 pgl::detail::hashCombine(seed, b.negative_);
84 pgl::detail::hashCombine(seed, b.small_);
85 for (
const auto& limb : b.limbs_) {
86 pgl::detail::hashCombine(seed, limb);
95 template <
class Po
intType,
class LabelType>
96 struct hash<pgl::
Segment<PointType, LabelType>> {
98 std::size_t seed = pgl::detail::shapeRank<pgl::Segment<PointType, LabelType>>;
99 pgl::detail::hashCombine(seed, segment.
min());
100 pgl::detail::hashCombine(seed, segment.
max());
108 template <
class Po
intType,
class LabelType>
111 std::size_t seed = pgl::detail::shapeRank<pgl::OrientedSegment<PointType, LabelType>>;
112 pgl::detail::hashCombine(seed, segment.
source());
113 pgl::detail::hashCombine(seed, segment.
target());
122 template <
class Po
intType,
class LabelType>
123 struct hash<pgl::
Line<PointType, LabelType>> {
125 std::size_t seed = pgl::detail::shapeRank<pgl::Line<PointType, LabelType>>;
127 pgl::detail::hashCombine(seed, line.
min());
130 pgl::detail::hashCombine(seed, line.
min().x());
139 const auto [anum,bnum,den] = line.template dualCoordinates<N>();
140 pgl::detail::hashCombine(seed, anum / den);
141 pgl::detail::hashCombine(seed, bnum / den);
148 using IntRational = pgl::detail::promoted_number_t<N>;
150 const auto [anum,bnum,den] = line.template dualCoordinates<IntRational>();
152 pgl::detail::hashCombine(seed, RationalKey(anum,den));
153 pgl::detail::hashCombine(seed, RationalKey(bnum,den));
164 template <
class Po
intType,
class LabelType>
167 std::size_t seed = pgl::detail::shapeRank<pgl::OrientedLine<PointType, LabelType>>
170 pgl::detail::hashCombine(seed,
static_cast<T
>(line));
179 template <
class Po
intType,
class LabelType>
180 struct hash<pgl::
Ray<PointType, LabelType>> {
182 std::size_t seed = pgl::detail::shapeRank<pgl::Ray<PointType, LabelType>>;
183 pgl::detail::hashCombine(seed, ray.
source());
185 pgl::detail::hashCombine(seed,
static_cast<T
>(ray));
193 template <
class Po
intType,
class LabelType>
194 struct hash<pgl::
Halfplane<PointType, LabelType>> {
196 std::size_t seed = pgl::detail::shapeRank<pgl::Halfplane<PointType, LabelType>>
199 pgl::detail::hashCombine(seed,
static_cast<T
>(halfplane));
207 template <
class Po
intType,
class LabelType>
208 struct hash<pgl::
Rectangle<PointType, LabelType>> {
210 std::size_t seed = pgl::detail::shapeRank<pgl::Rectangle<PointType, LabelType>>;
211 pgl::detail::hashCombine(seed, rectangle.
min());
212 pgl::detail::hashCombine(seed, rectangle.
max());
220 template <
class Po
intType,
class LabelType>
221 struct hash<pgl::
Triangle<PointType, LabelType>> {
223 std::size_t seed = pgl::detail::shapeRank<pgl::Triangle<PointType, LabelType>>;
224 pgl::detail::hashCombine(seed, triangle.
a());
225 pgl::detail::hashCombine(seed, triangle.
b());
226 pgl::detail::hashCombine(seed, triangle.
c());
234 template <
class Po
intType,
class LabelType>
235 struct hash<pgl::
Disk<PointType, LabelType>> {
237 std::size_t seed = pgl::detail::shapeRank<pgl::Disk<PointType, LabelType>>;
240 pgl::detail::hashCombine(seed, disk.
a());
241 pgl::detail::hashCombine(seed, disk.
b());
242 pgl::detail::hashCombine(seed, disk.
c());
244 using Number =
typename std::decay_t<
decltype(disk)>::NumberType;
245 pgl::detail::hashCombine(seed, disk.template center<Number>());
246 pgl::detail::hashCombine(seed, disk.template squaredRadius<Number>());
255 template <
class Po
intType,
class LabelType>
256 struct hash<pgl::
Convex<PointType, LabelType>> {
259 if (convex.hash_ != Shape::hashUnset_) {
262 std::size_t seed = pgl::detail::shapeRank<Shape>;
263 for (
const auto& vertex : convex) {
264 pgl::detail::hashCombine(seed, vertex);
268 if (seed == Shape::hashUnset_) {
269 seed = Shape::hashUnset_ - 1;
279 template <
class Po
intType,
class LabelType>
280 struct hash<pgl::
Polygon<PointType, LabelType>> {
283 if (polygon.hash_ != Shape::hashUnset_) {
284 return polygon.hash_;
286 std::size_t seed = pgl::detail::shapeRank<Shape>;
287 for (
const auto& vertex : polygon) {
288 pgl::detail::hashCombine(seed, vertex);
292 if (seed == Shape::hashUnset_) {
293 seed = Shape::hashUnset_ - 1;
295 polygon.hash_ = seed;
306 template <
class Po
intType,
class LabelType>
310 if (region.hash_ != Shape::hashUnset_) {
313 std::size_t seed = pgl::detail::shapeRank<Shape>;
314 pgl::detail::hashCombine(seed, region.
outer());
315 for (
const auto& hole : region.
holes()) {
316 pgl::detail::hashCombine(seed, hole);
320 if (seed == Shape::hashUnset_) {
321 seed = Shape::hashUnset_ - 1;
334 template <
class Po
intType,
class LabelType>
335 struct hash<pgl::
PolygonSet<PointType, LabelType>> {
338 if (set.hash_ != Shape::hashUnset_) {
341 std::size_t seed = pgl::detail::shapeRank<Shape>;
342 for (
const auto& component : set.
components()) {
343 pgl::detail::hashCombine(seed, component);
347 if (seed == Shape::hashUnset_) {
348 seed = Shape::hashUnset_ - 1;
358 template <
class Po
intType,
class LabelType>
362 if (region.hash_ != Shape::hashUnset_) {
365 std::size_t seed = pgl::detail::shapeRank<Shape>;
366 pgl::detail::hashCombine(seed, region.
empty());
367 for (
const auto& halfplane : region) {
368 pgl::detail::hashCombine(seed, halfplane);
372 if (seed == Shape::hashUnset_) {
373 seed = Shape::hashUnset_ - 1;
383 template <
class Po
intType,
class LabelType,
class Storage>
384 struct hash<pgl::
MonotoneChain<PointType, LabelType, Storage>> {
387 if (chain.hash_ != Shape::hashUnset_) {
390 std::size_t seed = pgl::detail::shapeRank<Shape>;
391 for (
const auto& vertex : chain) {
392 pgl::detail::hashCombine(seed, vertex);
396 if (seed == Shape::hashUnset_) {
397 seed = Shape::hashUnset_ - 1;
407 template <
class Po
intType,
class LabelType>
408 struct hash<pgl::
Polyline<PointType, LabelType>> {
411 if (polyline.hash_ != Shape::hashUnset_) {
412 return polyline.hash_;
414 std::size_t seed = pgl::detail::shapeRank<Shape>;
417 const bool reversed = !polyline.storedIsCanonical();
418 for (std::size_t i = 0; i < polyline.
size(); ++i) {
419 pgl::detail::hashCombine(seed, polyline.canonicalAt(i, reversed));
423 if (seed == Shape::hashUnset_) {
424 seed = Shape::hashUnset_ - 1;
426 polyline.hash_ = seed;
434 template <
class Po
intType>
435 struct hash<pgl::EmptyShape<PointType>> {
436 std::size_t operator()(
const pgl::EmptyShape<PointType>&)
const {
437 return pgl::detail::shapeRank<pgl::EmptyShape<PointType>>;
444 template <
class Po
intType>
445 struct hash<pgl::
Shape<PointType>> {
447 std::size_t seed = 12;
448 pgl::detail::hashCombine(seed, shape.
variant().index());
450 [&seed](
const auto& value) {
451 pgl::detail::hashCombine(seed, value);
Lightweight SVG canvas for drawing Pangolin shapes.
constexpr Int numerator() const noexcept
Get numerator (in lowest terms).
Definition rational.hpp:359
constexpr Int denominator() const noexcept
Get denominator (in lowest terms).
Definition rational.hpp:365
Forward declarations for core numeric and geometry types.
HalfplaneIntersection() -> HalfplaneIntersection< Point<>, NoLabel >
Definition halfplaneintersection.hpp:2308
Rectangle() -> Rectangle< Point<>, NoLabel >
Definition rectangle.hpp:2384
constexpr bool is_Rational_v
Definition rational.hpp:37
Line() -> Line< Point<>, NoLabel >
PolygonSet() -> PolygonSet< Point<>, NoLabel >
Definition polygonset.hpp:1699
OrientedSegment() -> OrientedSegment< Point<>, NoLabel >
Rational(T) -> Rational< T >
MonotoneChain() -> MonotoneChain< Point<>, NoLabel >
Definition monotonechain.hpp:2439
Shape(const std::variant< T, Ts... > &) -> Shape< detail::shape_point_type_t< T > >
PolygonWithHoles() -> PolygonWithHoles< Point<>, NoLabel >
Definition polygonwithholes.hpp:3093
Convex() -> Convex< Point<>, NoLabel >
Definition convex.hpp:3311
Segment() -> Segment< Point<>, NoLabel >
Halfplane() -> Halfplane< Point<>, NoLabel >
Polyline() -> Polyline< Point<>, NoLabel >
Definition polyline.hpp:2369
Ray() -> Ray< Point<>, NoLabel >
Polygon() -> Polygon< Point<>, NoLabel >
Definition polygon.hpp:3200
Disk() -> Disk< Point<>, NoLabel >
Deduces a default disk with Point<> boundary points and no label.
Definition disk.hpp:1691
OrientedLine() -> OrientedLine< Point<>, NoLabel >
Triangle() -> Triangle< Point<>, NoLabel >
Definition triangle.hpp:2029
Numeric concepts and helpers shared by exact geometry operations.
constexpr bool isDegenerate() const
Returns whether the three boundary points are collinear.
Definition disk.hpp:348
constexpr const PointType & c() const
Returns the third boundary point in canonical order.
Definition disk.hpp:244
constexpr const PointType & a() const
Returns the first boundary point (lexicographically smallest).
Definition disk.hpp:228
constexpr const PointType & b() const
Returns the second boundary point in canonical order.
Definition disk.hpp:235
constexpr bool empty() const
Returns whether the region is the empty set.
Definition halfplaneintersection.hpp:649
constexpr const PointType & target() const
Returns the target boundary point.
Definition halfplane.hpp:193
constexpr const PointType & source() const
Returns the source boundary point.
Definition halfplane.hpp:181
constexpr bool isVertical() const
Returns whether the line is vertical.
Definition predicates.hpp:461
constexpr const PointType & min() const
Returns the smallest stored defining point.
Definition line.hpp:180
PointType::NumberType NumberType
Definition line.hpp:54
constexpr bool isDegenerate() const
Returns whether the defining points coincide.
Definition predicates.hpp:451
constexpr const PointType & target() const
Returns the target defining point.
Definition orientedline.hpp:195
constexpr const PointType & source() const
Returns the source defining point.
Definition orientedline.hpp:183
constexpr const PointType & source() const
Returns the source endpoint.
Definition orientedsegment.hpp:178
constexpr const PointType & target() const
Returns the target endpoint.
Definition orientedsegment.hpp:190
constexpr const NumberType & x() const
Returns the x coordinate.
Definition point.hpp:193
constexpr const NumberType & y() const
Returns the y coordinate.
Definition point.hpp:205
constexpr const std::vector< ComponentType > & components() const
Returns the components in canonical order.
Definition polygonset.hpp:277
constexpr const PolygonType & outer() const
Returns the outer boundary.
Definition polygonwithholes.hpp:178
constexpr const std::vector< PolygonType > & holes() const
Returns the holes in canonical order.
Definition polygonwithholes.hpp:202
constexpr std::size_t size() const
Returns the number of vertices in the polyline.
Definition polyline.hpp:388
constexpr const PointType & source() const
Returns the source point of the ray.
Definition ray.hpp:181
constexpr const PointType & min() const
Returns the minimum corner (min x, min y).
Definition rectangle.hpp:347
constexpr const PointType & max() const
Returns the maximum corner (max x, max y).
Definition rectangle.hpp:359
constexpr const PointType & max() const
Returns the largest stored endpoint.
Definition segment.hpp:199
constexpr const PointType & min() const
Returns the smallest stored endpoint.
Definition segment.hpp:190
constexpr const Variant & variant() const
Returns the underlying variant.
Definition shape.hpp:264
constexpr const PointType & b() const
Returns the second vertex.
Definition triangle.hpp:217
constexpr const PointType & a() const
Returns the first vertex.
Definition triangle.hpp:208
constexpr const PointType & c() const
Returns the third vertex.
Definition triangle.hpp:226