Documentation Home >> Headers >> <jss/experimental_atomic.hpp> Header >> std::experimental::shared_ptr class template

The std::experimental::shared_ptr class template is an implementation of std::shared_ptr that integrates with std::experimental::atomic_shared_ptr. It is a complete drop-in replacement: you can just switch everywhere that uses std::shared_ptr to use std::experimental::shared_ptr instead, and everything should work as before.

The reason for the new implementation is that the core reference counting data structure needs to be modified to accommodate the additional requirements of std::experimental::atomic_shared_ptr, which are not supported by std::shared_ptr.

To handle the cases where it is not acceptable to replace all uses of std::shared_ptr throughout a codebase, instances of std::experimental::shared_ptr<T> can be converted to and from std::shared_ptr<T> and std::tr1::shared_ptr<T> if either is available from the native library on a given platform. Conversion in either direction will require allocating an additional data structure, but conversion back to the source type will seamlessly return a correct instance of the source type without any further allocation. The pointed-to object remains the same in all cases.

std::shared_ptr<int> sp(std::make_shared<int>(42));
std::experimental::shared_ptr<int> sp2=sp; // allocates new data structure
assert(sp2.get()==sp.get());
std::shared_ptr<int> sp3=sp2; // no allocation
assert(!sp3.owner_before(sp)); // sp and sp3 share the same header block
assert(!sp.owner_before(sp3));

std::experimental::shared_ptr<int> sp4(std::experimental::make_shared<int>(42));
std::shared_ptr<int> sp5=sp4; // allocates new data structure
assert(sp5.get()==sp4.get());
std::experimental::shared_ptr<int> sp6=sp5; // no allocation
assert(!sp6.owner_before(sp4)); // sp4 and sp6 share the same header block
assert(!sp4.owner_before(sp6));

For details on the operations, see std::experimental::shared_ptr operations.

template<typename T>
class shared_ptr
{
public:
    constexpr shared_ptr() noexcept;
    ~shared_ptr() noexcept;

    template<class Target>
    explicit shared_ptr(Target* p);
    template<class Target, class Deleter>
    shared_ptr(Target* p, Deleter d);
    template<class Target, class Deleter,typename Allocator>
    shared_ptr(Target* p, Deleter d,Allocator a);

    shared_ptr(nullptr_t);
    template<class Deleter>
    shared_ptr(nullptr_t p, Deleter d);

    template<class U>
    shared_ptr(const shared_ptr<U>& other, T* p) noexcept;

    shared_ptr(shared_ptr const& other) noexcept;
    shared_ptr(shared_ptr&&  other) noexcept;

    template<typename U>
    shared_ptr(shared_ptr<U>&&  other) noexcept;
    template<typename U>
    shared_ptr(shared_ptr<U> const& other) noexcept;
    template<typename U>
    explicit shared_ptr(weak_ptr<U> const& other);

    template<typename U>
    shared_ptr(std::auto_ptr<U>&& other);
    template<typename U,typename Deleter>
    shared_ptr(std::unique_ptr<U,Deleter>&& other);

    shared_ptr(std::shared_ptr<T> other);
    operator std::shared_ptr<T>() const;
    shared_ptr(std::tr1::shared_ptr<T> other);
    operator std::tr1::shared_ptr<T>() const;


    shared_ptr& operator=(shared_ptr&& other) noexcept;

    template<typename U>
    shared_ptr& operator=(shared_ptr<U>&& other) noexcept;

    shared_ptr& operator=(shared_ptr const& other) noexcept;

    template<class U>
    shared_ptr& operator=(const shared_ptr<U>& other) noexcept;
    template<class U>
    shared_ptr& operator=(std::auto_ptr<U>&& other);
    template<class U,class Deleter>
    shared_ptr& operator=(std::unique_ptr<U,Deleter>&& other);

    void swap(shared_ptr& other) noexcept;

    T* operator->() const noexcept;
    T* get() const noexcept;
    T& operator*() const noexcept;

    void reset() noexcept;

    template<class Target>
    void reset(Target* p);

    template<class Target, class Deleter>
    void reset(Target* p, Deleter d);

    template<class Target, class Deleter,class Allocator>
    void reset(Target* p, Deleter d,Allocator a);

    long use_count() const noexcept;
    bool unique() const noexcept;
    bool operator!() const noexcept;
    explicit operator bool () noexcept;

    template<class U>
    bool owner_before(shared_ptr<U> const& other) const noexcept;
    template<class U>
    bool owner_before(weak_ptr<U> const& other) const noexcept;
};

template<class Deleter, class Target>
Deleter* get_deleter(const shared_ptr<Target>& p) noexcept;

template<typename T,typename U>
inline bool operator==(shared_ptr<T> const& lhs,shared_ptr<U> const& rhs) noexcept;

template<typename T,typename U>
inline bool operator!=(shared_ptr<T> const& lhs,shared_ptr<U> const& rhs) noexcept;

template<typename T,typename U>
inline bool operator<(shared_ptr<T> const& lhs,shared_ptr<U> const& rhs) noexcept;

template<typename T,typename U>
inline bool operator>(shared_ptr<T> const& lhs,shared_ptr<U> const& rhs) noexcept;

template<typename T,typename U>
inline bool operator>=(shared_ptr<T> const& lhs,shared_ptr<U> const& rhs) noexcept;

template<typename T,typename U>
inline bool operator<=(shared_ptr<T> const& lhs,shared_ptr<U> const& rhs) noexcept;

template<typename T,typename ... Args>
shared_ptr<T> make_shared(Args&& ... args);

template<typename Target,typename Source>
shared_ptr<Target> static_pointer_cast(shared_ptr<Source> const& other);

template<typename Target,typename Source>
shared_ptr<Target> dynamic_pointer_cast(shared_ptr<Source> const& other);
Header

#include <experimental/atomic>

See Also