diff --git a/Algebraic_foundations/include/CGAL/number_utils.h b/Algebraic_foundations/include/CGAL/number_utils.h index abb7894ccf4..d29434ad603 100644 --- a/Algebraic_foundations/include/CGAL/number_utils.h +++ b/Algebraic_foundations/include/CGAL/number_utils.h @@ -302,13 +302,13 @@ to_interval( const Real_embeddable& x) { } template -NT approximate_sqrt(const NT& nt, CGAL::Field_tag) +NT approximate_sqrt(const NT& nt, CGAL::Null_functor) { return NT(sqrt(CGAL::to_double(nt))); } -template -NT approximate_sqrt(const NT& nt, CGAL::Field_with_sqrt_tag) +template +NT approximate_sqrt(const NT& nt, Sqrt sqrt) { return sqrt(nt); } @@ -316,9 +316,12 @@ NT approximate_sqrt(const NT& nt, CGAL::Field_with_sqrt_tag) template NT approximate_sqrt(const NT& nt) { + // the initial version of this function was using Algebraic_category + // for the dispatch but some ring type (like Gmpz) provides a Sqrt + // functor even if not being Field_with_sqrt. typedef CGAL::Algebraic_structure_traits AST; - typedef typename AST::Algebraic_category Algebraic_category; - return approximate_sqrt(nt, Algebraic_category()); + typedef typename AST::Sqrt Sqrt; + return approximate_sqrt(nt, Sqrt()); } CGAL_NTS_END_NAMESPACE diff --git a/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h b/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h index 3f5dd1ae3bb..d4a62c21c91 100644 --- a/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h +++ b/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h @@ -246,8 +246,8 @@ bisector_of_linesC2(const FT &pa, const FT &pb, const FT &pc, FT &a, FT &b, FT &c) { // We normalize the equations of the 2 lines, and we then add them. - FT n1 = CGAL_NTS sqrt(CGAL_NTS square(pa) + CGAL_NTS square(pb)); - FT n2 = CGAL_NTS sqrt(CGAL_NTS square(qa) + CGAL_NTS square(qb)); + FT n1 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(pa) + CGAL_NTS square(pb)) ); + FT n2 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(qa) + CGAL_NTS square(qb)) ); a = n2 * pa + n1 * qa; b = n2 * pb + n1 * qb; c = n2 * pc + n1 * qc; diff --git a/Cartesian_kernel/include/CGAL/constructions/kernel_ftC3.h b/Cartesian_kernel/include/CGAL/constructions/kernel_ftC3.h index 63a1442f511..ac1dced802c 100644 --- a/Cartesian_kernel/include/CGAL/constructions/kernel_ftC3.h +++ b/Cartesian_kernel/include/CGAL/constructions/kernel_ftC3.h @@ -366,10 +366,10 @@ bisector_of_planesC3(const FT &pa, const FT &pb, const FT &pc, const FT &pd, FT &a, FT &b, FT &c, FT &d) { // We normalize the equations of the 2 planes, and we then add them. - FT n1 = CGAL_NTS sqrt(CGAL_NTS square(pa) + CGAL_NTS square(pb) + - CGAL_NTS square(pc)); - FT n2 = CGAL_NTS sqrt(CGAL_NTS square(qa) + CGAL_NTS square(qb) + - CGAL_NTS square(qc)); + FT n1 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(pa) + CGAL_NTS square(pb) + + CGAL_NTS square(pc)) ); + FT n2 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(qa) + CGAL_NTS square(qb) + + CGAL_NTS square(qc)) ); a = n2 * pa + n1 * qa; b = n2 * pb + n1 * qb; c = n2 * pc + n1 * qc; diff --git a/Documentation/doc/Documentation/Third_party.txt b/Documentation/doc/Documentation/Third_party.txt index 55705a34ad8..0dccb54db4e 100644 --- a/Documentation/doc/Documentation/Third_party.txt +++ b/Documentation/doc/Documentation/Third_party.txt @@ -154,6 +154,10 @@ executables should be linked with the CMake imported target The \sc{libpointmatcher} web site is `https://github.com/ethz-asl/libpointmatcher`. +\attention On Windows, we only support version 1.3.1 of PointMatcher with version 3.3.7 of Eigen, with some changes to the recipe at +`https://github.com/ethz-asl/libpointmatcher/blob/master/doc/CompilationWindows.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS` +and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" section. + \subsection thirdpartyLeda LEDA Version 6.2 or later diff --git a/GraphicsView/demo/Segment_Delaunay_graph_2/include/CGAL/Constraints_loader.h b/GraphicsView/demo/Segment_Delaunay_graph_2/include/CGAL/Constraints_loader.h index 1a3a2f3621f..66899ca4237 100644 --- a/GraphicsView/demo/Segment_Delaunay_graph_2/include/CGAL/Constraints_loader.h +++ b/GraphicsView/demo/Segment_Delaunay_graph_2/include/CGAL/Constraints_loader.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -96,7 +97,7 @@ class Constraints_loader { for(Points_iterator it = points.begin(); it != points.end(); ++it) { indices.push_back(it); } - std::random_shuffle(indices.begin(), indices.end()); + CGAL::cpp98::random_shuffle(indices.begin(), indices.end()); CGAL::spatial_sort(indices.begin(), indices.end(), sort_traits); diff --git a/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/include/CGAL/Constraints_loader.h b/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/include/CGAL/Constraints_loader.h index 1a3a2f3621f..66899ca4237 100644 --- a/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/include/CGAL/Constraints_loader.h +++ b/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/include/CGAL/Constraints_loader.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -96,7 +97,7 @@ class Constraints_loader { for(Points_iterator it = points.begin(); it != points.end(); ++it) { indices.push_back(it); } - std::random_shuffle(indices.begin(), indices.end()); + CGAL::cpp98::random_shuffle(indices.begin(), indices.end()); CGAL::spatial_sort(indices.begin(), indices.end(), sort_traits); diff --git a/GraphicsView/include/CGAL/Qt/camera_impl.h b/GraphicsView/include/CGAL/Qt/camera_impl.h index d79ce8af56d..88a0eaf1617 100644 --- a/GraphicsView/include/CGAL/Qt/camera_impl.h +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -883,10 +883,13 @@ void Camera::interpolateTo(const Frame &fr, qreal duration) { imprecision along the viewing direction. */ CGAL_INLINE_FUNCTION Vec Camera::pointUnderPixel(const QPoint &pixel, bool &found) const { - float depth; + float depth = 2.0; // Qt uses upper corner for its origin while GL uses the lower corner. - dynamic_cast(parent())->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1, - GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + if(auto p = dynamic_cast(parent())) + { + p->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + } found = depth < 1.0; Vec point(pixel.x(), pixel.y(), depth); point = unprojectedCoordinatesOf(point); diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 946a15c49b4..f54f751f9f4 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -738,7 +738,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { (mh == qglviewer::FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; setMouseBinding(modifiers, ::Qt::LeftButton, mh, qglviewer::ROTATE); - setMouseBinding(modifiers, ::Qt::MidButton, mh, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::MiddleButton, mh, qglviewer::ZOOM); setMouseBinding(modifiers, ::Qt::RightButton, mh, qglviewer::TRANSLATE); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, qglviewer::SCREEN_ROTATE); @@ -748,7 +748,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { setWheelBinding(::Qt::Key_Z, ::Qt::NoModifier, qglviewer::CAMERA, qglviewer::ZOOM_FOV); // Z o o m o n r e g i o n - setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); + setMouseBinding(::Qt::ShiftModifier, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); // S e l e c t setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, qglviewer::SELECT); @@ -756,7 +756,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, qglviewer::RAP_FROM_PIXEL); // D o u b l e c l i c k setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::SHOW_ENTIRE_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, qglviewer::ALIGN_FRAME, true); @@ -1223,7 +1223,7 @@ static QString mouseButtonsString(::Qt::MouseButtons b) { result += CGAL::QGLViewer::tr("Left", "left mouse button"); addAmpersand = true; } - if (b & ::Qt::MidButton) { + if (b & ::Qt::MiddleButton) { if (addAmpersand) result += " & "; result += CGAL::QGLViewer::tr("Middle", "middle mouse button"); @@ -1760,7 +1760,7 @@ Mouse tab. \c ::Qt::AltModifier, \c ::Qt::ShiftModifier, \c ::Qt::MetaModifier). Possibly combined using the \c "|" operator. -\p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MidButton, +\p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MiddleButton, \c ::Qt::RightButton...). \p doubleClick indicates whether or not the user has to double click this button @@ -3037,27 +3037,27 @@ void CGAL::QGLViewer::toggleCameraMode() { camera()->frame()->stopSpinning(); setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); - setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); + setMouseBinding(modifiers, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::MOVE_BACKWARD); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROLL); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::NO_CLICK_ACTION, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::NO_CLICK_ACTION, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::NO_CLICK_ACTION, true); setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); } else { // Should stop flyTimer. But unlikely and not easy. setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROTATE); - setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::ZOOM); setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::TRANSLATE); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::SCREEN_ROTATE); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::SHOW_ENTIRE_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::ZOOM); diff --git a/Installation/cmake/modules/CGAL_pointmatcher_support.cmake b/Installation/cmake/modules/CGAL_pointmatcher_support.cmake index c023102661f..7323feae702 100644 --- a/Installation/cmake/modules/CGAL_pointmatcher_support.cmake +++ b/Installation/cmake/modules/CGAL_pointmatcher_support.cmake @@ -1,7 +1,16 @@ if(libpointmatcher_FOUND AND NOT TARGET CGAL::pointmatcher_support) - add_library(CGAL::pointmatcher_support INTERFACE IMPORTED) - set_target_properties(CGAL::pointmatcher_support PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "CGAL_LINKED_WITH_POINTMATCHER" - INTERFACE_INCLUDE_DIRECTORIES "${libpointmatcher_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${libpointmatcher_LIBRARIES}") + find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono) + if(Boost_chrono_FOUND + AND Boost_thread_FOUND + AND Boost_filesystem_FOUND + AND Boost_system_FOUND + AND Boost_program_options_FOUND + AND Boost_date_time_FOUND) + add_library(CGAL::pointmatcher_support INTERFACE IMPORTED) + target_compile_definitions(CGAL::pointmatcher_support INTERFACE "CGAL_LINKED_WITH_POINTMATCHER") + target_include_directories(CGAL::pointmatcher_support INTERFACE "${libpointmatcher_INCLUDE_DIR}") + target_link_libraries(CGAL::pointmatcher_support INTERFACE "${libpointmatcher_LIBRARIES}") + else() + message(STATUS "NOTICE : the libpointmatcher library requires the following boost components: thread filesystem system program_options date_time chrono.") + endif() endif() diff --git a/Kernel_23/doc/Kernel_23/CGAL/Kernel/global_functions.h b/Kernel_23/doc/Kernel_23/CGAL/Kernel/global_functions.h index 98ea9f7ed60..bb63612593e 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Kernel/global_functions.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Kernel/global_functions.h @@ -355,8 +355,10 @@ through the intersection of `l1` and `l2`. If `l1` and `l2` are parallel, then the bisector is defined as the line which has the same direction as `l1`, and which is at the same distance from `l1` and `l2`. -This function requires that `Kernel::RT` supports the `sqrt()` -operation. +If `Kernel::FT` is not a model of `FieldWithSqrt` +an approximation of the square root will be used in this function, +impacting the exactness of the result even with an (exact) multiprecision +number type. */ template CGAL::Line_2 bisector(const CGAL::Line_2 &l1, @@ -379,8 +381,10 @@ passes through the intersection of `h1` and `h2`. If `h1` and `h2` are parallel, then the bisector is defined as the plane which has the same oriented normal vector as `l1`, and which is at the same distance from `h1` and `h2`. -This function requires that `Kernel::RT` supports the `sqrt()` -operation. +If `Kernel::FT` is not a model of `FieldWithSqrt` +an approximation of the square root will be used in this function, +impacting the exactness of the result even with an (exact) multiprecision +number type. */ template CGAL::Plane_3 bisector(const CGAL::Plane_3 &h1, diff --git a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h index 44e13cfbbe4..623fd66d526 100644 --- a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h +++ b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h @@ -3882,8 +3882,6 @@ public: If `l1` and `l2` are parallel, then the bisector is defined as the line which has the same direction as `l1`, and which is at the same distance from `l1` and `l2`. - This function requires that `Kernel::RT` supports the `sqrt()` - operation. */ Kernel::Line_2 operator()(const Kernel::Line_2&l1, const Kernel::Line_2&l2); @@ -3925,8 +3923,6 @@ public: If `h1` and `h2` are parallel, then the bisector is defined as the plane which has the same oriented normal vector as `h1`, and which is at the same distance from `h1` and `h2`. - This function requires that `Kernel::RT` supports the `sqrt()` - operation. */ Kernel::Plane_3 operator()(const Kernel::Plane_3&h1, const Kernel::Plane_3&h2); diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_line_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_line_2.h index e88c95fb0fe..05df87c02f1 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_line_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_line_2.h @@ -18,22 +18,9 @@ #ifndef CGAL__TEST_FCT_LINE_2_H #define CGAL__TEST_FCT_LINE_2_H -// Accessory function testing functions that require sqrt(). -// Doesn't instantiate anything if RT doesn't support sqrt(). template bool -_test_fct_line_sqrt_2(const R&, CGAL::Tag_false) -{ -// bool UNTESTED_STUFF_BECAUSE_SQRT_IS_NOT_SUPPORTED; - std::cout << std::endl - << "NOTE : FT doesn't support sqrt()," - " hence some functions are not tested." << std::endl; - return true; -} - -template -bool -_test_fct_line_sqrt_2(const R&, CGAL::Tag_true) +_test_fct_line_sqrt_2(const R&) { typedef typename R::Point_2 Point_2; typedef typename R::Line_2 Line_2; @@ -66,7 +53,6 @@ _test_fct_line_2(const R& ) std::cout << "Testing functions Line_2" ; typedef typename R::RT RT; - typedef typename R::FT FT; typedef typename R::Point_2 Point_2; typedef typename R::Line_2 Line_2; @@ -178,13 +164,9 @@ _test_fct_line_2(const R& ) assert(bl1.oriented_side(p2) == CGAL::ON_POSITIVE_SIDE); assert( CGAL::parallel(bl1, bl2) ); - // More tests, that require sqrt(). - { - typedef ::CGAL::Algebraic_structure_traits AST; - static const bool has_sqrt = - ! ::boost::is_same< ::CGAL::Null_functor, typename AST::Sqrt >::value; - _test_fct_line_sqrt_2(R(), ::CGAL::Boolean_tag()); - } + // More tests, that require sqrt() or use approx. + _test_fct_line_sqrt_2(R()); + std::cout << "done" << std::endl; return true; } diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_plane_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_plane_3.h index f39bc4d1ae7..17578d544ce 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_plane_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_plane_3.h @@ -17,22 +17,9 @@ #ifndef CGAL__TEST_FCT_PLANE_3_H #define CGAL__TEST_FCT_PLANE_3_H -// Accessory function testing functions that require sqrt(). -// Doesn't instantiate anything if RT doesn't support sqrt(). template bool -_test_fct_plane_sqrt_3(const R&, CGAL::Tag_false) -{ -// bool UNTESTED_STUFF_BECAUSE_SQRT_IS_NOT_SUPPORTED; - std::cout << std::endl - << "NOTE : FT doesn't support sqrt()," - " hence some functions are not tested." << std::endl; - return true; -} - -template -bool -_test_fct_plane_sqrt_3(const R&, CGAL::Tag_true) +_test_fct_plane_sqrt_3(const R&) { typedef typename R::Point_3 Point_3; typedef typename R::Plane_3 Plane_3; @@ -66,7 +53,6 @@ _test_fct_plane_3(const R& ) std::cout << "Testing functions Plane_3" ; typedef typename R::RT RT; - typedef typename R::FT FT; typedef typename R::Point_3 Point_3; typedef typename R::Plane_3 Plane_3; @@ -97,11 +83,8 @@ _test_fct_plane_3(const R& ) assert( CGAL::parallel(h1, h2) ); assert( ! CGAL::parallel(h1, h5) ); - // More tests, that require sqrt(). - typedef ::CGAL::Algebraic_structure_traits AST; - static const bool has_sqrt = - ! ::boost::is_same< ::CGAL::Null_functor, typename AST::Sqrt >::value; - _test_fct_plane_sqrt_3(R(), ::CGAL::Boolean_tag()); + // More tests, that require sqrt() or use approx. + _test_fct_plane_sqrt_3(R()); std::cout << "done" << std::endl; return true; diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 7a006c3d10a..0103389b0b6 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -17,6 +17,7 @@ #include +#include #include @@ -933,15 +934,15 @@ public: /*! \brief Returns a vector of pairs that describe properties and associated types. */ - std::vector > properties_and_types() const + std::vector > properties_and_types() const { std::vector prop = m_base.properties(); prop.erase (prop.begin()); // remove "index" prop.erase (prop.begin()); // remove "point" - std::vector > out; out.reserve (prop.size()); + std::vector > out; out.reserve (prop.size()); for (std::size_t i = 0; i < prop.size(); ++ i) - out.push_back (std::make_pair (prop[i], m_base.get_type(prop[i]))); + out.push_back (std::make_pair (prop[i], std::type_index(m_base.get_type(prop[i])))); return out; } diff --git a/Point_set_3/test/Point_set_3/point_set_test.cpp b/Point_set_3/test/Point_set_3/point_set_test.cpp index 4accb458dfa..3089af3eca1 100644 --- a/Point_set_3/test/Point_set_3/point_set_test.cpp +++ b/Point_set_3/test/Point_set_3/point_set_test.cpp @@ -106,6 +106,11 @@ int main (int, char**) point_set.add_property_map ("label", 0); point_set.add_property_map ("intensity", 0.0); + auto pnt = point_set.properties_and_types(); + std::cerr << "Properties = " << std::endl; + for (const auto& p : pnt) + std::cerr << " * " << p.first << " with type " << p.second.name() << std::endl; + test (point_set.base().n_properties() == 4, "point set should have 4 properties."); Point p_before = *(point_set.points().begin()); diff --git a/STL_Extension/include/CGAL/array.h b/STL_Extension/include/CGAL/array.h index 1900a8b1ba0..cfaca0a0550 100644 --- a/STL_Extension/include/CGAL/array.h +++ b/STL_Extension/include/CGAL/array.h @@ -13,11 +13,8 @@ #define CGAL_ARRAY_H #include -#ifndef CGAL_CFG_NO_CPP0X_ARRAY -# include -#else -# include -#endif +#include +#include namespace CGAL { @@ -49,7 +46,7 @@ namespace CGAL { // It's also untrue that this is not documented... It is ! template< typename T, typename... Args > -inline +BOOST_CXX14_CONSTEXPR std::array< T, 1 + sizeof...(Args) > make_array(const T & t, const Args & ... args) { @@ -62,12 +59,27 @@ make_array(const T & t, const Args & ... args) struct Construct_array { template - std::array operator()(const T& t, const Args& ... args) + constexpr + std::array + operator()(const T& t, const Args& ... args) const { return make_array (t, args...); } }; +template +constexpr std::array +make_filled_array_aux(const T& value, std::index_sequence) +{ + return {(static_cast(Is), value)...}; +} + +template +constexpr std::array make_filled_array(const T& value) +{ + return make_filled_array_aux(value, std::make_index_sequence()); +} + } //namespace CGAL #endif // CGAL_ARRAY_H diff --git a/Testsuite/include/CGAL/Testsuite/Triangulation_23/test_move_semantic.h b/Testsuite/include/CGAL/Testsuite/Triangulation_23/test_move_semantic.h new file mode 100644 index 00000000000..3254fb6571f --- /dev/null +++ b/Testsuite/include/CGAL/Testsuite/Triangulation_23/test_move_semantic.h @@ -0,0 +1,69 @@ +// Copyright (c) 2021 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Laurent Rineau +// + + +#include + +namespace CGAL { + namespace Testsuite { + namespace Triangulation_23 { + template + void test_move_semantic(Tr source_tr) { + const auto dimension = source_tr.dimension(); + const auto nb_of_vertices = source_tr.number_of_vertices(); + auto check_triangulation_validity = [&](const Tr& tr) { + assert(tr.is_valid()); + assert(tr.number_of_vertices() == nb_of_vertices); + assert(tr.dimension() == dimension); + }; + auto check_moved_from_triangulation = [](const Tr& tr_copy) { + assert(tr_copy.dimension() == -2); + assert(tr_copy.number_of_vertices() + 1 == 0); + }; + auto check_empty_triangulation = [](const Tr& tr_copy2) { + assert(tr_copy2.dimension() == -1); + assert(tr_copy2.number_of_vertices() == 0); + }; + // move constructor + { + Tr tr_copy(source_tr); + check_triangulation_validity(tr_copy); + + Tr tr_move_constructed(std::move(tr_copy)); + check_triangulation_validity(tr_move_constructed); + check_moved_from_triangulation(tr_copy); + + Tr tr_copy2(source_tr); + Tr tr_move_constructed2(std::move(tr_copy2)); + check_moved_from_triangulation(tr_copy2); + tr_copy2.clear(); + check_empty_triangulation(tr_copy2); + + Tr tr_copy3(source_tr); + Tr tr_move_constructed3(std::move(tr_copy3)); + check_moved_from_triangulation(tr_copy3); + tr_copy3 = source_tr; + check_triangulation_validity(tr_copy3); + } + // move-assignment + { + Tr tr_copy4(source_tr); + Tr tr_move_assigned; + tr_move_assigned = std::move(tr_copy4); + check_triangulation_validity(tr_move_assigned); + check_moved_from_triangulation(tr_copy4); + } + }; + } + } +} diff --git a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h index 266c4964e03..679ace59a24 100644 --- a/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_hierarchy_2.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace CGAL { @@ -82,7 +83,14 @@ public: #endif private: - // here is the stack of triangulations which form the hierarchy + void init_hierarchy() { + hierarchy[0] = this; + for(int i=1; i hierarchy_triangulations; std::array hierarchy; boost::rand48 random; @@ -93,13 +101,10 @@ public: Triangulation_hierarchy_2(Triangulation_hierarchy_2&& other) noexcept( noexcept(Tr_Base(std::move(other))) ) : Tr_Base(std::move(other)) + , hierarchy_triangulations(std::move(other.hierarchy_triangulations)) , random(std::move(other.random)) { - hierarchy[0] = this; - for(int i=1; i @@ -107,10 +112,7 @@ public: const Geom_traits& traits = Geom_traits()) : Tr_Base(traits) { - hierarchy[0] = this; - for(int i=1;i(*this) = std::move(other); - hierarchy[0] = this; - for(int i=1; i Triangulation_hierarchy_2:: Triangulation_hierarchy_2(const Geom_traits& traits) : Tr_Base(traits) + , hierarchy_triangulations( + make_filled_array(traits)) { - hierarchy[0] = this; - for(int i=1;i Triangulation_hierarchy_2:: Triangulation_hierarchy_2(const Triangulation_hierarchy_2 &tr) - : Tr_Base() + : Triangulation_hierarchy_2(tr.geom_traits()) { - // create an empty triangulation to be able to delete it ! - hierarchy[0] = this; - for(int i=1;i:: swap(Triangulation_hierarchy_2 &tr) { - Tr_Base* temp; Tr_Base::swap(tr); - for(int i= 1; i -Triangulation_hierarchy_2:: -~Triangulation_hierarchy_2() -{ - clear(); - for(int i= 1; i diff --git a/Triangulation_2/test/Triangulation_2/include/CGAL/_test_cls_triangulation_short_2.h b/Triangulation_2/test/Triangulation_2/include/CGAL/_test_cls_triangulation_short_2.h index d34268631cf..249b1d9e115 100644 --- a/Triangulation_2/test/Triangulation_2/include/CGAL/_test_cls_triangulation_short_2.h +++ b/Triangulation_2/test/Triangulation_2/include/CGAL/_test_cls_triangulation_short_2.h @@ -31,6 +31,7 @@ #include #include #include +#include template @@ -281,6 +282,15 @@ _test_cls_triangulation_short_2( const Triangul &) assert( T2_3_4.number_of_vertices() == 11 ); assert( T2_3_4.is_valid() ); + /****************************/ + /******* MOVE SEMANTIC*******/ + + std::cout << " move constructors and move assignment" << std::endl; + namespace test_tr_23 = CGAL::Testsuite::Triangulation_23; + test_tr_23::test_move_semantic(T0_1); + test_tr_23::test_move_semantic(T1_5); + test_tr_23::test_move_semantic(T2_8); + test_tr_23::test_move_semantic(T2_3); /*********************************************/ /****** FINITE/INFINITE VERTICES/FACES *******/ diff --git a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h index 0831c09c656..6fc656ca9eb 100644 --- a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h @@ -51,6 +51,7 @@ #include #include +#include #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO @@ -92,7 +93,14 @@ public: private: + void init_hierarchy() { + hierarchy[0] = this; + for(int i=1; i hierarchy_triangulations; std::array hierarchy; boost::rand48 random; @@ -111,24 +119,20 @@ public: Triangulation_hierarchy_3(Triangulation_hierarchy_3&& other) noexcept( noexcept(Tr_Base(std::move(other))) ) : Tr_Base(std::move(other)) + , hierarchy_triangulations(std::move(other.hierarchy_triangulations)) , random(std::move(other.random)) { - hierarchy[0] = this; - for(int i=1; i Triangulation_hierarchy_3(InputIterator first, InputIterator last, const Geom_traits& traits = Geom_traits()) : Tr_Base(traits) + , hierarchy_triangulations(make_filled_array(traits)) { - hierarchy[0] = this; - for(int i=1; i(*this) = std::move(other); - hierarchy[0] = this; - for(int i=1; i Triangulation_hierarchy_3:: Triangulation_hierarchy_3(const Geom_traits& traits) : Tr_Base(traits) + , hierarchy_triangulations(make_filled_array(traits)) { - hierarchy[0] = this; - for(int i=1;i Triangulation_hierarchy_3:: Triangulation_hierarchy_3(const Triangulation_hierarchy_3 &tr) : Tr_Base(tr) + , hierarchy_triangulations(tr.hierarchy_triangulations) { - hierarchy[0] = this; - for(int i=1; i #include #include +#include // Accessory set of functions to differentiate between // Delaunay::nearest_vertex[_in_cell] and @@ -421,7 +422,8 @@ _test_cls_delaunay_3(const Triangulation &) assert(T1.number_of_vertices() == 0); assert(T1.is_valid()); - + namespace test_tr_23 = CGAL::Testsuite::Triangulation_23; + test_tr_23::test_move_semantic(T0); // Affectation : T1=T0; @@ -454,6 +456,7 @@ _test_cls_delaunay_3(const Triangulation &) assert(T1_0.dimension()==1); assert(T1_0.number_of_vertices()==n); assert(T1_0.is_valid()); + test_tr_23::test_move_semantic(T1_0); std::cout << " Constructor7 " << std::endl; Cls T1_1; n = T1_1.insert(l2.begin(),l2.end()); @@ -514,6 +517,8 @@ _test_cls_delaunay_3(const Triangulation &) assert(T2_0.dimension()==2); assert(T2_0.number_of_vertices()==8); + test_tr_23::test_move_semantic(T2_0); + { Cls Tfromfile; std::cout << " I/O" << std::endl; @@ -562,6 +567,8 @@ _test_cls_delaunay_3(const Triangulation &) assert(T3_0.number_of_vertices()==125); assert(T3_0.dimension()==3); + test_tr_23::test_move_semantic(T3_0); + if (del) { std::cout << " deletion in Delaunay - grid case - (dim 3) " << std::endl; @@ -1194,6 +1201,19 @@ _test_cls_delaunay_3(const Triangulation &) _test_remove_cluster(); } + // Test from issue https://github.com/CGAL/cgal/issues/5396 + { + auto Triangulate = []() -> Triangulation + { + Triangulation tri; + for (int i=0; i<10; i++) + tri.insert(Point(i+1, i+2, i+3)); + + return tri; + }; + auto t = Triangulate(); + auto t2 = std::move(t); + } } #endif // CGAL_TEST_CLS_DELAUNAY_C diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h index fba2db023fd..ea40d75963e 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h @@ -17,6 +17,8 @@ #include #include #include +#include + template void _test_cls_regular_3(const Triangulation &) @@ -205,6 +207,7 @@ _test_cls_regular_3(const Triangulation &) << T.number_of_vertices() << std::endl; assert(T.is_valid()); assert(T.dimension()==3); + + namespace test_tr_23 = CGAL::Testsuite::Triangulation_23; + test_tr_23::test_move_semantic(T); } - - diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_triangulation_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_triangulation_3.h index ded18a9175f..a2afe749131 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_triangulation_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_triangulation_3.h @@ -23,6 +23,7 @@ #include #include #include +#include template bool check_all_are_finite(Triangulation* tr, const Container& cont) @@ -286,7 +287,8 @@ _test_cls_triangulation_3(const Triangulation &) assert(T1.number_of_vertices() == 0); assert(T1.is_valid()); - + namespace test_tr_23 = CGAL::Testsuite::Triangulation_23; + test_tr_23::test_move_semantic(T0); // Assignment T1=T0; @@ -363,12 +365,14 @@ _test_cls_triangulation_3(const Triangulation &) assert(T2_0.dimension()==1); assert(T2_0.number_of_vertices()==3); + test_tr_23::test_move_semantic(T2_0); v0=T2_0.insert(p4); assert(T2_0.is_valid()); assert(T2_0.dimension()==2); assert(T2_0.number_of_vertices()==4); + test_tr_23::test_move_semantic(T2_0); v0=T2_0.insert(p5); v0=T2_0.insert(p6); @@ -380,6 +384,8 @@ _test_cls_triangulation_3(const Triangulation &) assert(T2_0.dimension()==2); assert(T2_0.number_of_vertices()==8); + test_tr_23::test_move_semantic(T2_0); + if (! del) // to avoid doing the following tests for both Delaunay // and non Delaunay triangulations { @@ -403,6 +409,8 @@ _test_cls_triangulation_3(const Triangulation &) assert( T2_1.dimension()==2 ); assert( T2_1.is_valid() ); + test_tr_23::test_move_semantic(T2_1); + std::cout << " Constructor11 " << std::endl; // 3-dimensional triangulations // This is a simple grid :