namespace std {
template<class T> class weak_ptr {
public:
using element_type = remove_extent_t<T>;
// [util.smartptr.weak.const], constructors
constexpr weak_ptr() noexcept;
template<class Y>
weak_ptr(const shared_ptr<Y>& r) noexcept;
weak_ptr(const weak_ptr& r) noexcept;
template<class Y>
weak_ptr(const weak_ptr<Y>& r) noexcept;
weak_ptr(weak_ptr&& r) noexcept;
template<class Y>
weak_ptr(weak_ptr<Y>&& r) noexcept;
// [util.smartptr.weak.dest], destructor
~weak_ptr();
// [util.smartptr.weak.assign], assignment
weak_ptr& operator=(const weak_ptr& r) noexcept;
template<class Y>
weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
template<class Y>
weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
weak_ptr& operator=(weak_ptr&& r) noexcept;
template<class Y>
weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
// [util.smartptr.weak.mod], modifiers
void swap(weak_ptr& r) noexcept;
void reset() noexcept;
// [util.smartptr.weak.obs], observers
long use_count() const noexcept;
bool expired() const noexcept;
shared_ptr<T> lock() const noexcept;
template<class U>
bool owner_before(const shared_ptr<U>& b) const noexcept;
template<class U>
bool owner_before(const weak_ptr<U>& b) const noexcept;
};
template<class T>
weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
// [util.smartptr.weak.spec], specialized algorithms
template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
}constexpr weak_ptr() noexcept;
weak_ptr(const weak_ptr& r) noexcept;
template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
weak_ptr(weak_ptr&& r) noexcept;
template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
~weak_ptr();
weak_ptr& operator=(const weak_ptr& r) noexcept;
template<class Y> weak_ptr& operator=(const weak_ptr<Y>& r) noexcept;
template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
weak_ptr& operator=(weak_ptr&& r) noexcept;
template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
long use_count() const noexcept;
bool expired() const noexcept;
shared_ptr<T> lock() const noexcept;
template<class U> bool owner_before(const shared_ptr<U>& b) const noexcept;
template<class U> bool owner_before(const weak_ptr<U>& b) const noexcept;