#include <memory>
namespace std {
namespace experimental::inline fundamentals_v3 {
template <class W> class observer_ptr;
template <class W>
void swap(observer_ptr<W>&, observer_ptr<W>&) noexcept;
template <class W>
observer_ptr<W> make_observer(W*) noexcept;
// (in)equality operators
template <class W1, class W2>
bool operator==(observer_ptr<W1>, observer_ptr<W2>);
template <class W1, class W2>
bool operator!=(observer_ptr<W1>, observer_ptr<W2>);
template <class W>
bool operator==(observer_ptr<W>, nullptr_t) noexcept;
template <class W>
bool operator!=(observer_ptr<W>, nullptr_t) noexcept;
template <class W>
bool operator==(nullptr_t, observer_ptr<W>) noexcept;
template <class W>
bool operator!=(nullptr_t, observer_ptr<W>) noexcept;
// ordering operators
template <class W1, class W2>
bool operator<(observer_ptr<W1>, observer_ptr<W2>);
template <class W1, class W2>
bool operator>(observer_ptr<W1>, observer_ptr<W2>);
template <class W1, class W2>
bool operator<=(observer_ptr<W1>, observer_ptr<W2>);
template <class W1, class W2>
bool operator>=(observer_ptr<W1>, observer_ptr<W2>);
} // namespace experimental::inline fundamentals_v3
template <class T> struct hash;
template <class T> struct hash<experimental::observer_ptr<T>>;
} // namespace std
observer_ptr overviewnamespace std::experimental::inline fundamentals_v3 {
template <class W> class observer_ptr {
using pointer = add_pointer_t<W>; // exposition-only
using reference = add_lvalue_reference_t<W>; // exposition-only
public:
// publish our template parameter and variations thereof
using element_type = W;
// default constructor
constexpr observer_ptr() noexcept;
// pointer-accepting constructors
constexpr observer_ptr(nullptr_t) noexcept;
constexpr explicit observer_ptr(pointer) noexcept;
// copying constructors (in addition to the implicit copy constructor)
template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept;
constexpr pointer get() const noexcept;
constexpr reference operator*() const;
constexpr pointer operator->() const noexcept;
constexpr explicit operator bool() const noexcept;
constexpr explicit operator pointer() const noexcept;
constexpr pointer release() noexcept;
constexpr void reset(pointer = nullptr) noexcept;
constexpr void swap(observer_ptr&) noexcept;
}; // observer_ptr<>
} // namespace std::experimental::inline fundamentals_v3
A non-owning pointer, known as an observer, is an object o that stores a pointer to a second object, w.
In this context, w is known as a watched object.
nullptr.o and w.
Specializations of observer_ptr shall meet the requirements
of a W of an observer_ptr
shall not be a reference type, but may be an incomplete type.
observer_ptr include clarity of interface specification in new code,
and interoperability with pointer-based legacy code.
observer_ptr constructorsget() == nullptr.get() == other.W2* is convertible to W*.get() == other.get().observer_ptr observersget() != nullptr is true.*get().get().get() != nullptr.observer_ptr conversionsget().observer_ptr modifiersget() == nullptr.get() had at the start of the call to release.get() == p.swap on the stored pointers of *this and other.observer_ptr specialized algorithmsp1.swap(p2).observer_ptr<W>{p}.p1.get() == p2.get().not (p1 == p2).not p.(bool)p.less<W3>()(p1.get(), p2.get()),
where W3 is the composite pointer type (W1* and W2*.
p2 < p1.not (p2 < p1).not (p1 < p2).observer_ptr hash support
The specialization is enabled (p of type observer_ptr<T>,
hash<observer_ptr<T>>()(p) evaluates to the same value as hash<T*>()(p.get()).
<experimental/memory_resource> synopsisnamespace std::pmr::experimental::inline fundamentals_v3 {
// The name resource_adaptor_imp is for exposition only.
template <class Allocator> class resource_adaptor_imp;
template <class Allocator>
using resource_adaptor = resource_adaptor_imp<
typename allocator_traits<Allocator>::template rebind_alloc<char>>;
} // namespace std::pmr::experimental::inline fundamentals_v3
resource_adaptorresource_adaptor
An instance of resource_adaptor<Allocator> is an adaptor that wraps a memory_resource interface around Allocator.
In order that resource_adaptor<X<T>> and resource_adaptor<X<U>> are the same type for any allocator template X and types T and U,
resource_adaptor<Allocator> is rendered as an alias to a class template such that Allocator is rebound to a char value type in every specialization of the class template.
The requirements on this class template are defined below.
The name resource_adaptor_imp is for exposition only and is not normative,
but the definitions of the members of that class, whatever its name, are normative.
In addition to the resource_adaptor shall meet the following additional requirements:
typename allocator_traits<Allocator>::pointer shall be identical to typename allocator_traits<Allocator>::value_type*.typename allocator_traits<Allocator>::const_pointer shall be identical to typename allocator_traits<Allocator>::value_type const*.typename allocator_traits<Allocator>::void_pointer shall be identical to void*.typename allocator_traits<Allocator>::const_void_pointer shall be identical to void const*.
// The name resource_adaptor_imp is for exposition only.
template <class Allocator>
class resource_adaptor_imp : public memory_resource {
// for exposition only
Allocator m_alloc;
public:
using allocator_type = Allocator;
resource_adaptor_imp() = default;
resource_adaptor_imp(const resource_adaptor_imp&) = default;
resource_adaptor_imp(resource_adaptor_imp&&) = default;
explicit resource_adaptor_imp(const Allocator& a2);
explicit resource_adaptor_imp(Allocator&& a2);
resource_adaptor_imp& operator=(const resource_adaptor_imp&) = default;
allocator_type get_allocator() const { return m_alloc; }
protected:
virtual void* do_allocate(size_t bytes, size_t alignment);
virtual void do_deallocate(void* p, size_t bytes, size_t alignment);
virtual bool do_is_equal(const memory_resource& other) const noexcept;
};
template <class Allocator>
using resource_adaptor = typename resource_adaptor_imp<
typename allocator_traits<Allocator>::template rebind_alloc<char>>;
resource_adaptor_imp constructorsm_alloc with a2.m_alloc with std::move(a2).resource_adaptor_imp member functionsm_alloc.allocate.
The size and alignment of the allocated memory shall meet the requirements
for a class derived from memory_resource (p was previously allocated using A.allocate, where A == m_alloc, and not subsequently deallocated.m_alloc.deallocate().Let p be dynamic_cast<const resource_adaptor_imp*>(&other).
false if p is null, otherwise the value of m_alloc == p->m_alloc.