|
Boost : |
From: Daniel Wallin (dalwan01_at_[hidden])
Date: 2004-01-20 19:06:09
I'm moving this to a new thread.
Not every smart pointer has to handle every possible case. If you want
custom deleters, use shared_ptr<>. The extra storage needed for the
deleter IMO just isn't justified for something as simple as an ownership
transfer utility. What I do find interesting though is the ability to
delete incomplete types, IOW at some level capture of type at
construction.
I'm attaching the implementation that I believe should be pushed
further.
-- Daniel Wallin
// Copyright Daniel Wallin 2004. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Based on auto_ptr<> implementation by Rani Sharoni.
#ifndef BOOST_MOVE_PTR_HPP
#define BOOST_MOVE_PTR_HPP
#include <algorithm>
namespace boost {
template<class T>
struct move_source
{
move_source(T& x) : source(x) {}
T& source;
private:
move_source(T const&);
};
template<class T>
move_source<T> move(T& x)
{
return move_source<T>(x);
}
template<class T>
class move_ptr
{
public:
move_ptr() : m_p(0) {}
move_ptr(const move_ptr& p)
: m_p(const_cast<move_ptr&>(p).release())
{
}
template<class U>
move_ptr(const move_ptr<U>& p)
: m_p(const_cast<move_ptr<U>&>(p).release())
{
delete_fn = &delete_aux::delete_;
}
template<class U>
move_ptr(move_source<move_ptr<U> > x)
: m_p(x.source.release())
{
delete_fn = &delete_aux::delete_;
}
explicit move_ptr(T* p) : m_p(p)
{
delete_fn = &delete_aux::delete_;
}
~move_ptr()
{
if (m_p) delete_fn(m_p);
}
move_ptr& operator=(move_ptr p)
{
p.swap(*this);
return *this;
}
T* release()
{
T* p = m_p;
m_p = 0;
return p;
}
void reset(T* p = 0)
{
move_ptr(p).swap(*this);
}
void swap(move_ptr& p)
{
std::swap(m_p, p.m_p);
}
T& operator*() const
{
return *m_p;
}
T* get() const
{
return m_p;
}
T* operator->() const
{
return m_p;
}
struct implementation_detail { bool b; };
typedef bool implementation_detail::*safe_bool_type;
operator safe_bool_type() const
{
return m_p ? &implementation_detail::b : 0;
}
private:
template<class U>
struct cant_move_from_const;
template<class U>
struct cant_move_from_const<const move_ptr<U> >
{
typedef typename move_ptr<U>::error type;
};
template<class U>
move_ptr(U&, typename cant_move_from_const<U>::type = 0);
move_ptr(move_ptr&);
template<class U> move_ptr(move_ptr<U>&);
struct delete_aux
{
static void delete_(T* p) { delete p; }
};
typedef void(*delete_fn_t)(T*);
T* m_p;
static delete_fn_t delete_fn;
};
template<class T>
typename move_ptr<T>::delete_fn_t move_ptr<T>::delete_fn = 0;
} // namespace boost
#endif // BOOST_MOVE_PTR_HPP
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk