From f73430626f9316258b447a7e342349178f2ebd2b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 21 Nov 2024 08:56:18 +0100 Subject: [PATCH] fix(Exception): add basic object exceptions --- include/geode/basic/assert.hpp | 5 +++ .../geode/geometry/basic_objects/segment.hpp | 38 +++++++++++++++++++ .../geometry/basic_objects/tetrahedron.hpp | 25 ++++++++++++ .../geode/geometry/basic_objects/triangle.hpp | 34 +++++++++++++++++ include/geode/geometry/point.hpp | 6 +-- src/geode/basic/assert.cpp | 20 ++++++++++ src/geode/geometry/basic_objects/segment.cpp | 8 ++++ .../geometry/basic_objects/tetrahedron.cpp | 11 ++++++ src/geode/geometry/basic_objects/triangle.cpp | 10 +++++ src/geode/geometry/bounding_box.cpp | 2 +- 10 files changed, 155 insertions(+), 4 deletions(-) diff --git a/include/geode/basic/assert.hpp b/include/geode/basic/assert.hpp index 0978ee146..223de19c6 100644 --- a/include/geode/basic/assert.hpp +++ b/include/geode/basic/assert.hpp @@ -102,6 +102,11 @@ namespace geode * Always return 1. */ int opengeode_basic_api geode_lippincott(); + + /*! + * Catch all exceptions and rethrow an OpenGeodeException + */ + void opengeode_basic_api throw_lippincott(); } // namespace geode #ifdef OPENGEODE_DEBUG diff --git a/include/geode/geometry/basic_objects/segment.hpp b/include/geode/geometry/basic_objects/segment.hpp index da9ecbd25..7eb773706 100644 --- a/include/geode/geometry/basic_objects/segment.hpp +++ b/include/geode/geometry/basic_objects/segment.hpp @@ -61,6 +61,7 @@ namespace geode [[nodiscard]] const std::array< PointType, 2 >& vertices() const; [[nodiscard]] BoundingBox< dimension > bounding_box() const; [[nodiscard]] bool is_degenerated() const; + [[nodiscard]] std::string string() const; private: std::array< PointType, 2 > vertices_; @@ -102,4 +103,41 @@ namespace geode Segment< dimension >&& other ) noexcept; }; ALIAS_1D_AND_2D_AND_3D( Segment ); + + template < index_t dimension > + class OpenGeodeSegmentException : public OpenGeodeException + { + public: + template < typename... Args > + explicit OpenGeodeSegmentException( + Segment< dimension > segment_in, const Args&... message ) + : OpenGeodeException{ absl::StrCat( + message..., " at ", segment_in.string() ) }, + segment{ std::move( segment_in ) } + { + } + + OwnerSegment< dimension > segment; + }; + ALIAS_1D_AND_2D_AND_3D( OpenGeodeSegmentException ); } // namespace geode + +// NOLINTNEXTLINE +#define OPENGEODE_SEGMENT_EXCEPTION( dimension, condition, segment, ... ) \ + if( ABSL_PREDICT_FALSE( !( condition ) ) ) \ + throw geode::OpenGeodeSegmentException< dimension > \ + { \ + segment, __VA_ARGS__ \ + } + +// NOLINTNEXTLINE +#define OPENGEODE_SEGMENT1D_EXCEPTION( condition, segment, ... ) \ + OPENGEODE_SEGMENT_EXCEPTION( 1, condition, segment, __VA_ARGS__ ) + +// NOLINTNEXTLINE +#define OPENGEODE_SEGMENT2D_EXCEPTION( condition, segment, ... ) \ + OPENGEODE_SEGMENT_EXCEPTION( 2, condition, segment, __VA_ARGS__ ) + +// NOLINTNEXTLINE +#define OPENGEODE_SEGMENT3D_EXCEPTION( condition, segment, ... ) \ + OPENGEODE_SEGMENT_EXCEPTION( 3, condition, segment, __VA_ARGS__ ) diff --git a/include/geode/geometry/basic_objects/tetrahedron.hpp b/include/geode/geometry/basic_objects/tetrahedron.hpp index 9b60addc2..b4c2759ec 100644 --- a/include/geode/geometry/basic_objects/tetrahedron.hpp +++ b/include/geode/geometry/basic_objects/tetrahedron.hpp @@ -65,6 +65,7 @@ namespace geode [[nodiscard]] const std::array< PointType, 4 >& vertices() const; [[nodiscard]] BoundingBox3D bounding_box() const; [[nodiscard]] bool is_degenerated() const; + [[nodiscard]] std::string string() const; private: std::array< PointType, 4 > vertices_; @@ -104,4 +105,28 @@ namespace geode Tetrahedron( Tetrahedron&& other ) noexcept; Tetrahedron& operator=( Tetrahedron&& other ) noexcept; }; + + class OpenGeodeTetrahedronException : public OpenGeodeException + { + public: + template < typename... Args > + explicit OpenGeodeTetrahedronException( + Tetrahedron tetrahedron_in, const Args&... message ) + : OpenGeodeException{ absl::StrCat( + message..., " at ", tetrahedron_in.string() ) }, + tetrahedron{ std::move( tetrahedron_in ) } + { + } + + OwnerTetrahedron tetrahedron; + }; } // namespace geode + +// NOLINTNEXTLINE +#define OPENGEODE_TETRAHEDRON_EXCEPTION( \ + dimension, condition, tetrahedron, ... ) \ + if( ABSL_PREDICT_FALSE( !( condition ) ) ) \ + throw geode::OpenGeodeTetrahedronException< dimension > \ + { \ + tetrahedron, __VA_ARGS__ \ + } diff --git a/include/geode/geometry/basic_objects/triangle.hpp b/include/geode/geometry/basic_objects/triangle.hpp index 6975703f0..39e8359cf 100644 --- a/include/geode/geometry/basic_objects/triangle.hpp +++ b/include/geode/geometry/basic_objects/triangle.hpp @@ -86,6 +86,7 @@ namespace geode [[nodiscard]] local_index_t longest_edge_index() const; [[nodiscard]] double minimum_height() const; [[nodiscard]] bool is_degenerated() const; + [[nodiscard]] std::string string() const; private: std::array< PointType, 3 > vertices_; @@ -129,4 +130,37 @@ namespace geode Triangle< dimension >&& other ) noexcept; }; ALIAS_2D_AND_3D( Triangle ); + + template < index_t dimension > + class OpenGeodeTriangleException : public OpenGeodeException + { + public: + template < typename... Args > + explicit OpenGeodeTriangleException( + Triangle< dimension > triangle_in, const Args&... message ) + : OpenGeodeException{ absl::StrCat( + message..., " at ", triangle_in.string() ) }, + triangle{ std::move( triangle_in ) } + { + } + + OwnerTriangle< dimension > triangle; + }; + ALIAS_2D_AND_3D( OpenGeodeTriangleException ); } // namespace geode + +// NOLINTNEXTLINE +#define OPENGEODE_TRIANGLE_EXCEPTION( dimension, condition, triangle, ... ) \ + if( ABSL_PREDICT_FALSE( !( condition ) ) ) \ + throw geode::OpenGeodeTriangleException< dimension > \ + { \ + triangle, __VA_ARGS__ \ + } + +// NOLINTNEXTLINE +#define OPENGEODE_TRIANGLE2D_EXCEPTION( condition, triangle, ... ) \ + OPENGEODE_TRIANGLE_EXCEPTION( 2, condition, triangle, __VA_ARGS__ ) + +// NOLINTNEXTLINE +#define OPENGEODE_TRIANGLE3D_EXCEPTION( condition, triangle, ... ) \ + OPENGEODE_TRIANGLE_EXCEPTION( 3, condition, triangle, __VA_ARGS__ ) diff --git a/include/geode/geometry/point.hpp b/include/geode/geometry/point.hpp index e73c86ae5..ce48af8a7 100644 --- a/include/geode/geometry/point.hpp +++ b/include/geode/geometry/point.hpp @@ -284,15 +284,15 @@ namespace geode } // NOLINTNEXTLINE -#define OPENGEODE_POINT_EXCEPTION1D( condition, point, ... ) \ +#define OPENGEODE_POINT1D_EXCEPTION( condition, point, ... ) \ OPENGEODE_POINT_EXCEPTION( 1, condition, point, __VA_ARGS__ ) // NOLINTNEXTLINE -#define OPENGEODE_POINT_EXCEPTION2D( condition, point, ... ) \ +#define OPENGEODE_POINT2D_EXCEPTION( condition, point, ... ) \ OPENGEODE_POINT_EXCEPTION( 2, condition, point, __VA_ARGS__ ) // NOLINTNEXTLINE -#define OPENGEODE_POINT_EXCEPTION3D( condition, point, ... ) \ +#define OPENGEODE_POINT3D_EXCEPTION( condition, point, ... ) \ OPENGEODE_POINT_EXCEPTION( 3, condition, point, __VA_ARGS__ ) namespace std diff --git a/src/geode/basic/assert.cpp b/src/geode/basic/assert.cpp index 90a2b9999..0ef994912 100644 --- a/src/geode/basic/assert.cpp +++ b/src/geode/basic/assert.cpp @@ -61,4 +61,24 @@ namespace geode } return 1; } + + void throw_lippincott() + { + try + { + throw; + } + catch( const OpenGeodeException& /*unused*/ ) + { + throw; + } + catch( const std::exception& exception ) + { + throw OpenGeodeException{ "std::exception, ", exception.what() }; + } + catch( ... ) + { + throw OpenGeodeException{ "Unknown exception" }; + } + } } // namespace geode diff --git a/src/geode/geometry/basic_objects/segment.cpp b/src/geode/geometry/basic_objects/segment.cpp index 9df8bc8cb..194db9b46 100644 --- a/src/geode/geometry/basic_objects/segment.cpp +++ b/src/geode/geometry/basic_objects/segment.cpp @@ -108,6 +108,14 @@ namespace geode return length() <= GLOBAL_EPSILON; } + template < typename PointType, index_t dimension > + std::string GenericSegment< PointType, dimension >::string() const + { + const Point< dimension >& point0 = vertices_[0]; + const Point< dimension >& point1 = vertices_[1]; + return absl::StrCat( "[", point0.string(), ", ", point1.string(), "]" ); + } + template < index_t dimension > OwnerSegment< dimension >::OwnerSegment( Point< dimension > point0, Point< dimension > point1 ) noexcept diff --git a/src/geode/geometry/basic_objects/tetrahedron.cpp b/src/geode/geometry/basic_objects/tetrahedron.cpp index 7c58606fc..b0a889c36 100644 --- a/src/geode/geometry/basic_objects/tetrahedron.cpp +++ b/src/geode/geometry/basic_objects/tetrahedron.cpp @@ -99,6 +99,17 @@ namespace geode <= GLOBAL_EPSILON; } + template < typename PointType > + std::string GenericTetrahedron< PointType >::string() const + { + const Point3D& point0 = vertices_[0]; + const Point3D& point1 = vertices_[1]; + const Point3D& point2 = vertices_[2]; + const Point3D& point3 = vertices_[3]; + return absl::StrCat( "[", point0.string(), ", ", point1.string(), ", ", + point2.string(), ", ", point3.string(), "]" ); + } + OwnerTetrahedron::OwnerTetrahedron( Point3D point0, Point3D point1, Point3D point2, diff --git a/src/geode/geometry/basic_objects/triangle.cpp b/src/geode/geometry/basic_objects/triangle.cpp index d88f5584f..7eb4f5365 100644 --- a/src/geode/geometry/basic_objects/triangle.cpp +++ b/src/geode/geometry/basic_objects/triangle.cpp @@ -285,6 +285,16 @@ namespace geode <= GLOBAL_EPSILON; } + template < typename PointType, index_t dimension > + std::string GenericTriangle< PointType, dimension >::string() const + { + const Point< dimension >& point0 = vertices_[0]; + const Point< dimension >& point1 = vertices_[1]; + const Point< dimension >& point2 = vertices_[2]; + return absl::StrCat( "[", point0.string(), ", ", point1.string(), ", ", + point2.string(), "]" ); + } + template < index_t dimension > OwnerTriangle< dimension >::OwnerTriangle( Point< dimension > point0, Point< dimension > point1, diff --git a/src/geode/geometry/bounding_box.cpp b/src/geode/geometry/bounding_box.cpp index 1def8ef49..270171a62 100644 --- a/src/geode/geometry/bounding_box.cpp +++ b/src/geode/geometry/bounding_box.cpp @@ -487,7 +487,7 @@ namespace geode for( const auto c : geode::LRange{ dimension } ) { const auto local_distance = std::min( - std::abs( Pmin.value( c ) ), std::abs( Pmax.value( c ) ) ); + std::fabs( Pmin.value( c ) ), std::fabs( Pmax.value( c ) ) ); inner_distance = std::min( inner_distance, local_distance ); } return -inner_distance;