Instances of std::experimental::weak_ptr hold non-owning
          pointers to objects owned by one or more std::experimental::shared_ptr instances. A std::experimental::weak_ptr
          cannot be dereferenced directly, but must be converted to a std::experimental::shared_ptr instance beforehand,
          which will then share ownership of the pointer with the other std::experimental::shared_ptr instances.
        
          When the last std::experimental::shared_ptr object that owns a
          pointer referenced by a std::experimental::weak_ptr instance is destroyed
          or reassigned, that std::experimental::weak_ptr instance is expired, and attempts to convert that std::experimental::weak_ptr instance to a std::experimental::shared_ptr will fail.
        
          The std::experimental::weak_ptr class template is an implementation
          of std::weak_ptr that integrates with std::experimental::atomic_weak_ptr. It is a complete
          drop-in replacement: you can just switch everywhere that uses std::weak_ptr to use std::experimental::weak_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_weak_ptr, which are not
          supported by std::weak_ptr.
        
          To handle the cases where it is not acceptable to replace all uses of
          std::weak_ptr throughout a codebase, instances
          of std::experimental::weak_ptr<T>
          can be converted from std::weak_ptr<T> and std::tr1::weak_ptr<T> if either is available from the native
          library on a given platform. This will require allocating an additional
          data structure if the store pointer was not first owned by a std::experimental::shared_ptr instance.
        
template<typename T> class weak_ptr { public: constexpr weak_ptr() noexcept; weak_ptr(weak_ptr const& other) noexcept; weak_ptr(weak_ptr&& other) noexcept; template<class Other> weak_ptr(weak_ptr<Other> const& other) noexcept; template<class Other> weak_ptr(weak_ptr<Other>&& other) noexcept; template<class Other> weak_ptr(shared_ptr<Other> const& other) noexcept; weak_ptr(std::weak_ptr<T> other); weak_ptr(std::tr1::weak_ptr<T> other); ~weak_ptr(); weak_ptr& operator=(weak_ptr const& other) noexcept; weak_ptr& operator=(weak_ptr&& other) noexcept; template<typename Other> weak_ptr& operator=(weak_ptr<Other> const& other) noexcept; template<typename Other> weak_ptr& operator=(weak_ptr<Other>&& other) noexcept; void swap(weak_ptr& other) noexcept; void reset() noexcept; long use_count() const noexcept; bool expired() const noexcept; shared_ptr<T> lock() const noexcept; template<typename Other> bool owner_before(shared_ptr<Other> const&) const noexcept; template<typename Other> bool owner_before(weak_ptr<Other> const&) const noexcept; };
          #include <experimental/atomic>