diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Direction_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Direction_2.h index 4d27652873c..302299d0898 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Direction_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Direction_2.h @@ -47,7 +47,7 @@ public: DirectionC2() {} DirectionC2(const FT &x, const FT &y) - : base(CGAL::make_array(x, y)) {} + : base{x, y} {} bool operator==(const DirectionC2 &d) const; bool operator!=(const DirectionC2 &d) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Direction_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Direction_3.h index 6cf5c0c8e78..a9c9867a934 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Direction_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Direction_3.h @@ -45,7 +45,7 @@ public: DirectionC3() {} explicit DirectionC3(const Vector_3 &v) - : base(CGAL::make_array(v.x(), v.y(), v.z())) {} + : base{v.x(), v.y(), v.z()} {} // { *this = v.direction(); } explicit DirectionC3(const Line_3 &l) @@ -58,7 +58,7 @@ public: { *this = s.rep().direction(); } DirectionC3(const FT &x, const FT &y, const FT &z) - : base(CGAL::make_array(x, y, z)) {} + : base{x, y, z} {} typename R::Boolean operator==(const DirectionC3 &d) const; typename R::Boolean operator!=(const DirectionC3 &d) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Iso_cuboid_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Iso_cuboid_3.h index 2e22a69b77d..82f319261a0 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Iso_cuboid_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Iso_cuboid_3.h @@ -43,7 +43,7 @@ public: Iso_cuboidC3() {} Iso_cuboidC3(const Point_3 &p, const Point_3 &q, int) - : base(CGAL::make_array(p, q)) + : base{p, q} { // I have to remove the assertions, because of Cartesian_converter. // CGAL_kernel_assertion(p.x()<=q.x()); @@ -68,8 +68,8 @@ public: Iso_cuboidC3(const Point_3 &left, const Point_3 &right, const Point_3 &bottom, const Point_3 &top, const Point_3 &far_, const Point_3 &close) - : base(CGAL::make_array(Construct_point_3()(left.x(), bottom.y(), far_.z()), - Construct_point_3()(right.x(), top.y(), close.z()))) + : base{Construct_point_3()(left.x(), bottom.y(), far_.z()), + Construct_point_3()(right.x(), top.y(), close.z())} { CGAL_kernel_precondition(!less_x(right, left)); CGAL_kernel_precondition(!less_y(top, bottom)); diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Iso_rectangle_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Iso_rectangle_2.h index 6f3b8c40f2a..e238cf57767 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Iso_rectangle_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Iso_rectangle_2.h @@ -43,7 +43,7 @@ public: // : base(p, q) {} Iso_rectangleC2(const Point_2 &p, const Point_2 &q, int) - : base(CGAL::make_array(p, q)) + : base{p, q} { // I have to remove the assertions, because of Cartesian_converter. // CGAL_kernel_assertion(p<=q); diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Line_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Line_2.h index 77ec08c459d..21ff3298338 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Line_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Line_2.h @@ -46,7 +46,7 @@ public: LineC2() {} LineC2(const FT &a, const FT &b, const FT &c) - : base(CGAL::make_array(a, b, c)) {} + : base{a, b, c} {} typename R_::Boolean operator==(const LineC2 &l) const; typename R_::Boolean operator!=(const LineC2 &l) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Plane_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Plane_3.h index d9d873b0847..38a119e1320 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Plane_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Plane_3.h @@ -64,7 +64,7 @@ public: { *this = plane_from_point_direction(o, v.direction()); } PlaneC3(const FT &a, const FT &b, const FT &c, const FT &d) - : base(CGAL::make_array(a, b, c, d)) {} + : base{a, b, c, d} {} PlaneC3(const Line_3 &l, const Point_3 &p) { *this = plane_from_points(l.point(), diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h index 92a71f42557..d11db7d4d68 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Point_2.h @@ -44,11 +44,14 @@ public: PointC2(const Origin &) : base(NULL_VECTOR) {} - PointC2(const FT &x, const FT &y) - : base(x, y) {} + template + PointC2(T1 &&x, T2 &&y) + : base(std::forward(x), std::forward(y)) + {} - PointC2(const FT &hx, const FT &hy, const FT &hw) - : base(hx, hy, hw) {} + template + PointC2(T1 &&hx, T2 &&hy, T3 &&hw) + : base(std::forward(hx), std::forward(hy), std::forward(hw)) {} friend void swap(Self& a, Self& b) #if !defined(__INTEL_COMPILER) && defined(__cpp_lib_is_swappable) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h index 1bd80cdb016..e4dcd3357d8 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Point_3.h @@ -42,11 +42,17 @@ public: PointC3(const Origin &) : base(NULL_VECTOR) {} - PointC3(const FT &x, const FT &y, const FT &z) - : base(x, y, z) {} - PointC3(const FT &x, const FT &y, const FT &z, const FT &w) - : base(x, y, z, w) {} + template + PointC3(T1 &&x, T2 &&y, T3 &&z) + : base(std::forward(x), std::forward(y), std::forward(z)) + {} + + template + PointC3(T1 &&x, T2 &&y, T3 &&z, T4 &&w) + : base(std::forward(x), std::forward(y), + std::forward(z), std::forward(w)) + {} friend void swap(Self& a, Self& b) #if !defined(__INTEL_COMPILER) && defined(__cpp_lib_is_swappable) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Ray_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Ray_2.h index 8448eba97e7..c703dc79dcd 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Ray_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Ray_2.h @@ -40,7 +40,7 @@ public: {} RayC2(const Point_2 &sp, const Point_2 &secondp) - : base(CGAL::make_array(sp, secondp)) + : base{sp, secondp} {} diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Ray_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Ray_3.h index 15892d8dfc0..7dd67e372ba 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Ray_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Ray_3.h @@ -43,16 +43,16 @@ public: RayC3() {} RayC3(const Point_3 &sp, const Point_3 &secondp) - : base(CGAL::make_array(sp, secondp)) {} + : base{sp, secondp} {} RayC3(const Point_3 &sp, const Vector_3 &v) - : base(CGAL::make_array(sp, sp + v)) {} + : base{sp, sp + v} {} RayC3(const Point_3 &sp, const Direction_3 &d) - : base(CGAL::make_array(sp, sp + d.to_vector())) {} + : base{sp, sp + d.to_vector()} {} RayC3(const Point_3 &sp, const Line_3 &l) - : base(CGAL::make_array(sp, sp + l.to_vector())) {} + : base{sp, sp + l.to_vector()} {} typename R::Boolean operator==(const RayC3 &r) const; typename R::Boolean operator!=(const RayC3 &r) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Segment_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Segment_2.h index 3672c797e7c..25bff4769fd 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Segment_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Segment_2.h @@ -39,7 +39,7 @@ public: {} SegmentC2(const Point_2 &sp, const Point_2 &ep) - : base(CGAL::make_array(sp, ep)) + : base{sp, ep} {} const Point_2 & diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Segment_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Segment_3.h index 122626550f4..8ab1d082d6f 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Segment_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Segment_3.h @@ -42,7 +42,7 @@ public: SegmentC3() {} SegmentC3(const Point_3 &sp, const Point_3 &ep) - : base(CGAL::make_array(sp, ep)) {} + : base{sp, ep} {} bool has_on(const Point_3 &p) const; bool collinear_has_on(const Point_3 &p) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Tetrahedron_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Tetrahedron_3.h index 3a197adecf8..c20733313af 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Tetrahedron_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Tetrahedron_3.h @@ -45,7 +45,7 @@ public: TetrahedronC3(const Point_3 &p, const Point_3 &q, const Point_3 &r, const Point_3 &s) - : base(CGAL::make_array(p, q, r, s)) {} + : base{p, q, r, s} {} const Point_3 & vertex(int i) const; const Point_3 & operator[](int i) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Triangle_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Triangle_2.h index 5639f2363c4..48661cb5964 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Triangle_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Triangle_2.h @@ -41,7 +41,7 @@ public: TriangleC2() {} TriangleC2(const Point_2 &p, const Point_2 &q, const Point_2 &r) - : base(CGAL::make_array(p, q, r)) {} + : base{p, q, r} {} const Point_2 & diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Triangle_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Triangle_3.h index 1fa2525ae10..7e61db2dee2 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Triangle_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Triangle_3.h @@ -42,7 +42,7 @@ public: TriangleC3() {} TriangleC3(const Point_3 &p, const Point_3 &q, const Point_3 &r) - : base(CGAL::make_array(p, q, r)) {} + : base{p, q, r} {} bool operator==(const TriangleC3 &t) const; bool operator!=(const TriangleC3 &t) const; diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h b/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h index 575df5d0728..1ff9d12ee7b 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Vector_2.h @@ -50,7 +50,10 @@ public: VectorC2() {} VectorC2(const FT &x, const FT &y) - : base(CGAL::make_array(x, y)) {} + : base{x, y} {} + + VectorC2(FT&& x, FT&& y) + : base{std::move(x), std::move(y)} {} VectorC2(const FT &hx, const FT &hy, const FT &hw) : base( hw != FT(1) ? CGAL::make_array(hx/hw, hy/hw) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h index 5b03e8d0fb3..89540fd9b0d 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Vector_3.h @@ -65,7 +65,10 @@ public: { *this = R().construct_vector_3_object()(l); } VectorC3(const FT_ &x, const FT_ &y, const FT_ &z) - : base(CGAL::make_array(x, y, z)) {} + : base{x, y, z} {} + + VectorC3(FT_&& x, FT_&& y, FT_&& z) + : base{std::move(x), std::move(y), std::move(z)} {} VectorC3(const FT_ &x, const FT_ &y, const FT_ &z, const FT_ &w) : base( w != FT_(1) ? CGAL::make_array(x/w, y/w, z/w) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 8b0153f03e1..ffb1056f147 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -3075,17 +3075,10 @@ namespace CartesianKernelFunctors { typedef const Point_2& type; }; + template Rep // Point_2 - operator()(Return_base_tag, Origin o) const - { return Rep(o); } - - Rep // Point_2 - operator()(Return_base_tag, const RT& x, const RT& y) const - { return Rep(x, y); } - - Rep // Point_2 - operator()(Return_base_tag, const RT& x, const RT& y, const RT& w) const - { return Rep(x, y, w); } + operator()(Return_base_tag, Args&& ...args) const + { return Rep(std::forward(args)...); } Point_2 operator()(const Line_2& l) const @@ -3097,7 +3090,7 @@ namespace CartesianKernelFunctors { } Point_2 - operator()(const Line_2& l, const FT i) const + operator()(const Line_2& l, const FT& i) const { typename K::Construct_point_2 construct_point_2; typename K::FT x, y; @@ -3121,6 +3114,10 @@ namespace CartesianKernelFunctors { operator()(const RT& x, const RT& y) const { return Point_2(x, y); } + Point_2 + operator()(RT&& x, RT&& y) const + { return Point_2(std::move(x), std::move(y)); } + Point_2 operator()(const RT& x, const RT& y, const RT& w) const { return Point_2(x, y, w); } @@ -3151,18 +3148,10 @@ namespace CartesianKernelFunctors { typedef const Point_3& type; }; - + template Rep // Point_3 - operator()(Return_base_tag, Origin o) const - { return Rep(o); } - - Rep // Point_3 - operator()(Return_base_tag, const RT& x, const RT& y, const RT& z) const - { return Rep(x, y, z); } - - Rep // Point_3 - operator()(Return_base_tag, const RT& x, const RT& y, const RT& z, const RT& w) const - { return Rep(x, y, z, w); } + operator()(Return_base_tag, Args&& ...args) const + { return Rep(std::forward(args)...); } const Point_3& operator()(const Point_3 & p) const @@ -3180,6 +3169,10 @@ namespace CartesianKernelFunctors { operator()(const RT& x, const RT& y, const RT& z) const { return Point_3(x, y, z); } + Point_3 + operator()(RT&& x, RT&& y, RT&& z) const + { return Point_3(std::move(x), std::move(y), std::move(z)); } + Point_3 operator()(const RT& x, const RT& y, const RT& z, const RT& w) const { return Point_3(x, y, z, w); } @@ -3577,11 +3570,17 @@ namespace CartesianKernelFunctors { operator()(Return_base_tag, const RT& x, const RT& y) const { return Rep(x, y); } + Rep + operator()(Return_base_tag, RT&& x, RT&& y) const + { return Rep(std::move(x), std::move(y)); } + Rep // Vector_2 operator()(Return_base_tag, const RT& x, const RT& y, const RT& w) const { return Rep(x, y, w); } - + Rep + operator()(Return_base_tag, RT&& x, RT&& y, RT&& w) const + { return Rep(std::move(x), std::move(y), std::move(w)); } Vector_2 operator()( const Point_2& p, const Point_2& q) const @@ -3681,6 +3680,10 @@ namespace CartesianKernelFunctors { operator()(Return_base_tag, const RT& x, const RT& y, const RT& z) const { return Rep(x, y, z); } + Rep // Vector_3 + operator()(Return_base_tag, RT&& x, RT&& y, RT&& z) const + { return Rep(std::move(x), std::move(y), std::move(z)); } + Rep // Vector_3 operator()(Return_base_tag, const RT& x, const RT& y, const RT& z, const RT& w) const { return Rep(x, y, z, w); } diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/DirectionH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/DirectionH2.h index a86847f9e87..b30267cf7d2 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/DirectionH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/DirectionH2.h @@ -56,7 +56,7 @@ public: DirectionH2() {} DirectionH2(const RT& x, const RT& y) - : base(CGAL::make_array(x, y, RT(1))) {} + : base{x, y, RT(1)} {} // TODO Not documented : should not exist, not used. // we should also change array -> array diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_cuboidH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_cuboidH3.h index 0119260a3c1..e4830033289 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_cuboidH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_cuboidH3.h @@ -43,7 +43,7 @@ public: Iso_cuboidH3() {} Iso_cuboidH3(const Point_3& p, const Point_3& q, int) - : base(CGAL::make_array(p, q)) + : base{p, q} { CGAL_kernel_assertion(p.x()<=q.x()); CGAL_kernel_assertion(p.y()<=q.y()); @@ -173,8 +173,8 @@ CGAL_KERNEL_LARGE_INLINE Iso_cuboidH3:: Iso_cuboidH3(const RT& min_hx, const RT& min_hy, const RT& min_hz, const RT& max_hx, const RT& max_hy, const RT& max_hz) - : base(CGAL::make_array(Point_3(min_hx, min_hy, min_hz, RT(1)), - Point_3(max_hx, max_hy, max_hz, RT(1)))) + : base{Point_3(min_hx, min_hy, min_hz, RT(1)), + Point_3(max_hx, max_hy, max_hz, RT(1))} {} template < class R > diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_rectangleH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_rectangleH2.h index 5c3f1ba9d32..6bdde3dec91 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_rectangleH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/Iso_rectangleH2.h @@ -42,7 +42,7 @@ public: Iso_rectangleH2() {} Iso_rectangleH2(const Point_2& p, const Point_2& q, int) - : base(CGAL::make_array(p, q)) + : base{p, q} { // I have to remove the assertions, because of Homogeneous_converter. // CGAL_kernel_assertion(p.x()<=q.x()); diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/LineH2.h b/Homogeneous_kernel/include/CGAL/Homogeneous/LineH2.h index 5f37cfee985..ab69b965f35 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/LineH2.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/LineH2.h @@ -45,7 +45,7 @@ public: LineH2() {} LineH2(const RT& a, const RT& b, const RT& c) - : base(CGAL::make_array(a, b, c)) {} + : base{a, b, c} {} bool operator==(const LineH2& l) const; bool operator!=(const LineH2& l) const; diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h index aecd718d41a..56a0e2b9ad8 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/VectorH3.h @@ -63,7 +63,7 @@ public: { *this = R().construct_vector_3_object()(l); } VectorH3(const Null_vector&) - : base(CGAL::make_array(RT(0), RT(0), RT(0), RT(1))) {} + : base{RT(0), RT(0), RT(0), RT(1)} {} template < typename Tx, typename Ty, typename Tz > VectorH3(const Tx & x, const Ty & y, const Tz & z, diff --git a/Kernel_23/include/CGAL/Exact_predicates_exact_constructions_kernel.h b/Kernel_23/include/CGAL/Exact_predicates_exact_constructions_kernel.h index f963f2e9ec3..68eb4a252c8 100644 --- a/Kernel_23/include/CGAL/Exact_predicates_exact_constructions_kernel.h +++ b/Kernel_23/include/CGAL/Exact_predicates_exact_constructions_kernel.h @@ -29,8 +29,15 @@ namespace CGAL { +constexpr bool epeck_use_static_filter = +#ifdef CGAL_NO_STATIC_FILTERS + false; +#else + true; +#endif + // Epeck_ft is either Gmpq, or leda_rational, or Quotient -typedef internal::Exact_field_selector::Type Epeck_ft; +using Epeck_ft = internal::Exact_field_selector::Type; // The following are redefined kernels instead of simple typedefs in order to shorten // template name length (for error messages, mangling...). @@ -41,33 +48,36 @@ typedef internal::Exact_field_selector::Type Epeck_ft; class Epeck : public Filtered_kernel_adaptor< Type_equality_wrapper< Simple_cartesian >::Base::Type, Epeck >, -#ifdef CGAL_NO_STATIC_FILTERS - false > -#else - true > -#endif + epeck_use_static_filter > {}; // end class Epeck #else // no CGAL_DONT_USE_LAZY_KERNEL +namespace internal { + template + using Epeck_sc = Simple_cartesian; + using Epeck_interval = Simple_cartesian; + + template + using Epeck_converter = Cartesian_converter, Epeck_interval>; + + template + using Epeck_lazy_base = Lazy_kernel_base, Epeck_interval, Epeck_converter, Kernel>; + + template + using Epeck_lazy_base_with_type_equality = Type_equality_wrapper, Kernel>; +} // namespace internal + // Equivalent to Lazy_kernel > -class Epeck - : public Type_equality_wrapper< - Lazy_kernel_base< Simple_cartesian, - Simple_cartesian, - Cartesian_converter< Simple_cartesian, - Simple_cartesian >, - Epeck>, - Epeck > -{}; +class Epeck : public internal::Epeck_lazy_base_with_type_equality {}; #endif // no CGAL_DONT_USE_LAZY_KERNEL -typedef Epeck Exact_predicates_exact_constructions_kernel; +using Exact_predicates_exact_constructions_kernel = Epeck; template <> struct Triangulation_structural_filtering_traits { - typedef Tag_true Use_structural_filtering_tag; + using Use_structural_filtering_tag = Tag_true; }; } //namespace CGAL diff --git a/Kernel_23/include/CGAL/Point_2.h b/Kernel_23/include/CGAL/Point_2.h index 96bffa243e2..2c29178175f 100644 --- a/Kernel_23/include/CGAL/Point_2.h +++ b/Kernel_23/include/CGAL/Point_2.h @@ -79,9 +79,11 @@ public: : Rep(wp.point()) {} - template < typename T1, typename T2 > - Point_2(const T1 &x, const T2 &y) - : Rep(typename R::Construct_point_2()(Return_base_tag(), x, y)) + template < typename T1, typename T2> + Point_2(T1&& x, T2&& y) + : Rep(typename R::Construct_point_2()(Return_base_tag(), + std::forward(x), + std::forward(y))) {} Point_2(const RT& hx, const RT& hy, const RT& hw) @@ -255,7 +257,7 @@ extract(std::istream& is, Point_2& p, const Cartesian_tag&) break; } if (is) - p = Point_2(x, y); + p = Point_2(std::move(x), std::move(y)); return is; } diff --git a/Kernel_23/include/CGAL/Point_3.h b/Kernel_23/include/CGAL/Point_3.h index f2444a9506c..219aabe0292 100644 --- a/Kernel_23/include/CGAL/Point_3.h +++ b/Kernel_23/include/CGAL/Point_3.h @@ -75,8 +75,10 @@ public: {} template < typename T1, typename T2, typename T3 > - Point_3(const T1& x, const T2& y, const T3& z) - : Rep(typename R::Construct_point_3()(Return_base_tag(), x, y, z)) + Point_3(T1&& x, T2&& y, T3&& z) + : Rep(typename R::Construct_point_3()(Return_base_tag(), std::forward(x), + std::forward(y), + std::forward(z))) {} Point_3(const RT& hx, const RT& hy, const RT& hz, const RT& hw) @@ -283,7 +285,7 @@ extract(std::istream& is, Point_3& p, const Cartesian_tag&) break; } if (is) - p = Point_3(x, y, z); + p = Point_3(std::move(x), std::move(y), std::move(z)); return is; } diff --git a/Kernel_23/include/CGAL/Vector_2.h b/Kernel_23/include/CGAL/Vector_2.h index 4449fc3ef9f..c1bcfe45f31 100644 --- a/Kernel_23/include/CGAL/Vector_2.h +++ b/Kernel_23/include/CGAL/Vector_2.h @@ -88,8 +88,11 @@ public: : RVector_2(typename R::Construct_vector_2()(Return_base_tag(), v)) {} template < typename T1, typename T2 > - Vector_2(const T1 &x, const T2 &y) - : RVector_2(typename R::Construct_vector_2()(Return_base_tag(), x,y)) {} + Vector_2(T1&& x, T2&& y) + : RVector_2(typename R::Construct_vector_2()(Return_base_tag(), + std::forward(x), + std::forward(y))) + {} Vector_2(const RT &x, const RT &y, const RT &w) : RVector_2(typename R::Construct_vector_2()(Return_base_tag(), x,y,w)) {} diff --git a/Kernel_23/include/CGAL/Vector_3.h b/Kernel_23/include/CGAL/Vector_3.h index 9220f3e8527..7712d380098 100644 --- a/Kernel_23/include/CGAL/Vector_3.h +++ b/Kernel_23/include/CGAL/Vector_3.h @@ -88,8 +88,11 @@ public: : Rep(typename R::Construct_vector_3()(Return_base_tag(), v)) {} template < typename T1, typename T2, typename T3 > - Vector_3(const T1 &x, const T2 &y, const T3 &z) - : Rep(typename R::Construct_vector_3()(Return_base_tag(), x, y, z)) {} + Vector_3(T1&& x, T2&& y, T3&& z) + : Rep(typename R::Construct_vector_3()(Return_base_tag(), std::forward(x), + std::forward(y), + std::forward(z))) + {} 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)) {} diff --git a/LEDA/include/CGAL/LEDA_basic.h b/LEDA/include/CGAL/LEDA_basic.h index 5dc01566024..eb6baa5ad56 100644 --- a/LEDA/include/CGAL/LEDA_basic.h +++ b/LEDA/include/CGAL/LEDA_basic.h @@ -25,8 +25,14 @@ // The following is needed for LEDA 4.4 due to min/max problems... # define LEDA_NO_MIN_MAX_TEMPL +#ifdef CGAL_CXX20 +# define STREAM_DUMMY // disable stream_dummy() function that is not used and using features removed from c++20 +// We cannot undef STREAM_DUMMY as LEDA/internal/PREAMBULE.h is not protected +#endif #include + + #ifdef LEDA_NAMESPACE # define CGAL_LEDA_SCOPE leda #else diff --git a/Number_types/include/CGAL/Mpzf.h b/Number_types/include/CGAL/Mpzf.h index 020ea8ce94b..44bb8fd9246 100644 --- a/Number_types/include/CGAL/Mpzf.h +++ b/Number_types/include/CGAL/Mpzf.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #ifdef CGAL_USE_GMPXX diff --git a/Number_types/include/CGAL/NT_wrapper.h b/Number_types/include/CGAL/NT_wrapper.h new file mode 100644 index 00000000000..97f66f1e55b --- /dev/null +++ b/Number_types/include/CGAL/NT_wrapper.h @@ -0,0 +1,187 @@ +// Copyright (c) 2024, 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 + +#ifndef CGAL_NT_WRAPPER_H +#define CGAL_NT_WRAPPER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +/* + * This class template `NT_wapper` is currently undocumented, on purpose. + * + * This class template provides a wrapper for number types. It calls a function + * `f` when a constructor, destructor, or assignment operator is called. This + * is useful to detect when a copy constructor is called, for example. An + * example of use case is in the test file + * `Number_types/test/Number_types/wrapping_type.cpp`. + */ + +template +class NT_wrapper { + NT value; + + static void call_f(const std::source_location& l = std::source_location::current()) { + if (f) + f(l); + } + +public: + inline static std::function f; + + NT_wrapper() : value(0) { call_f(std::source_location::current()); } + NT_wrapper(const NT& val) : value(val) { call_f(std::source_location::current());} + NT_wrapper(NT&& val) : value(std::move(val)) { call_f(std::source_location::current()); } + NT_wrapper(int val) : value(val) { call_f(std::source_location::current()); } + + template >> + NT_wrapper(const NT_wrapper& other) : value(other.get_value()) { call_f(std::source_location::current()); } + + NT_wrapper(const NT_wrapper& other) : value(other.value) { call_f(std::source_location::current()); } + NT_wrapper(NT_wrapper&& other) : value(std::move(other.value)) { call_f(std::source_location::current()); } + ~NT_wrapper() { call_f(std::source_location::current()); } + + NT_wrapper& operator=(const NT_wrapper& other) { + if (this != &other) { + value = other.value; + call_f(std::source_location::current()); + } + return *this; + } + + NT_wrapper& operator=(NT_wrapper&& other) { + if (this != &other) { + value = std::move(other.value); + call_f(std::source_location::current()); + } + return *this; + } + + NT get_value() const { + return value; + } + + operator NT() const { + return value; + } + + NT_wrapper operator+(const NT_wrapper& rhs) const { + return NT_wrapper(value + rhs.value); + } + + NT_wrapper operator-(const NT_wrapper& rhs) const { + return NT_wrapper(value - rhs.value); + } + + NT_wrapper operator*(const NT_wrapper& rhs) const { + return NT_wrapper(value * rhs.value); + } + + NT_wrapper operator/(const NT_wrapper& rhs) const { + return NT_wrapper(value / rhs.value); + } + + NT_wrapper operator/(int rhs) const { + return NT_wrapper(value / rhs); + } + + bool operator==(const NT_wrapper& rhs) const { + return value == rhs.value; + } + + bool operator!=(const NT_wrapper& rhs) const { + return value != rhs.value; + } + + bool operator<(const NT_wrapper& rhs) const { + return value < rhs.value; + } + + bool operator>(const NT_wrapper& rhs) const { + return value > rhs.value; + } + + bool operator<=(const NT_wrapper& rhs) const { + return value <= rhs.value; + } + + bool operator>=(const NT_wrapper& rhs) const { + return value >= rhs.value; + } +}; + +CGAL_DEFINE_COERCION_TRAITS_FROM_TO_TEM(NT_wrapper, double, typename NT) + +template +struct Real_embeddable_traits> + : public INTERN_RET::Real_embeddable_traits_base, + typename Real_embeddable_traits::Is_real_embeddable> +{ + using Type = NT_wrapper; + class Sgn + : public CGAL::cpp98::unary_function< NT, ::CGAL::Sign > { + public: + ::CGAL::Sign operator()( const Type& x ) const { + return CGAL_NTS sign( x.get_value() ); + } + }; + + class To_double + : public CGAL::cpp98::unary_function< NT, double > { + public: + double operator()( const Type& x) const { + return CGAL_NTS to_double( x.get_value() ); + } + }; + + class To_interval + : public CGAL::cpp98::unary_function< NT, std::pair > { + public: + std::pair operator()( const Type& x ) const { + return CGAL_NTS to_interval( x.get_value() ); + } + }; +}; + +namespace internal { + +template +struct Exact_field_selector> { + using Type = NT_wrapper::Type>; + using type = Type; +}; + +template +struct Exact_ring_selector> { + using Type = NT_wrapper::Type>; + using type = Type; +}; + +} // namespace internal + +struct Wrapped_epick + : public CGAL::internal::Epick_with_filtered_predicates, Wrapped_epick> +{}; +struct Wrapped_epeck + : public CGAL::internal::Epeck_lazy_base_with_type_equality, Wrapped_epeck> +{}; + +} // namespace CGAL + +#endif // CGAL_NT_WRAPPER_H \ No newline at end of file diff --git a/Number_types/include/CGAL/known_bit_size_integers.h b/Number_types/include/CGAL/known_bit_size_integers.h index c5bc43fed54..195d0fae2c2 100644 --- a/Number_types/include/CGAL/known_bit_size_integers.h +++ b/Number_types/include/CGAL/known_bit_size_integers.h @@ -24,11 +24,12 @@ #define CGAL_KNOWN_BIT_SIZE_INTEGERS_H #define CGAL_DEPRECATED_HEADER "" -#define CGAL_REPLACEMENT_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" #include #include #include +#include #ifndef CGAL_NO_DEPRECATED_CODE diff --git a/Number_types/test/Number_types/CMakeLists.txt b/Number_types/test/Number_types/CMakeLists.txt index f8ff8698b72..2dd6186a70d 100644 --- a/Number_types/test/Number_types/CMakeLists.txt +++ b/Number_types/test/Number_types/CMakeLists.txt @@ -62,6 +62,7 @@ create_single_source_cgal_program("utilities.cpp") create_single_source_cgal_program("Exact_rational.cpp") create_single_source_cgal_program("Mpzf_new.cpp") create_single_source_cgal_program("check_exact_backend.cpp") +create_single_source_cgal_program("wrapping_type.cpp" CXX_FEATURES cxx_std_20) if( CGAL_Core_FOUND ) create_single_source_cgal_program( "CORE_Expr_ticket_4296.cpp" ) diff --git a/Number_types/test/Number_types/known_bit_size_integers.cpp b/Number_types/test/Number_types/known_bit_size_integers.cpp index 351ffa412af..4027fcfff14 100644 --- a/Number_types/test/Number_types/known_bit_size_integers.cpp +++ b/Number_types/test/Number_types/known_bit_size_integers.cpp @@ -1,10 +1,10 @@ #include -#include +#include #include int main() { - std::cout << "Verifying the sizes of boost::[u]int{8,16,32,64}_t" + std::cout << "Verifying the sizes of std::[u]int{8,16,32,64}_t" << std::endl; static_assert(sizeof(std::int8_t) == 1); diff --git a/Number_types/test/Number_types/wrapping_type.cpp b/Number_types/test/Number_types/wrapping_type.cpp new file mode 100644 index 00000000000..6313e3769a1 --- /dev/null +++ b/Number_types/test/Number_types/wrapping_type.cpp @@ -0,0 +1,53 @@ +#include +#include + +#include +#if __has_include() +#include + +struct Map { + std::map m; + void increment(const std::string& key) { + m[key]++; + } + ~Map() { + for(const auto& [key, value] : m) + std::clog << value << " " << key << std::endl; + } +} map; + +void incr_counter(const std::source_location& l) { + map.increment(l.function_name()); +} + +using K = CGAL::Wrapped_epick; + +using EK = CGAL::Wrapped_epeck; + +int main() { + CGAL::NT_wrapper::f = incr_counter; + CGAL::NT_wrapper::f = incr_counter; + K ::Point_2 p1(0, 2), p2(2, 4), p3(4, 6); + EK::Point_2 p4(0, 2), p5(2, 4), p6(4, 6); + exact(p4); + exact(p5); + exact(p6); + [[maybe_unused]] bool result_2d_k = CGAL::orientation(p1, p2, p3) == CGAL::COLLINEAR; + [[maybe_unused]] bool result_2d_e = CGAL::orientation(p4, p5, p6) == CGAL::COLLINEAR; + assert (result_2d_k && result_2d_e); + + for(auto [key, _] : map.m) { + if(key.find("const") != std::string::npos) { + std::cerr << "ERROR: copy constructor called!\n"; + return 1; + } + } + return 0; +} + +#else +int main() { + std::cerr << "C++20 not available\n"; + return 0; +} +#endif diff --git a/STL_Extension/doc/STL_Extension/CGAL/array.h b/STL_Extension/doc/STL_Extension/CGAL/array.h index 5c3d083c2a5..9a1c2921641 100644 --- a/STL_Extension/doc/STL_Extension/CGAL/array.h +++ b/STL_Extension/doc/STL_Extension/CGAL/array.h @@ -6,8 +6,6 @@ namespace CGAL { \returns `std::array` where `N` is the number of arguments given to the function. The position of each argument in the array is the same as its position in the argument list. - -The maximal number of arguments is `6`. */ template std::array make_array(const T&...); @@ -18,8 +16,6 @@ arguments given to the function. The position of each argument in the array is the same as its position in the argument list. This is the functor version of `make_array()`. - -The maximal number of arguments is `6`. */ struct Construct_array { diff --git a/STL_Extension/include/CGAL/Handle_for.h b/STL_Extension/include/CGAL/Handle_for.h index 2f05c6be1ce..9384277f7ae 100644 --- a/STL_Extension/include/CGAL/Handle_for.h +++ b/STL_Extension/include/CGAL/Handle_for.h @@ -42,7 +42,7 @@ class Handle_for T t; std::atomic_uint count; template - RefCounted(U&&...u ) : t(std::forward(u)...), count(1) {} + RefCounted(U&&...u ) : t{std::forward(u)...}, count(1) {} }; diff --git a/STL_Extension/include/CGAL/array.h b/STL_Extension/include/CGAL/array.h index eb6d4c086e9..60cf9253b81 100644 --- a/STL_Extension/include/CGAL/array.h +++ b/STL_Extension/include/CGAL/array.h @@ -13,6 +13,7 @@ #define CGAL_ARRAY_H #include +#include #include #include @@ -45,25 +46,48 @@ namespace CGAL { // It's also untrue that this is not documented... It is ! -template< typename T, typename... Args > -BOOST_CXX14_CONSTEXPR -std::array< T, 1 + sizeof...(Args) > -make_array(const T & t, const Args & ... args) -{ - std::array< T, 1 + sizeof...(Args) > a = { { t, static_cast(args)... } }; - return a; -} +template +struct Make_array_element_type { + using type = T; +}; +template +struct Make_array_element_type { + using type = typename std::common_type_t; +}; + +template +using Make_array_element_type_t = typename Make_array_element_type::type; + +template +constexpr +std::array, sizeof...(Args) > +make_array(Args&& ... args) +{ + using Target_type = Make_array_element_type_t; + +// MSVC 2017 chokes on the following code, so we simplify it for this compiler +// See https://godbolt.org/z/7Y34Y1c53 +#if ! defined(_MSC_VER) || (_MSC_VER > 1916) + if constexpr ( (CGAL::is_convertible_without_narrowing_v, Target_type>&&...) ) + return {{ std::forward(args)... }}; + else +#endif // not MSVC or MSVC 2019 or later + { + std::array< Target_type, sizeof...(Args) > a = { { static_cast(args)... } }; + return a; + } +} // Functor version struct Construct_array { - template + template constexpr - std::array - operator()(const T& t, const Args& ... args) const + decltype(auto) + operator()(Args&& ... args) const { - return make_array (t, args...); + return make_array( std::forward(args)... ); } }; diff --git a/STL_Extension/include/CGAL/type_traits.h b/STL_Extension/include/CGAL/type_traits.h index c68386c7f76..f64e7c0c57f 100644 --- a/STL_Extension/include/CGAL/type_traits.h +++ b/STL_Extension/include/CGAL/type_traits.h @@ -29,6 +29,12 @@ struct is_same_or_derived : namespace cpp20 { + template + struct type_identity { using type = T; }; + + template + using type_identity_t = typename type_identity::type; + template< class T > struct remove_cvref { typedef std::remove_cv_t> type; @@ -39,6 +45,26 @@ namespace cpp20 { } // end namespace cpp20 +namespace details { + template + struct is_convertible_without_narrowing : std::false_type + {}; + + template + struct is_convertible_without_narrowing{std::declval()})>> + : std::is_convertible + {}; +} + +template +struct is_convertible_without_narrowing : details::is_convertible_without_narrowing +{}; + +template +inline constexpr bool is_convertible_without_narrowing_v = is_convertible_without_narrowing::value; + } // end namespace CGAL #endif // CGAL_TYPE_TRAITS_H diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index efa222f2e7b..3b54df0088d 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -53,6 +53,8 @@ create_single_source_cgal_program("test_for_each.cpp") create_single_source_cgal_program("test_skiplist.cpp") create_single_source_cgal_program("test_leak.cpp") create_single_source_cgal_program("test_nth_element.cpp") +create_single_source_cgal_program("test_fwd_make_array.cpp") + if(TARGET CGAL::TBB_support) message(STATUS "Found TBB") target_link_libraries(test_for_each PUBLIC CGAL::TBB_support) diff --git a/STL_Extension/test/STL_Extension/test_fwd_make_array.cpp b/STL_Extension/test/STL_Extension/test_fwd_make_array.cpp new file mode 100644 index 00000000000..f228358287c --- /dev/null +++ b/STL_Extension/test/STL_Extension/test_fwd_make_array.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +struct B {}; + +struct A // move-only class, move-constructible from B +{ + A(B&&) {} + + A(const A&) = delete; + A(A&&) = default; +}; + +int main() +{ +#if ! defined(_MSC_VER) || (_MSC_VER > 1916) + // This test requires C++17 mandatory return-value optimization (RVO). + // + // MSVC-2017 does not implement C++17 correctly + // See https://godbolt.org/z/7Y34Y1c53 + // and commit 15349f0bdafe60b85697f9d142c2652200d968e8 + // where we introduced a workaround for MSVC-2017: disable the correct + // forwarding of arguments in the `make_array` function. + // For that reason we disable this test for MSVC-2017) + std::array a = CGAL::make_array(B()); + CGAL_USE(a); +#endif + auto b = CGAL::make_array(1u); + static_assert(std::is_same_v>); + CGAL_USE(b); + return 0; +} diff --git a/STL_Extension/test/STL_Extension/test_type_traits.cpp b/STL_Extension/test/STL_Extension/test_type_traits.cpp index 77586b50c89..caa0e3afa36 100644 --- a/STL_Extension/test/STL_Extension/test_type_traits.cpp +++ b/STL_Extension/test/STL_Extension/test_type_traits.cpp @@ -18,14 +18,22 @@ struct B : public A {}; typedef A C; int main() { - assert( ( ::CGAL::is_same_or_derived< A,A >::value == 1 ) ); - assert( ( ::CGAL::is_same_or_derived< A,B >::value == 1 ) ); - assert( ( ::CGAL::is_same_or_derived< B,A >::value == 0 ) ); - assert( ( ::CGAL::is_same_or_derived< B,B >::value == 1 ) ); - assert( ( ::CGAL::is_same_or_derived< A,C >::value == 1 ) ); - assert( ( ::CGAL::is_same_or_derived< B,C >::value == 0 ) ); - assert( ( ::CGAL::is_same_or_derived< C,C >::value == 1 ) ); - assert( ( ::CGAL::is_same_or_derived< C,A >::value == 1 ) ); - assert( ( ::CGAL::is_same_or_derived< C,B >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< A,A >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< A,B >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< B,A >::value == 0 ) ); + static_assert( ( ::CGAL::is_same_or_derived< B,B >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< A,C >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< B,C >::value == 0 ) ); + static_assert( ( ::CGAL::is_same_or_derived< C,C >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< C,A >::value == 1 ) ); + static_assert( ( ::CGAL::is_same_or_derived< C,B >::value == 1 ) ); + + static_assert( CGAL::is_convertible_without_narrowing_v ); + static_assert( ! CGAL::is_convertible_without_narrowing_v ); + static_assert( CGAL::is_convertible_without_narrowing_v ); + static_assert( ! CGAL::is_convertible_without_narrowing_v ); + static_assert( CGAL::is_convertible_without_narrowing_v ); + static_assert( ! CGAL::is_convertible_without_narrowing_v ); + static_assert( ! CGAL::is_convertible_without_narrowing_v ); return 0; }