// Copyright (c) 2019,2025 // GeometryFactory (France) // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Simon Giraudot // // Test file: test/Kernel_23/test_hash_functions.cpp #ifndef CGAL_KERNEL_HASH_FUNCTIONS_H #define CGAL_KERNEL_HASH_FUNCTIONS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace CGAL { using boost::hash_value; template inline constexpr bool has_rep_tag_v = false; template inline constexpr bool has_rep_tag_v> = true; template struct Rep_tag { using type = void; }; template struct Rep_tag>> { using type = typename K::Rep_tag; }; template using Rep_tag_t = typename Rep_tag::type; template inline constexpr bool is_Cartesian_v = std::is_same, Cartesian_tag>::value; template struct Is_kernel_hashable : public std::false_type {}; template struct Is_kernel_hashable()))>> : public std::true_type {}; template inline constexpr bool is_kernel_hashable_v = Is_kernel_hashable::value; template using enable_if_Cartesian_and_hashable_t = std::enable_if_t && is_kernel_hashable_v, T>; template inline enable_if_Cartesian_and_hashable_t hash_value (const Aff_transformation_2& transform) { std::size_t result = hash_value(transform.cartesian(0,0)); for(int i=0; i < 3; ++i) for(int j=0; j < 3; ++j) // Skip (0,0) as it was already used to initialize the hash if (!(i == 0 && j == 0)) boost::hash_combine(result, hash_value(transform.cartesian(i,j))); return result; } inline std::size_t hash_value (const Bbox_2& bbox) { std::size_t result = hash_value(bbox.xmin()); boost::hash_combine(result, hash_value(bbox.xmax())); boost::hash_combine(result, hash_value(bbox.ymin())); boost::hash_combine(result, hash_value(bbox.ymax())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Circle_2& circle) { std::size_t result = hash_value(circle.center()); boost::hash_combine(result, hash_value(circle.squared_radius())); boost::hash_combine(result, hash_value(circle.orientation())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Iso_rectangle_2& iso_rectangle) { std::size_t result = hash_value((iso_rectangle.min)()); boost::hash_combine(result, hash_value((iso_rectangle.max)())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Point_2& point) { std::size_t result = hash_value(point.x()); boost::hash_combine(result, hash_value(point.y())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Segment_2& segment) { std::size_t result = hash_value(segment.source()); boost::hash_combine(result, hash_value(segment.target())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Vector_2& vector) { std::size_t result = hash_value(vector.x()); boost::hash_combine(result, hash_value(vector.y())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Weighted_point_2& weighed_point) { std::size_t result = hash_value(weighed_point.point()); boost::hash_combine(result, hash_value(weighed_point.weight())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Aff_transformation_3& transform) { std::size_t result = hash_value(transform.cartesian(0,0)); for(int i = 0; i < 3; ++i) for(int j = (i == 0 ? 1 : 0); j < 4; ++j) boost::hash_combine(result, hash_value(transform.cartesian(i,j))); return result; } inline std::size_t hash_value (const Bbox_3& bbox) { std::size_t result = hash_value(bbox.xmin()); boost::hash_combine(result, hash_value(bbox.xmax())); boost::hash_combine(result, hash_value(bbox.ymin())); boost::hash_combine(result, hash_value(bbox.ymax())); boost::hash_combine(result, hash_value(bbox.zmin())); boost::hash_combine(result, hash_value(bbox.zmax())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Iso_cuboid_3& iso_cuboid) { std::size_t result = hash_value((iso_cuboid.min)()); boost::hash_combine(result, hash_value((iso_cuboid.max)())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Point_3& point) { std::size_t result = hash_value(point.x()); boost::hash_combine(result, hash_value(point.y())); boost::hash_combine(result, hash_value(point.z())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Segment_3& segment) { std::size_t result = hash_value(segment.source()); boost::hash_combine(result, hash_value(segment.target())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Sphere_3& sphere) { std::size_t result = hash_value(sphere.center()); boost::hash_combine(result, hash_value(sphere.squared_radius())); boost::hash_combine(result, hash_value(sphere.orientation())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Vector_3& vector) { std::size_t result = hash_value(vector.x()); boost::hash_combine(result, hash_value(vector.y())); boost::hash_combine(result, hash_value(vector.z())); return result; } template inline enable_if_Cartesian_and_hashable_t hash_value (const Weighted_point_3& weighed_point) { std::size_t result = hash_value(weighed_point.point()); boost::hash_combine(result, hash_value(weighed_point.weight())); return result; } struct Forward_to_hash_value { template std::size_t operator()(T&& t) const { using boost::hash_value; return hash_value(std::forward(t)); } }; template struct Maybe_forward_to_hash_value { Maybe_forward_to_hash_value() = delete; Maybe_forward_to_hash_value(const Maybe_forward_to_hash_value&) = delete; }; template struct Maybe_forward_to_hash_value>> : public Forward_to_hash_value {}; } //namespace CGAL // overloads of std::hash used for using std::unordered_[set/map] on CGAL Kernel objects namespace std { template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template <> struct hash : CGAL::Forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template struct hash> : CGAL::Maybe_forward_to_hash_value {}; template <> struct hash : CGAL::Forward_to_hash_value {}; } // namespace std #endif // CGAL_KERNEL_HASH_FUNCTIONS_H