|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TCG_UNIQUE_PTR_H
|
|
Toshihiro Shimizu |
890ddd |
#define TCG_UNIQUE_PTR_H
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "traits.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "base.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "deleter_types.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STD includes
|
|
Toshihiro Shimizu |
890ddd |
#include "assert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include <utility></utility>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// unique_ptr definition
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
\brief The unique_ptr class is a C++03 compatibility class that implements
|
|
Toshihiro Shimizu |
890ddd |
a \a noncopyable smart pointer, similarly to \p boost::scoped_ptr,
|
|
Toshihiro Shimizu |
890ddd |
but accepting a custom deleter type as template parameter.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\details \par Properties
|
|
Toshihiro Shimizu |
890ddd |
This class provides the following features:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
It's noncopyable, like \p boost::scoped_ptr.
|
|
Toshihiro Shimizu |
890ddd |
Unlike \p boost::scoped_ptr, it provides the release() method.
|
|
Toshihiro Shimizu |
890ddd |
Arrays are valid template types - so <tt>tcg::unique_ptr<int []=""></int></tt>
|
|
Toshihiro Shimizu |
890ddd |
is accepted and works as expected.
|
|
Toshihiro Shimizu |
890ddd |
Like \p std::unique_ptr, it accepts custom \a inheritable deallocators.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\par Incomplete types
|
|
Toshihiro Shimizu |
890ddd |
Like \p boost::scoped_ptr, incomplete types are accepted as template
|
|
Toshihiro Shimizu |
890ddd |
parameter, \a provided their definition is completed by the time the destructor
|
|
Toshihiro Shimizu |
890ddd |
is invoked. In particular, pointers to incomplete types \b must be stored in
|
|
Toshihiro Shimizu |
890ddd |
classes whose destructor is defined in an implementation file - and remember
|
|
Toshihiro Shimizu |
890ddd |
that compiler-generated destructors are always implicitly inlined.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\par Type erasure
|
|
Toshihiro Shimizu |
890ddd |
Unlike shared_ptr, this class does not employ type erasure
|
|
Toshihiro Shimizu |
890ddd |
on the deleter object - which is an explicit template argument by
|
|
Toshihiro Shimizu |
890ddd |
default. This means that the pointed object type must be \b complete
|
|
Toshihiro Shimizu |
890ddd |
at the moment the \p unique_ptr is destroyed, \a except if the
|
|
Toshihiro Shimizu |
890ddd |
supplied deleter is type-erased on its own.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\remark The C++11 class \p std::unique_ptr should be preferred, if possible.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename d="typename" t,="" tcg::deleter<t="" typename="">></typename>
|
|
Toshihiro Shimizu |
890ddd |
class unique_ptr : private D // Empty Base Optimization
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
typedef typename tcg::traits<t>::element_type element_type;</t>
|
|
Toshihiro Shimizu |
890ddd |
typedef typename tcg::traits<element_type>::pointer_type ptr_type;</element_type>
|
|
Toshihiro Shimizu |
890ddd |
typedef typename tcg::traits<element_type>::reference_type ref_type;</element_type>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
explicit unique_ptr(ptr_type ptr = ptr_type()) // Explicit unary constructors
|
|
Toshihiro Shimizu |
890ddd |
: m_ptr(ptr)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
explicit unique_ptr(D d) : m_ptr(), D(d) {} //
|
|
Toshihiro Shimizu |
890ddd |
unique_ptr(ptr_type ptr, D d) : m_ptr(ptr), D(d) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~unique_ptr() { D::operator()(m_ptr); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
friend void swap(unique_ptr &a, unique_ptr &b)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
using std::swap;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
swap(static_cast<d &="">(a), static_cast<d &="">(b));</d></d>
|
|
Toshihiro Shimizu |
890ddd |
swap(a.m_ptr, b.m_ptr);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Explicitly disabled (safe) conversion to bool - although
|
|
Toshihiro Shimizu |
890ddd |
// std::unique_ptr could support it, that would just add overhead.
|
|
Toshihiro Shimizu |
890ddd |
// It's also not compatible with other C++03 smart pointers.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//typedef ptr_type unique_ptr::* bool_type;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//operator bool_type() const // Safe bool idiom
|
|
Toshihiro Shimizu |
890ddd |
// { return m_ptr ? &unique_ptr::m_ptr : 0; } // additional branching!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ptr_type operator->() const { return m_ptr; }
|
|
Toshihiro Shimizu |
890ddd |
ref_type operator*() const { return *m_ptr; }
|
|
Toshihiro Shimizu |
890ddd |
ref_type operator[](size_t idx) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_ptr[idx];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void reset(ptr_type ptr = ptr_type())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
D::operator()(m_ptr);
|
|
Toshihiro Shimizu |
890ddd |
m_ptr = ptr;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void reset(ptr_type ptr, D d)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
reset(ptr);
|
|
Toshihiro Shimizu |
890ddd |
D::operator=(d);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ptr_type release()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ptr_type ptr = m_ptr;
|
|
Toshihiro Shimizu |
890ddd |
m_ptr = ptr_type();
|
|
Toshihiro Shimizu |
890ddd |
return ptr;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const ptr_type get() const { return m_ptr; }
|
|
Toshihiro Shimizu |
890ddd |
ptr_type get() { return m_ptr; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
ptr_type m_ptr;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} // namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif // TCG_UNIQUE_PTR_H
|