Boost logo

Boost :

Subject: Re: [boost] unique_ptr for C++03
From: Eric Niebler (eniebler_at_[hidden])
Date: 2013-08-03 17:15:42


On 8/3/2013 2:12 PM, Eric Niebler wrote:
>
> On 8/3/2013 2:00 AM, Andrew Ho wrote:
>> Hi,
>>
>> I implemented std::unique_ptr using C++03 features plus a few other
>> Boost Libraries. Incidentally, I also implemented default_delete
>> (which binds to std::default_delete if available) because it's
>> required for unique_ptr.
>>
>> https://github.com/helloworld922/unique_ptr
>
> I never participated much in the discussion of Boost.Move, so I don't
> know if this emulation approach was ever discussed, but once upon a
> time I developed my own technique to simulate move-only types in
> C++03. I never did anything with this technique when I first
> discovered it (about 10 years ago now), and indeed completely forgot
> about it until now.
>
> Not extensively tested. Might miss important corner cases ...
<snip>

Sorry! Forgot move assignment:

    template<typename T>
    struct unique_ptr;

    template<typename T>
    struct unique_ptr_ref
    {
        explicit unique_ptr_ref(T *p)
          : p_(p)
        {}
    private:
        friend struct unique_ptr<T>;
        T *p_;
    };

    template<typename T>
    struct unique_ptr
    {
        unique_ptr()
          : p_(0)
        {}

        explicit unique_ptr(T *p)
          : p_(p)
        {}

        unique_ptr(unique_ptr_ref<T> r)
          : p_(r.p_)
        {}

        unique_ptr &operator=(unique_ptr_ref<T> r)
        {
            delete p_;
            p_ = r.p_;
            return *this;
        }

        ~unique_ptr()
        {
            delete p_;
        }

        operator unique_ptr_ref<T>()
        {
            unique_ptr_ref<T> r(p_);
            p_ = 0;
            return r;
        }

        T *operator->() const
        {
            return p_;
        }

        T &operator*() const
        {
            return *p_;
        }

    private:
        unique_ptr(unique_ptr &); // param must be non-const ref
        unique_ptr &operator=(unique_ptr &);
        T *p_;
    };

    template<typename T>
    unique_ptr<T> make_unique()
    {
        return unique_ptr<T>(new T);
    }

    template<typename T>
    unique_ptr<T> move(unique_ptr<T> &p)
    {
        return unique_ptr<T>(static_cast<unique_ptr_ref<T> >(p));
    }

    int main()
    {
        unique_ptr<int> p = make_unique<int>();
        //unique_ptr<int> no = p; // <== ERROR
        unique_ptr<int> yes = move(p); // <== OK
        p = move(yes);
    }

-- 
Eric Niebler
Boost.org
http://www.boost.org

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk