From 6c65f5d92983801b566ef8540c2ae3978ed632b0 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Wed, 12 Feb 2020 09:42:51 +0100 Subject: [PATCH 1/5] Some noexcept, swap, etc to help Handle* types --- Number_types/include/CGAL/GMP/Gmpq_type.h | 19 ++++++++++-------- STL_Extension/include/CGAL/Handle.h | 16 ++++++++------- STL_Extension/include/CGAL/Handle_for.h | 24 +++++++++++------------ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/Number_types/include/CGAL/GMP/Gmpq_type.h b/Number_types/include/CGAL/GMP/Gmpq_type.h index 8fa397492d5..e339590b8d1 100644 --- a/Number_types/include/CGAL/GMP/Gmpq_type.h +++ b/Number_types/include/CGAL/GMP/Gmpq_type.h @@ -222,20 +222,23 @@ public: Gmpq& operator*=(const Gmpq &q); Gmpq& operator/=(const Gmpq &q); - bool operator==(const Gmpq &q) const { return mpq_equal(this->mpq(), q.mpq()) != 0;} - bool operator< (const Gmpq &q) const { return mpq_cmp(this->mpq(), q.mpq()) < 0; } + bool operator==(const Gmpq &q) const noexcept { return mpq_equal(this->mpq(), q.mpq()) != 0;} + bool operator< (const Gmpq &q) const noexcept { return mpq_cmp(this->mpq(), q.mpq()) < 0; } - double to_double() const; - Sign sign() const; + double to_double() const noexcept; + Sign sign() const noexcept; - const mpq_t & mpq() const { return Ptr()->mpQ; } - mpq_t & mpq() { return ptr()->mpQ; } + const mpq_t & mpq() const noexcept { return Ptr()->mpQ; } + mpq_t & mpq() noexcept { return ptr()->mpQ; } + friend void swap(Gmpq &x, Gmpq &y) noexcept { x.Base::swap(y); } +#ifdef CGAL_PROFILE ~Gmpq() { CGAL_HISTOGRAM_PROFILER("[Gmpq sizes in log2 scale]", (unsigned) ( ::log(double(size())) / ::log(double(2)) ) ); } +#endif // Interoperability with int Gmpq& operator+=(int z){return (*this)+= Gmpq(z);} @@ -446,12 +449,12 @@ Gmpq& Gmpq::operator/=(const Gmpz &z){ inline double -Gmpq::to_double() const +Gmpq::to_double() const noexcept { return mpq_get_d(mpq()); } inline Sign -Gmpq::sign() const +Gmpq::sign() const noexcept { return static_cast(mpq_sgn(mpq())); } inline diff --git a/STL_Extension/include/CGAL/Handle.h b/STL_Extension/include/CGAL/Handle.h index 278232748a5..80acd63e7f3 100644 --- a/STL_Extension/include/CGAL/Handle.h +++ b/STL_Extension/include/CGAL/Handle.h @@ -39,13 +39,15 @@ class Handle typedef std::ptrdiff_t Id_type ; - Handle() + Handle() noexcept : PTR(static_cast(0)) {} - Handle(const Handle& x) + // FIXME: if the precondition throws in a noexcept function, the program terminates + Handle(const Handle& x) noexcept { CGAL_precondition( x.PTR != static_cast(0) ); PTR = x.PTR; + CGAL_assume (PTR->count > 0); PTR->count++; } @@ -56,7 +58,7 @@ class Handle } Handle& - operator=(const Handle& x) + operator=(const Handle& x) noexcept { CGAL_precondition( x.PTR != static_cast(0) ); x.PTR->count++; @@ -77,11 +79,11 @@ class Handle } int - refs() const { return PTR->count; } + refs() const noexcept { return PTR->count; } - Id_type id() const { return PTR - static_cast(0); } + Id_type id() const noexcept { return PTR - static_cast(0); } - bool identical(const Handle& h) const { return PTR == h.PTR; } + bool identical(const Handle& h) const noexcept { return PTR == h.PTR; } protected: Rep* PTR; @@ -89,7 +91,7 @@ class Handle //inline Handle::Id_type id(const Handle& x) { return x.id() ; } -inline bool identical(const Handle &h1, const Handle &h2) { return h1.identical(h2); } +inline bool identical(const Handle &h1, const Handle &h2) noexcept { return h1.identical(h2); } } //namespace CGAL diff --git a/STL_Extension/include/CGAL/Handle_for.h b/STL_Extension/include/CGAL/Handle_for.h index 8bc097d7c02..b283f469003 100644 --- a/STL_Extension/include/CGAL/Handle_for.h +++ b/STL_Extension/include/CGAL/Handle_for.h @@ -102,7 +102,7 @@ public: ptr_ = p; } - Handle_for(const Handle_for& h) + Handle_for(const Handle_for& h) noexcept : ptr_(h.ptr_) { CGAL_assume (ptr_->count > 0); @@ -110,7 +110,7 @@ public: } Handle_for& - operator=(const Handle_for& h) + operator=(const Handle_for& h) noexcept { Handle_for tmp = h; swap(tmp); @@ -132,7 +132,7 @@ public: // from e.g. using nullptr as a ptr value, but this is drastic. Handle_for& - operator=(Handle_for && h) + operator=(Handle_for && h) noexcept { swap(h); return *this; @@ -164,15 +164,15 @@ public: *this = t; } - Id_type id() const { return Ptr() - static_cast(0); } + Id_type id() const noexcept { return Ptr() - static_cast(0); } - bool identical(const Handle_for& h) const { return Ptr() == h.Ptr(); } + bool identical(const Handle_for& h) const noexcept { return Ptr() == h.Ptr(); } // Ptr() is the "public" access to the pointer to the object. // The non-const version asserts that the instance is not shared. const element_type * - Ptr() const + Ptr() const noexcept { return &(ptr_->t); } @@ -188,25 +188,25 @@ public: */ bool - is_shared() const + is_shared() const noexcept { return ptr_->count > 1; } bool - unique() const + unique() const noexcept { return !is_shared(); } long - use_count() const + use_count() const noexcept { return ptr_->count; } void - swap(Handle_for& h) + swap(Handle_for& h) noexcept { std::swap(ptr_, h.ptr_); } @@ -222,11 +222,11 @@ protected: // ptr() is the protected access to the pointer. Both const and non-const. // Redundant with Ptr(). element_type * - ptr() + ptr() noexcept { return &(ptr_->t); } const element_type * - ptr() const + ptr() const noexcept { return &(ptr_->t); } }; From 3e4c0d28e5239327357e763249372026f052c134 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 25 Feb 2020 01:29:48 +0100 Subject: [PATCH 2/5] More swaps. --- Filtered_kernel/include/CGAL/Lazy.h | 3 +++ Number_types/include/CGAL/Lazy_exact_nt.h | 3 +++ STL_Extension/include/CGAL/Handle.h | 2 ++ 3 files changed, 8 insertions(+) diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 2a887d57b48..dd3616d4a7e 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -731,6 +731,9 @@ public : PTR = new Lazy_rep_0(std::move(e)); } + friend void swap(Lazy& a, Lazy& b) noexcept + { swap(static_cast(a), static_cast(b)); } + const AT& approx() const { return ptr()->approx(); } diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index 471096f37ba..41e2c597981 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -383,6 +383,9 @@ public : typename boost::disable_if,int>::type=0) : Base(new Lazy_lazy_exact_Cst(x)){} + friend void swap(Lazy_exact_nt& a, Lazy_exact_nt& b) noexcept + { swap(static_cast(a), static_cast(b)); } + Self operator+ () const { return *this; } diff --git a/STL_Extension/include/CGAL/Handle.h b/STL_Extension/include/CGAL/Handle.h index 80acd63e7f3..7e725eb67dc 100644 --- a/STL_Extension/include/CGAL/Handle.h +++ b/STL_Extension/include/CGAL/Handle.h @@ -68,6 +68,8 @@ class Handle return *this; } + friend void swap(Handle& a, Handle& b) noexcept { std::swap(a.PTR, b.PTR); } + void reset() { if (PTR) From c92587fb9cab042b4e4176d8bab96400a3696aa3 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 25 Feb 2020 01:52:19 +0100 Subject: [PATCH 3/5] More swap We could add it for all kernel wrappers... It is really inconvenient that swap cannot be autogenerated like move assignments are. noexcept(auto) would also be convenient, whatever some people on the committee claim. --- Kernel_23/include/CGAL/Point_3.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Kernel_23/include/CGAL/Point_3.h b/Kernel_23/include/CGAL/Point_3.h index bf3952fb0dc..83f65b42b5a 100644 --- a/Kernel_23/include/CGAL/Point_3.h +++ b/Kernel_23/include/CGAL/Point_3.h @@ -46,12 +46,12 @@ public: typedef typename R_::Kernel_base::Point_3 Rep; typedef typename R_::Cartesian_const_iterator_3 Cartesian_const_iterator; - const Rep& rep() const + const Rep& rep() const noexcept { return *this; } - Rep& rep() + Rep& rep() noexcept { return *this; } @@ -81,6 +81,15 @@ public: : Rep(typename R::Construct_point_3()(Return_base_tag(), hx, hy, hz, hw)) {} + friend void swap(Point_3& a, Point_3& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.rep(), b.rep()); + } + typename cpp11::result_of::type x() const { From 1eed5a908c1189cd793fdf521916874be34d8b43 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 25 Feb 2020 08:57:53 +0100 Subject: [PATCH 4/5] swap Simple_cartesian::Point_3 --- Cartesian_kernel/include/CGAL/Cartesian/Point_3.h | 9 +++++++++ Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h | 9 +++++++++ Kernel_23/include/CGAL/Vector_3.h | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h index 614ec31fcc5..35abdde9a8c 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h @@ -47,6 +47,15 @@ public: PointC3(const FT &x, const FT &y, const FT &z, const FT &w) : base(x, y, z, w) {} + friend void swap(PointC3& a, PointC3& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.base, b.base); + } + const FT & x() const { return base.x(); diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h index ccad6ad574c..9b6b7e1db96 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h @@ -70,6 +70,15 @@ public: : base( w != FT_(1) ? CGAL::make_array(x/w, y/w, z/w) : CGAL::make_array(x, y, z) ) {} + friend void swap(VectorC3& a, VectorC3& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.base, b.base); + } + const FT_ & x() const { return get_pointee_or_identity(base)[0]; diff --git a/Kernel_23/include/CGAL/Vector_3.h b/Kernel_23/include/CGAL/Vector_3.h index c3c7c0bc953..2775aa4c13e 100644 --- a/Kernel_23/include/CGAL/Vector_3.h +++ b/Kernel_23/include/CGAL/Vector_3.h @@ -93,6 +93,15 @@ public: Vector_3(const RT& x, const RT& y, const RT& z, const RT& w) : Rep(typename R::Construct_vector_3()(Return_base_tag(), x, y, z, w)) {} + friend void swap(Vector_3& a, Vector_3& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.rep(), b.rep()); + } + Direction_3 direction() const { return R().construct_direction_3_object()(*this); From 3ebe8839b6f99d424bce25825b209974142cd14f Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sun, 1 Mar 2020 12:50:13 +0100 Subject: [PATCH 5/5] swap for Point_2 and Point_d and make the implementations more similar, in case someone wants to replace it with a macro at some point. --- Cartesian_kernel/include/CGAL/Cartesian/Point_2.h | 9 +++++++++ Cartesian_kernel/include/CGAL/Cartesian/Point_3.h | 3 ++- Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h | 10 ++++++++++ Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h | 3 ++- Kernel_23/include/CGAL/Point_2.h | 13 +++++++++++-- Kernel_23/include/CGAL/Point_3.h | 2 +- Kernel_23/include/CGAL/Vector_2.h | 13 +++++++++++-- Kernel_23/include/CGAL/Vector_3.h | 2 +- .../include/CGAL/NewKernel_d/Wrapper/Point_d.h | 12 ++++++++++-- 9 files changed, 57 insertions(+), 10 deletions(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h index 92985777bbb..028c772c102 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h @@ -50,6 +50,15 @@ public: PointC2(const FT &hx, const FT &hy, const FT &hw) : base(hx, hy, hw) {} + friend void swap(Self& a, Self& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.base, b.base); + } + const FT& x() const { return base.x(); diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h index 35abdde9a8c..b46ab99284b 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h @@ -24,6 +24,7 @@ namespace CGAL { template < class R_ > class PointC3 { + typedef PointC3 Self; typedef typename R_::Vector_3 Vector_3; typedef typename R_::Point_3 Point_3; typedef typename R_::Aff_transformation_3 Aff_transformation_3; @@ -47,7 +48,7 @@ public: PointC3(const FT &x, const FT &y, const FT &z, const FT &w) : base(x, y, z, w) {} - friend void swap(PointC3& a, PointC3& b) + friend void swap(Self& a, Self& b) #ifdef __cpp_lib_is_swappable noexcept(std::is_nothrow_swappable_v) #endif diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h index 6331471dff7..01986b321a3 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h @@ -27,6 +27,7 @@ namespace CGAL { template < class R_ > class VectorC2 { + typedef VectorC2 Self; typedef typename R_::FT FT; typedef typename R_::Point_2 Point_2; typedef typename R_::Vector_2 Vector_2; @@ -55,6 +56,15 @@ public: : base( hw != FT(1) ? CGAL::make_array(hx/hw, hy/hw) : CGAL::make_array(hx, hy) ) {} + friend void swap(Self& a, Self& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.base, b.base); + } + const FT & x() const { return CGAL::get_pointee_or_identity(base)[0]; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h index 9b6b7e1db96..72954931d0b 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h @@ -27,6 +27,7 @@ template < class R_ > class VectorC3 { // https://doc.cgal.org/latest/Manual/devman_code_format.html#secprogramming_conventions + typedef VectorC3 Self; typedef typename R_::FT FT_; typedef typename R_::Point_3 Point_3; typedef typename R_::Vector_3 Vector_3; @@ -70,7 +71,7 @@ public: : base( w != FT_(1) ? CGAL::make_array(x/w, y/w, z/w) : CGAL::make_array(x, y, z) ) {} - friend void swap(VectorC3& a, VectorC3& b) + friend void swap(Self& a, Self& b) #ifdef __cpp_lib_is_swappable noexcept(std::is_nothrow_swappable_v) #endif diff --git a/Kernel_23/include/CGAL/Point_2.h b/Kernel_23/include/CGAL/Point_2.h index a5b00bb1eb9..7358d0dc46b 100644 --- a/Kernel_23/include/CGAL/Point_2.h +++ b/Kernel_23/include/CGAL/Point_2.h @@ -48,12 +48,12 @@ public: typedef RPoint_2 Rep; typedef typename R_::Cartesian_const_iterator_2 Cartesian_const_iterator; - const Rep& rep() const + const Rep& rep() const noexcept { return *this; } - Rep& rep() + Rep& rep() noexcept { return *this; } @@ -84,6 +84,15 @@ public: : RPoint_2(typename R::Construct_point_2()(Return_base_tag(), hx, hy, hw)) {} + friend void swap(Self& a, Self& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.rep(), b.rep()); + } + typename cpp11::result_of::type x() const { diff --git a/Kernel_23/include/CGAL/Point_3.h b/Kernel_23/include/CGAL/Point_3.h index 83f65b42b5a..01b07bd3e0e 100644 --- a/Kernel_23/include/CGAL/Point_3.h +++ b/Kernel_23/include/CGAL/Point_3.h @@ -81,7 +81,7 @@ public: : Rep(typename R::Construct_point_3()(Return_base_tag(), hx, hy, hz, hw)) {} - friend void swap(Point_3& a, Point_3& b) + friend void swap(Self& a, Self& b) #ifdef __cpp_lib_is_swappable noexcept(std::is_nothrow_swappable_v) #endif diff --git a/Kernel_23/include/CGAL/Vector_2.h b/Kernel_23/include/CGAL/Vector_2.h index 4f570ed6b02..67f07e5e3e6 100644 --- a/Kernel_23/include/CGAL/Vector_2.h +++ b/Kernel_23/include/CGAL/Vector_2.h @@ -54,12 +54,12 @@ public: typedef RVector_2 Rep; typedef typename R_::Cartesian_const_iterator_2 Cartesian_const_iterator; - const Rep& rep() const + const Rep& rep() const noexcept { return *this; } - Rep& rep() + Rep& rep() noexcept { return *this; } @@ -93,6 +93,15 @@ public: Vector_2(const RT &x, const RT &y, const RT &w) : RVector_2(typename R::Construct_vector_2()(Return_base_tag(), x,y,w)) {} + friend void swap(Self& a, Self& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.rep(), b.rep()); + } + typename cpp11::result_of::type x() const diff --git a/Kernel_23/include/CGAL/Vector_3.h b/Kernel_23/include/CGAL/Vector_3.h index 2775aa4c13e..077da5d649d 100644 --- a/Kernel_23/include/CGAL/Vector_3.h +++ b/Kernel_23/include/CGAL/Vector_3.h @@ -93,7 +93,7 @@ public: Vector_3(const RT& x, const RT& y, const RT& z, const RT& w) : Rep(typename R::Construct_vector_3()(Return_base_tag(), x, y, z, w)) {} - friend void swap(Vector_3& a, Vector_3& b) + friend void swap(Self& a, Self& b) #ifdef __cpp_lib_is_swappable noexcept(std::is_nothrow_swappable_v) #endif diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Point_d.h b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Point_d.h index 404eca88bf3..5c0dce2db1f 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Point_d.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Wrapper/Point_d.h @@ -51,12 +51,12 @@ public: typedef typename Get_type::type Rep; //typedef typename CGAL::decay::type>::type Cartesian_const_iterator; - const Rep& rep() const + const Rep& rep() const noexcept { return *this; } - Rep& rep() + Rep& rep() noexcept { return *this; } @@ -101,6 +101,14 @@ public: Point_d(Origin&& v) : Rep(CPBase()(std::move(v))) {} + friend void swap(Self& a, Self& b) +#ifdef __cpp_lib_is_swappable + noexcept(std::is_nothrow_swappable_v) +#endif + { + using std::swap; + swap(a.rep(), b.rep()); + } decltype(auto) cartesian(int i)const{ return CCBase()(rep(),i);