mirror of https://github.com/CGAL/cgal
Use C++0x rvalue references in Object, Handle_for, MP_Float and Quotient.
This commit is contained in:
parent
6c9be1ff58
commit
8865f7ea4f
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -96,10 +96,60 @@ class Quotient
|
|||
template <class T>
|
||||
Quotient(const Quotient<T>& 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 <class T1, class T2>
|
||||
Quotient(const T1& n, const T2& d) : num(n), den(d)
|
||||
{ CGAL_precondition( d != 0 ); }
|
||||
|
||||
#else
|
||||
template <class T1, class T2>
|
||||
Quotient(T1 && n, T2 && d)
|
||||
: num(std::forward<T1>(n)), den(std::forward<T2>(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<NT>& operator+= (const Quotient<NT>& r);
|
||||
Quotient<NT>& operator-= (const Quotient<NT>& r);
|
||||
Quotient<NT>& operator*= (const Quotient<NT>& r);
|
||||
|
|
|
|||
|
|
@ -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;}
|
||||
|
|
|
|||
|
|
@ -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<T> 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>(t1), std::forward<T2>(t2), std::forward<Args>(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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<long int>(&*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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,15 +38,19 @@ CGAL_BEGIN_NAMESPACE
|
|||
template <class T>
|
||||
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<Ref_counted_virtual>
|
||||
{
|
||||
struct empty {};
|
||||
struct Empty {};
|
||||
typedef Handle_for_virtual<Ref_counted_virtual> base;
|
||||
|
||||
public:
|
||||
|
|
@ -73,14 +77,25 @@ class Object
|
|||
|
||||
Object()
|
||||
{
|
||||
initialize_with(Wrapper<empty>());
|
||||
typedef Wrapper<Empty> Wrap;
|
||||
ptr = new Wrap(Empty());
|
||||
}
|
||||
|
||||
#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
|
||||
template <class T>
|
||||
Object(T && t, private_tag)
|
||||
{
|
||||
typedef Wrapper< typename std::remove_reference< typename std::remove_cv<T>::type >::type > Wrap;
|
||||
ptr = new Wrap(std::forward<T>(t));
|
||||
}
|
||||
#else
|
||||
template <class T>
|
||||
Object(const T&t, private_tag)
|
||||
{
|
||||
initialize_with(Wrapper<T>(t));
|
||||
typedef Wrapper<T> Wrap;
|
||||
ptr = new Wrap(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
bool assign(T &t) const
|
||||
|
|
@ -91,31 +106,48 @@ class Object
|
|||
const Wrapper<T> *wp = dynamic_cast<const Wrapper<T> *>(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 <class T>
|
||||
inline
|
||||
Object
|
||||
make_object(T && t)
|
||||
{
|
||||
return Object(std::forward<T>(t), Object::private_tag());
|
||||
}
|
||||
#else
|
||||
template <class T>
|
||||
inline
|
||||
Object
|
||||
|
|
@ -123,6 +155,7 @@ make_object(const T& t)
|
|||
{
|
||||
return Object(t, Object::private_tag());
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
|
|
@ -143,14 +176,6 @@ struct Bad_object_cast
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <class T>
|
||||
inline
|
||||
T * object_cast(Object * o)
|
||||
{
|
||||
return o && o->type() == typeid(T) ? o->object_ptr() : NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
|
|
@ -160,9 +185,6 @@ const T * object_cast(const Object * o)
|
|||
if (wp == NULL)
|
||||
return NULL;
|
||||
return static_cast<const T*>(wp->object_ptr());
|
||||
// return o && o->type() == typeid(T)
|
||||
// ? static_cast<const T*>(o->object_ptr())
|
||||
// : NULL;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
|
|||
Loading…
Reference in New Issue