diff --git a/Number_types/include/CGAL/MP_Float.h b/Number_types/include/CGAL/MP_Float.h index 9e6cbc8846e..206ac600c18 100644 --- a/Number_types/include/CGAL/MP_Float.h +++ b/Number_types/include/CGAL/MP_Float.h @@ -206,6 +206,18 @@ public: MP_Float(long double d); +#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + MP_Float(MP_Float && m) + : v(std::move(m.v)), exp(m.exp) {} + + MP_Float& operator=(MP_Float && m) + { + clear(); + swap(m); + return *this; + } +#endif + MP_Float operator+() const { return *this; } @@ -252,6 +264,12 @@ public: return NEGATIVE; } + void clear() + { + v.clear(); + exp = 0; + } + void swap(MP_Float &m) { std::swap(v, m.v); diff --git a/Number_types/include/CGAL/Quotient.h b/Number_types/include/CGAL/Quotient.h index 33d4664e8a9..e43e8800f05 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -96,10 +96,60 @@ class Quotient template Quotient(const Quotient& n) : num(n.numerator()), den(n.denominator()) {} + Quotient& operator=(const NT & n) + { + num = n; + den = 1; + return *this; + } + + Quotient& operator=(const CGAL_double(NT) & n) + { + num = n; + den = 1; + return *this; + } + + Quotient& operator=(const CGAL_int(NT) & n) + { + num = n; + den = 1; + return *this; + } + +#ifdef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + template Quotient(const T1& n, const T2& d) : num(n), den(d) { CGAL_precondition( d != 0 ); } +#else + template + Quotient(T1 && n, T2 && d) + : num(std::forward(n)), den(std::forward(d)) + { CGAL_postcondition( den != 0 ); } + + Quotient(Quotient && q) + : num(std::move(q.num)), den(std::move(q.den)) {} + + Quotient(NT && n) + : num(std::move(n)), den(1) {} + + Quotient& operator=(NT && n) + { + num = std::move(n); + den = 1; + return *this; + } + + Quotient& operator=(Quotient && q) + { + num = std::move(q.num); + den = std::move(q.den); + return *this; + } +#endif + Quotient& operator+= (const Quotient& r); Quotient& operator-= (const Quotient& r); Quotient& operator*= (const Quotient& r); diff --git a/STL_Extension/doc_tex/STL_Extension_ref/Object.tex b/STL_Extension/doc_tex/STL_Extension_ref/Object.tex index a20cd4253e7..6f188040e90 100644 --- a/STL_Extension/doc_tex/STL_Extension_ref/Object.tex +++ b/STL_Extension/doc_tex/STL_Extension_ref/Object.tex @@ -37,7 +37,7 @@ Objects of type \ccRefName\ are normally created using the global function \ccMethod{Object &operator=(const Object &o);} {Assignment.} -\ccMethod{bool is_empty();}{returns true, if \ccVar\ does not +\ccMethod{bool empty();}{returns true, if \ccVar\ does not contain an object.} \ccMethod{const std::type_info & type() const;} diff --git a/STL_Extension/include/CGAL/Handle_for.h b/STL_Extension/include/CGAL/Handle_for.h index 6584bcace21..2126ba9bc50 100644 --- a/STL_Extension/include/CGAL/Handle_for.h +++ b/STL_Extension/include/CGAL/Handle_for.h @@ -55,18 +55,6 @@ public: ptr_->count = 1; } - Handle_for(const Handle_for& h) - : ptr_(h.ptr_) - { - ++(ptr_->count); - } - - // TODO : - // We should also think about providing template constructors in - // order to forward the functionality of T to Handle_for without - // the need to an intermediate copy. - // Currently it's not working, because some places use conversions. - Handle_for(const T& t) : ptr_(allocator.allocate(1)) { @@ -74,6 +62,15 @@ public: ptr_->count = 1; } +#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + Handle_for(T && t) + : ptr_(allocator.allocate(1)) + { + new (&(ptr_->t)) T(std::move(t)); + ptr_->count = 1; + } +#endif + /* I comment this one for now, since it's preventing the automatic conversions to take place. We'll see if it's a problem later. template < typename T1 > @@ -85,6 +82,15 @@ public: } */ +#if !defined CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES && !defined CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + template < typename T1, typename T2, typename... Args > + Handle_for(T1 && t1, T2 && t2, Args && ... args) + : ptr_(allocator.allocate(1)) + { + new (&(ptr_->t)) T(std::forward(t1), std::forward(t2), std::forward(args)...); + ptr_->count = 1; + } +#else template < typename T1, typename T2 > Handle_for(const T1& t1, const T2& t2) : ptr_(allocator.allocate(1)) @@ -108,15 +114,12 @@ public: new (&(ptr_->t)) T(t1, t2, t3, t4); ptr_->count = 1; } +#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES - ~Handle_for() + Handle_for(const Handle_for& h) + : ptr_(h.ptr_) { - if (! is_shared() ) { - allocator.destroy( ptr_); - allocator.deallocate( ptr_, 1); - } - else - --(ptr_->count); + ++(ptr_->count); } Handle_for& @@ -138,6 +141,39 @@ public: return *this; } +#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + // Note : I don't see a way to make a useful move constructor, apart + // from e.g. using NULL as a ptr value, but this is drastic. + + Handle_for& + operator=(Handle_for && h) + { + swap(h); + return *this; + } + + Handle_for& + operator=(T && t) + { + if (is_shared()) + *this = Handle_for(std::move(t)); + else + ptr_->t = std::move(t); + + return *this; + } +#endif + + ~Handle_for() + { + if (! is_shared() ) { + allocator.destroy( ptr_); + allocator.deallocate( ptr_, 1); + } + else + --(ptr_->count); + } + void initialize_with(const T& t) { diff --git a/STL_Extension/include/CGAL/Handle_for_virtual.h b/STL_Extension/include/CGAL/Handle_for_virtual.h index 8a7429a2c7c..ba6f3506c3a 100644 --- a/STL_Extension/include/CGAL/Handle_for_virtual.h +++ b/STL_Extension/include/CGAL/Handle_for_virtual.h @@ -99,6 +99,15 @@ class Handle_for_virtual return *this; } +#ifndef CGAL_CFP_NO_CPP0X_RVALUE_REFERENCE + Handle_for_virtual& + operator=( Handle_for_virtual && h) + { + swap(h); + return *this; + } +#endif + // protected: typedef RefCounted element_type; @@ -117,6 +126,10 @@ class Handle_for_virtual id() const { return reinterpret_cast(&*ptr); } + void + swap(Handle_for_virtual & h) + { std::swap(h.ptr, ptr); } + const RefCounted * Ptr() const { return ptr; } @@ -158,8 +171,6 @@ protected: } */ -private: - RefCounted * ptr; }; diff --git a/STL_Extension/include/CGAL/Object.h b/STL_Extension/include/CGAL/Object.h index e2f754c043d..701ea8ca4a1 100644 --- a/STL_Extension/include/CGAL/Object.h +++ b/STL_Extension/include/CGAL/Object.h @@ -38,15 +38,19 @@ CGAL_BEGIN_NAMESPACE template class Wrapper : public Ref_counted_virtual { + Wrapper(const Wrapper&); // deleted to make sure we don't make useless copies public: + Wrapper(const T& object) : _object(object) {} - Wrapper() {} - - operator T() const { return _object; } +#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + Wrapper(T && object) : _object(std::move(object)) {} +#endif ~Wrapper() {} + const T& get() const { return _object; } + virtual const std::type_info & type() const { return typeid(T); @@ -64,7 +68,7 @@ class Wrapper : public Ref_counted_virtual class Object : public Handle_for_virtual { - struct empty {}; + struct Empty {}; typedef Handle_for_virtual base; public: @@ -73,14 +77,25 @@ class Object Object() { - initialize_with(Wrapper()); + typedef Wrapper Wrap; + ptr = new Wrap(Empty()); } +#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE + template + Object(T && t, private_tag) + { + typedef Wrapper< typename std::remove_reference< typename std::remove_cv::type >::type > Wrap; + ptr = new Wrap(std::forward(t)); + } +#else template Object(const T&t, private_tag) { - initialize_with(Wrapper(t)); + typedef Wrapper Wrap; + ptr = new Wrap(t); } +#endif template bool assign(T &t) const @@ -91,31 +106,48 @@ class Object const Wrapper *wp = dynamic_cast *>(Ptr()); if (wp == NULL) return false; - t = *wp; + t = wp->get(); #ifdef _MSC_VER } catch (...) { - CGAL_error_msg( "Your compiler must support RTTI"); + CGAL_error_msg("Your compiler must support Run-Time Type Information (RTTI)"); } #endif return true; } + bool + empty() const + { + Empty E; + return assign(E); + } + + // is_empty() is kept for backward compatibility. + // empty() was introduced for consistency with e.g. std::vector::empty(). bool is_empty() const { - empty E; - return assign(E); + return empty(); } const std::type_info & type() const { - return is_empty() ? typeid(void) : Ptr()->type(); + return empty() ? typeid(void) : Ptr()->type(); } }; +#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE +template +inline +Object +make_object(T && t) +{ + return Object(std::forward(t), Object::private_tag()); +} +#else template inline Object @@ -123,6 +155,7 @@ make_object(const T& t) { return Object(t, Object::private_tag()); } +#endif template inline @@ -143,14 +176,6 @@ struct Bad_object_cast } }; -/* -template -inline -T * object_cast(Object * o) -{ - return o && o->type() == typeid(T) ? o->object_ptr() : NULL; -} -*/ template inline @@ -160,9 +185,6 @@ const T * object_cast(const Object * o) if (wp == NULL) return NULL; return static_cast(wp->object_ptr()); -// return o && o->type() == typeid(T) -// ? static_cast(o->object_ptr()) -// : NULL; } template