реализация safe_ptr

Я пытаюсь реализовать безопасную версию std :: shared_ptr, называемую "safe_ptr", которая гарантирует "ненулевое значение".

EDIT: Вопрос удален. Смотрите редактировать, если интересно. Отправка окончательного решения всем заинтересованным:

Этот код теперь размещен на код Google .

#pragma once

#include 
#include 
#include 

template
class safe_ptr
{   
    template  friend class safe_ptr;
public:
    typedef T element_type;

    safe_ptr() : impl_(std::make_shared()){} 

    safe_ptr(const safe_ptr& other) : impl_(other.impl_){}

    template
    safe_ptr(const safe_ptr& other, typename std::enable_if::value, void*>::type = 0) : impl_(other.impl_){}

    template    
    safe_ptr(const U& impl, typename std::enable_if::type, T*>::value, void>::type* = 0)
        : impl_(std::make_shared(impl)) {}

    template        
    safe_ptr(const U& impl, D dtor, typename std::enable_if::type, T*>::value, void>::type* = 0)
        : impl_(new U(impl), dtor) {}

    template    
    safe_ptr(U&& impl, typename std::enable_if::type, T*>::value, void>::type* = 0)
        : impl_(std::make_shared(std::forward(impl))) {}

    template    
    safe_ptr(U&& impl, D dtor, typename std::enable_if::type, T*>::value, void>::type* = 0)
        : impl_(new U(std::forward(impl)), dtor) {}

    template    
    explicit safe_ptr(const std::shared_ptr& impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl)
    {
        if(!impl_)
            throw std::invalid_argument("impl");
    }

    template    
    explicit safe_ptr(std::shared_ptr&& impl, typename std::enable_if::value, void*>::type = 0) : impl_(std::move(impl))
    {
        if(!impl_)
            throw std::invalid_argument("impl");
    }

    template    
    explicit safe_ptr(U* impl, typename std::enable_if::value, void*>::type = 0) : impl_(impl)
    {
        if(!impl_)
            throw std::invalid_argument("impl");
    }

    template    
    explicit safe_ptr(U* impl, D dtor, typename std::enable_if::value, void*>::type = 0) : impl_(impl, dtor)
    {
        if(!impl_)
            throw std::invalid_argument("impl");
    }

    template
    typename std::enable_if::value, safe_ptr&>::type
    operator=(const safe_ptr& other)
    {
        safe_ptr temp(other);
        temp.swap(*this);
        return *this;
    }

    template 
    typename std::enable_if::type, T*>::value, safe_ptr&>::type
    operator=(U&& impl)
    {
        safe_ptr temp(std::forward(impl));
        temp.swap(*this);
        return *this;
    }

    T& operator*() const { return *impl_.get();}

    T* operator->() const { return impl_.get();}

    T* get() const { return impl_.get();}

    bool unique() const { return impl_.unique();}

    long use_count() const { return impl_.use_count();}

    void swap(safe_ptr& other) { impl_.swap(other.impl_); } 

    operator std::shared_ptr() const { return impl_;}

    template
    bool owner_before(const safe_ptr& ptr){ return impl_.owner_before(ptr.impl_); }

    template
    bool owner_before(const std::shared_ptr& ptr){ return impl_.owner_before(ptr); }

    template 
    D* get_deleter(safe_ptr const& ptr) { return impl_.get_deleter(); }

private:    
    std::shared_ptr impl_;
};

template
bool operator==(const safe_ptr& a, const safe_ptr& b)
{
    return a.get() == b.get();
}

template
bool operator!=(const safe_ptr& a, const safe_ptr& b)
{
    return a.get() != b.get();
}

template
bool operator<(const safe_ptr& a, const safe_ptr& b)
{
    return a.get() < b.get();
}

template
bool operator>(const safe_ptr& a, const safe_ptr& b)
{
    return a.get() > b.get();
}

template
bool operator>=(const safe_ptr& a, const safe_ptr& b)
{
    return a.get() >= b.get();
}

template
bool operator<=(const safe_ptr& a, const safe_ptr& b)
{
    return a.get() <= b.get();
}

template
std::basic_ostream& operator<<(std::basic_ostream& out, const safe_ptr& p)
{
    return out << p.get();
}

template 
void swap(safe_ptr& a, safe_ptr& b)
{
    a.swap(b);
}

template 
T* get_pointer(safe_ptr const& p)
{
    return p.get();
}

template 
safe_ptr static_pointer_cast(const safe_ptr& p)
{
    return safe_ptr(std::static_pointer_cast(std::shared_ptr(p)));
}

template 
safe_ptr const_pointer_cast(const safe_ptr& p)
{
    return safe_ptr(std::const_pointer_cast(std::shared_ptr(p)));
}

template 
safe_ptr dynamic_pointer_cast(const safe_ptr& p)
{
    auto temp = std::dynamic_pointer_cast(std::shared_ptr(p));
    if(!temp)
        throw std::bad_cast();
    return safe_ptr(temp);
}

template
safe_ptr make_safe()
{
    return safe_ptr();
}

template
safe_ptr make_safe(P0&& p0)
{
    return safe_ptr(std::make_shared(std::forward(p0)));
}

template
safe_ptr make_safe(P0&& p0, P1&& p1)
{
    return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1)));
}

template
safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2)
{
    return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2)));
}

template
safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3)
{
    return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3)));
}

template
safe_ptr make_safe(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&&)
{
    return safe_ptr(std::make_shared(std::forward(p0), std::forward(p1), std::forward(p2), std::forward(p3), std::forward(p4)));
}

5
задан 16 revs 10 October 2011 в 17:27
поделиться