/* * Copyright (c) 2017-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include unsigned long int __infer_nondet_unsigned_long_int(); INFER_NAMESPACE_STD_BEGIN // forward declaration because it is used here template class shared_ptr; // Ideally: : public std__weak_ptr // use inheritance to avoid compilation errors when using // methods / non-member functions that are not modeled // Currently not inherited because it leads to Symexec_memory_error template class weak_ptr { template friend class weak_ptr; // WARNING: if sizeof(weak_ptr) becomes different than 16, it may // lead to compilation errors T* ptr; void* __ignore; public: // Conversion constructors to allow implicit conversions. // it's here purely to avoid compilation errors template ::value>::type> weak_ptr(const std__weak_ptr& r) {} // constructors: constexpr weak_ptr() noexcept { ptr = nullptr; } template ::value>::type> weak_ptr(const shared_ptr& r) noexcept { ptr = r.get(); } weak_ptr(const weak_ptr& r) noexcept { ptr = r.ptr; } template ::value>::type> weak_ptr(const weak_ptr& r) noexcept { ptr = r.ptr; } weak_ptr(weak_ptr&& r) noexcept { ptr = r.ptr; r.ptr = nullptr; } template ::value>::type> weak_ptr(weak_ptr&& r) noexcept { ptr = r.ptr; r.ptr = nullptr; } // destructor: ~weak_ptr() { ptr = nullptr; } // assignment: weak_ptr& operator=(const weak_ptr& r) noexcept { // weak_ptr(r).swap(*this); ptr = r.ptr; return *this; } template ::value>::type> weak_ptr& operator=(const weak_ptr& r) noexcept { // weak_ptr(r).swap(*this); ptr = r.ptr; return *this; } template ::value>::type> weak_ptr& operator=(const shared_ptr& r) noexcept { // weak_ptr(r).swap(*this); ptr = r.get(); return *this; } weak_ptr& operator=(weak_ptr&& r) noexcept { // shared_ptr(std::move(r)).swap(*this); ptr = r.ptr; r.ptr = nullptr; return *this; } template ::value>::type> weak_ptr& operator=(weak_ptr&& r) { // weak_ptr(std::move(r)).swap(*this); ptr = r.ptr; r.ptr = nullptr; return *this; } // modifiers: void swap(weak_ptr& r) noexcept { T* tmp = ptr; ptr = r.ptr; r.ptr = tmp; } void reset() noexcept { // weak_ptr().swap(*this); ptr = nullptr; } // observers: long use_count() const noexcept { if (ptr) { return __infer_nondet_unsigned_long_int(); } return 0; } bool expired() const noexcept { return use_count() <= 0; } shared_ptr lock() const noexcept { if (use_count() > 0) { return shared_ptr(ptr); } return shared_ptr(); } template bool owner_before(shared_ptr const& b) const { return true; /* FIXME - use non-det*/ } template bool owner_before(weak_ptr const& b) const { return true; /* FIXME - use non-det */ } }; template struct owner_less; template struct owner_less> : binary_function, weak_ptr, bool> { typedef bool result_type; bool operator()(weak_ptr const& x, weak_ptr const& y) const { return x.owner_before(y); } bool operator()(shared_ptr const& x, weak_ptr const& y) const { return x.owner_before(y); } bool operator()(weak_ptr const& x, shared_ptr const& y) const { return x.owner_before(y); } }; INFER_NAMESPACE_STD_END