889 lines
30 KiB
Markdown
889 lines
30 KiB
Markdown
[indirect]
|
||
|
||
# 20 Memory management library [[mem]](./#mem)
|
||
|
||
## 20.4 Types for composite class design [[mem.composite.types]](mem.composite.types#indirect)
|
||
|
||
### 20.4.1 Class template indirect [indirect]
|
||
|
||
#### [20.4.1.1](#general) General [[indirect.general]](indirect.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5901)
|
||
|
||
An indirect object manages the lifetime of an owned object[.](#general-1.sentence-1)
|
||
|
||
An indirect object is[*valueless*](#def:valueless,indirect_object "20.4.1.1 General [indirect.general]") if it has no owned object[.](#general-1.sentence-2)
|
||
|
||
An indirect object may become valueless only after it has been moved from[.](#general-1.sentence-3)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5907)
|
||
|
||
In every specialization indirect<T, Allocator>,
|
||
if the type allocator_traits<Allocator>::value_type is not the same type as T,
|
||
the program is ill-formed[.](#general-2.sentence-1)
|
||
|
||
Every object of type indirect<T, Allocator> uses an object of type Allocator to allocate and free storage
|
||
for the owned object as needed[.](#general-2.sentence-2)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5916)
|
||
|
||
Constructing an owned object with args... using the allocator a means callingallocator_traits<Allocator>::construct(a, *p*, args...) whereargs is an expression pack,a is an allocator, and*p* is a pointer obtained by
|
||
calling allocator_traits<Allocator>::allocate[.](#general-3.sentence-1)
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5925)
|
||
|
||
The member *alloc* is used for
|
||
any memory allocation and element construction
|
||
performed by member functions
|
||
during the lifetime of each indirect object[.](#general-4.sentence-1)
|
||
|
||
The allocator *alloc* may be replaced
|
||
only via assignment or swap()[.](#general-4.sentence-2)
|
||
|
||
Allocator replacement is performed by
|
||
copy assignment,
|
||
move assignment, or
|
||
swapping of the allocator
|
||
only if ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")):
|
||
|
||
- [(4.1)](#general-4.1)
|
||
|
||
allocator_traits<Allocator>::propagate_on_container_copy_assignment::value, or
|
||
|
||
- [(4.2)](#general-4.2)
|
||
|
||
allocator_traits<Allocator>::propagate_on_container_move_assignment::value, or
|
||
|
||
- [(4.3)](#general-4.3)
|
||
|
||
allocator_traits<Allocator>::propagate_on_container_swap::value
|
||
|
||
is true within the implementation of
|
||
the corresponding indirect operation[.](#general-4.sentence-3)
|
||
|
||
[5](#general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5948)
|
||
|
||
A program that instantiates the definition of
|
||
the template indirect<T, Allocator> with
|
||
a type for the T parameter that is
|
||
a non-object type,
|
||
an array type,in_place_t,
|
||
a specialization of in_place_type_t, or
|
||
a cv-qualified type
|
||
is ill-formed[.](#general-5.sentence-1)
|
||
|
||
[6](#general-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5959)
|
||
|
||
The template parameter T of indirect may be an incomplete type[.](#general-6.sentence-1)
|
||
|
||
[7](#general-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5963)
|
||
|
||
The template parameter Allocator of indirect shall meet the *Cpp17Allocator* requirements[.](#general-7.sentence-1)
|
||
|
||
[8](#general-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L5967)
|
||
|
||
If a program declares an explicit or partial specialization of indirect,
|
||
the behavior is undefined[.](#general-8.sentence-1)
|
||
|
||
#### [20.4.1.2](#syn) Synopsis [[indirect.syn]](indirect.syn)
|
||
|
||
[ð](#lib:indirect)
|
||
|
||
namespace std {template<class T, class Allocator = allocator<T>>class indirect {public:using value_type = T; using allocator_type = Allocator; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; // [[indirect.ctor]](#ctor "20.4.1.3 Constructors"), constructorsconstexpr explicit indirect(); constexpr explicit indirect(allocator_arg_t, const Allocator& a); constexpr indirect(const indirect& other); constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other); constexpr indirect(indirect&& other) noexcept; constexpr indirect(allocator_arg_t, const Allocator& a, indirect&& other)noexcept(*see below*); template<class U = T>constexpr explicit indirect(U&& u); template<class U = T>constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u); template<class... Us>constexpr explicit indirect(in_place_t, Us&&... us); template<class... Us>constexpr explicit indirect(allocator_arg_t, const Allocator& a,
|
||
in_place_t, Us&&... us); template<class I, class... Us>constexpr explicit indirect(in_place_t, initializer_list<I> ilist, Us&&... us); template<class I, class... Us>constexpr explicit indirect(allocator_arg_t, const Allocator& a,
|
||
in_place_t, initializer_list<I> ilist, Us&&... us); // [[indirect.dtor]](#dtor "20.4.1.4 Destructor"), destructorconstexpr ~indirect(); // [[indirect.assign]](#assign "20.4.1.5 Assignment"), assignmentconstexpr indirect& operator=(const indirect& other); constexpr indirect& operator=(indirect&& other) noexcept(*see below*); template<class U = T>constexpr indirect& operator=(U&& u); // [[indirect.obs]](#obs "20.4.1.6 Observers"), observersconstexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr const T&& operator*() const && noexcept; constexpr T&& operator*() && noexcept; constexpr const_pointer operator->() const noexcept; constexpr pointer operator->() noexcept; constexpr bool valueless_after_move() const noexcept; constexpr allocator_type get_allocator() const noexcept; // [[indirect.swap]](#swap "20.4.1.7 Swap"), swapconstexpr void swap(indirect& other) noexcept(*see below*); friend constexpr void swap(indirect& lhs, indirect& rhs) noexcept(*see below*); // [[indirect.relops]](#relops "20.4.1.8 Relational operators"), relational operatorstemplate<class U, class AA>friend constexpr bool operator==(const indirect& lhs, const indirect<U, AA>& rhs)noexcept(*see below*); template<class U, class AA>friend constexpr auto operator<=>(const indirect& lhs, const indirect<U, AA>& rhs)-> *synth-three-way-result*<T, U>; // [[indirect.comp.with.t]](#comp.with.t "20.4.1.9 Comparison with T"), comparison with Ttemplate<class U>friend constexpr bool operator==(const indirect& lhs, const U& rhs) noexcept(*see below*); template<class U>friend constexpr auto operator<=>(const indirect& lhs, const U& rhs)-> *synth-three-way-result*<T, U>; private: pointer *p*; // *exposition only* Allocator *alloc* = Allocator(); // *exposition only*}; template<class Value> indirect(Value) -> indirect<Value>; template<class Allocator, class Value> indirect(allocator_arg_t, Allocator, Value)-> indirect<Value, typename allocator_traits<Allocator>::template rebind_alloc<Value>>;}
|
||
|
||
#### [20.4.1.3](#ctor) Constructors [[indirect.ctor]](indirect.ctor)
|
||
|
||
[1](#ctor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6059)
|
||
|
||
The following element applies to all functions in [[indirect.ctor]](#ctor "20.4.1.3 Constructors"):
|
||
|
||
[2](#ctor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6063)
|
||
|
||
*Throws*: Nothing unless allocator_traits<Allocator>::allocate orallocator_traits<Allocator>::construct throws[.](#ctor-2.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor)
|
||
|
||
`constexpr explicit indirect();
|
||
`
|
||
|
||
[3](#ctor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6075)
|
||
|
||
*Constraints*: is_default_constructible_v<Allocator> is true[.](#ctor-3.sentence-1)
|
||
|
||
[4](#ctor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6079)
|
||
|
||
*Mandates*: is_default_constructible_v<T> is true[.](#ctor-4.sentence-1)
|
||
|
||
[5](#ctor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6083)
|
||
|
||
*Effects*: Constructs an owned object of type T with an empty argument list,
|
||
using the allocator *alloc*[.](#ctor-5.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor_)
|
||
|
||
`constexpr explicit indirect(allocator_arg_t, const Allocator& a);
|
||
`
|
||
|
||
[6](#ctor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6095)
|
||
|
||
*Mandates*: is_default_constructible_v<T> is true[.](#ctor-6.sentence-1)
|
||
|
||
[7](#ctor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6099)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized with a[.](#ctor-7.sentence-1)
|
||
|
||
Constructs an owned object of type T with an empty argument list,
|
||
using the allocator *alloc*[.](#ctor-7.sentence-2)
|
||
|
||
[ð](#lib:indirect,constructor__)
|
||
|
||
`constexpr indirect(const indirect& other);
|
||
`
|
||
|
||
[8](#ctor-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6112)
|
||
|
||
*Mandates*: is_copy_constructible_v<T> is true[.](#ctor-8.sentence-1)
|
||
|
||
[9](#ctor-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6116)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized withallocator_traits<Allocator>::select_on_container_copy_construction(other.*alloc*)[.](#ctor-9.sentence-1)
|
||
|
||
If other is valueless, *this is valueless[.](#ctor-9.sentence-2)
|
||
|
||
Otherwise,
|
||
constructs an owned object of type T with *other,
|
||
using the allocator *alloc*[.](#ctor-9.sentence-3)
|
||
|
||
[ð](#lib:indirect,constructor___)
|
||
|
||
`constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other);
|
||
`
|
||
|
||
[10](#ctor-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6132)
|
||
|
||
*Mandates*: is_copy_constructible_v<T> is true[.](#ctor-10.sentence-1)
|
||
|
||
[11](#ctor-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6136)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized with a[.](#ctor-11.sentence-1)
|
||
|
||
If other is valueless, *this is valueless[.](#ctor-11.sentence-2)
|
||
|
||
Otherwise,
|
||
constructs an owned object of type T with *other,
|
||
using the allocator *alloc*[.](#ctor-11.sentence-3)
|
||
|
||
[ð](#lib:indirect,constructor____)
|
||
|
||
`constexpr indirect(indirect&& other) noexcept;
|
||
`
|
||
|
||
[12](#ctor-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6151)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized fromstd::move(other.*alloc*)[.](#ctor-12.sentence-1)
|
||
|
||
If other is valueless, *this is valueless[.](#ctor-12.sentence-2)
|
||
|
||
Otherwise *this takes ownership of the owned object of other[.](#ctor-12.sentence-3)
|
||
|
||
[13](#ctor-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6158)
|
||
|
||
*Postconditions*: other is valueless[.](#ctor-13.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor_____)
|
||
|
||
`constexpr indirect(allocator_arg_t, const Allocator& a, indirect&& other)
|
||
noexcept(allocator_traits<Allocator>::is_always_equal::value);
|
||
`
|
||
|
||
[14](#ctor-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6170)
|
||
|
||
*Mandates*: If allocator_traits<Allocator>::is_always_equal::value is false then T is a complete type[.](#ctor-14.sentence-1)
|
||
|
||
[15](#ctor-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6175)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized with a[.](#ctor-15.sentence-1)
|
||
|
||
If other is valueless, *this is valueless[.](#ctor-15.sentence-2)
|
||
|
||
Otherwise,
|
||
if *alloc* == other.*alloc* is true,
|
||
constructs an object of type indirect that
|
||
takes ownership of the owned object of other[.](#ctor-15.sentence-3)
|
||
|
||
Otherwise,
|
||
constructs an owned object of type T with *std::move(other),
|
||
using the allocator *alloc*[.](#ctor-15.sentence-4)
|
||
|
||
[16](#ctor-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6187)
|
||
|
||
*Postconditions*: other is valueless[.](#ctor-16.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor______)
|
||
|
||
`template<class U = T>
|
||
constexpr explicit indirect(U&& u);
|
||
`
|
||
|
||
[17](#ctor-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6199)
|
||
|
||
*Constraints*:
|
||
|
||
- [(17.1)](#ctor-17.1)
|
||
|
||
is_same_v<remove_cvref_t<U>, indirect> is false,
|
||
|
||
- [(17.2)](#ctor-17.2)
|
||
|
||
is_same_v<remove_cvref_t<U>, in_place_t> is false,
|
||
|
||
- [(17.3)](#ctor-17.3)
|
||
|
||
is_constructible_v<T, U> is true, and
|
||
|
||
- [(17.4)](#ctor-17.4)
|
||
|
||
is_default_constructible_v<Allocator> is true[.](#ctor-17.sentence-1)
|
||
|
||
[18](#ctor-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6212)
|
||
|
||
*Effects*: Constructs an owned object of type T with std::forward<U>(u),
|
||
using the allocator *alloc*[.](#ctor-18.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor_______)
|
||
|
||
`template<class U = T>
|
||
constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u);
|
||
`
|
||
|
||
[19](#ctor-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6225)
|
||
|
||
*Constraints*:
|
||
|
||
- [(19.1)](#ctor-19.1)
|
||
|
||
is_same_v<remove_cvref_t<U>, indirect> is false,
|
||
|
||
- [(19.2)](#ctor-19.2)
|
||
|
||
is_same_v<remove_cvref_t<U>, in_place_t> is false, and
|
||
|
||
- [(19.3)](#ctor-19.3)
|
||
|
||
is_constructible_v<T, U> is true[.](#ctor-19.sentence-1)
|
||
|
||
[20](#ctor-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6236)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized with a[.](#ctor-20.sentence-1)
|
||
|
||
Constructs an owned object of type T withstd::forward<U>(u),
|
||
using the allocator *alloc*[.](#ctor-20.sentence-2)
|
||
|
||
[ð](#lib:indirect,constructor________)
|
||
|
||
`template<class... Us>
|
||
constexpr explicit indirect(in_place_t, Us&&... us);
|
||
`
|
||
|
||
[21](#ctor-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6251)
|
||
|
||
*Constraints*:
|
||
|
||
- [(21.1)](#ctor-21.1)
|
||
|
||
is_constructible_v<T, Us...> is true, and
|
||
|
||
- [(21.2)](#ctor-21.2)
|
||
|
||
is_default_constructible_v<Allocator> is true[.](#ctor-21.sentence-1)
|
||
|
||
[22](#ctor-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6260)
|
||
|
||
*Effects*: Constructs an owned object of type T withstd::forward<Us>(us)...,
|
||
using the allocator *alloc*[.](#ctor-22.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor_________)
|
||
|
||
`template<class... Us>
|
||
constexpr explicit indirect(allocator_arg_t, const Allocator& a,
|
||
in_place_t, Us&& ...us);
|
||
`
|
||
|
||
[23](#ctor-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6275)
|
||
|
||
*Constraints*: is_constructible_v<T, Us...> is true[.](#ctor-23.sentence-1)
|
||
|
||
[24](#ctor-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6279)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized with a[.](#ctor-24.sentence-1)
|
||
|
||
Constructs an owned object of type T withstd::forward<Us>(us)...,
|
||
using the allocator *alloc*[.](#ctor-24.sentence-2)
|
||
|
||
[ð](#lib:indirect,constructor__________)
|
||
|
||
`template<class I, class... Us>
|
||
constexpr explicit indirect(in_place_t, initializer_list<I> ilist, Us&&... us);
|
||
`
|
||
|
||
[25](#ctor-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6294)
|
||
|
||
*Constraints*:
|
||
|
||
- [(25.1)](#ctor-25.1)
|
||
|
||
is_constructible_v<T, initializer_list<I>&, Us...> is true, and
|
||
|
||
- [(25.2)](#ctor-25.2)
|
||
|
||
is_default_constructible_v<Allocator> is true[.](#ctor-25.sentence-1)
|
||
|
||
[26](#ctor-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6303)
|
||
|
||
*Effects*: Constructs an owned object of type T with the argumentsilist, std::forward<Us>(us)...,
|
||
using the allocator *alloc*[.](#ctor-26.sentence-1)
|
||
|
||
[ð](#lib:indirect,constructor___________)
|
||
|
||
`template<class I, class... Us>
|
||
constexpr explicit indirect(allocator_arg_t, const Allocator& a,
|
||
in_place_t, initializer_list<I> ilist, Us&&... us);
|
||
`
|
||
|
||
[27](#ctor-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6318)
|
||
|
||
*Constraints*: is_constructible_v<T, initializer_list<I>&, Us...> is true[.](#ctor-27.sentence-1)
|
||
|
||
[28](#ctor-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6322)
|
||
|
||
*Effects*: *alloc* is direct-non-list-initialized with a[.](#ctor-28.sentence-1)
|
||
|
||
Constructs an owned object of type T with the argumentsilist, std::forward<Us>(us)...,
|
||
using the allocator *alloc*[.](#ctor-28.sentence-2)
|
||
|
||
#### [20.4.1.4](#dtor) Destructor [[indirect.dtor]](indirect.dtor)
|
||
|
||
[ð](#lib:indirect,destructor)
|
||
|
||
`constexpr ~indirect();
|
||
`
|
||
|
||
[1](#dtor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6338)
|
||
|
||
*Mandates*: T is a complete type[.](#dtor-1.sentence-1)
|
||
|
||
[2](#dtor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6342)
|
||
|
||
*Effects*: If *this is not valueless,
|
||
destroys the owned object
|
||
using allocator_traits<Allocator>::destroy and
|
||
then the storage is deallocated[.](#dtor-2.sentence-1)
|
||
|
||
#### [20.4.1.5](#assign) Assignment [[indirect.assign]](indirect.assign)
|
||
|
||
[ð](#lib:operator=,indirect)
|
||
|
||
`constexpr indirect& operator=(const indirect& other);
|
||
`
|
||
|
||
[1](#assign-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6358)
|
||
|
||
*Mandates*:
|
||
|
||
- [(1.1)](#assign-1.1)
|
||
|
||
is_copy_assignable_v<T> is true, and
|
||
|
||
- [(1.2)](#assign-1.2)
|
||
|
||
is_copy_constructible_v<T> is true[.](#assign-1.sentence-1)
|
||
|
||
[2](#assign-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6368)
|
||
|
||
*Effects*: If addressof(other) == this is true, there are no effects[.](#assign-2.sentence-1)
|
||
|
||
Otherwise:
|
||
|
||
- [(2.1)](#assign-2.1)
|
||
|
||
The allocator needs updating ifallocator_traits<Allocator>::propagate_on_container_copy_assignment::value is true[.](#assign-2.1.sentence-1)
|
||
|
||
- [(2.2)](#assign-2.2)
|
||
|
||
If other is valueless,*this becomes valueless and
|
||
the owned object in *this, if any,
|
||
is destroyed using allocator_traits<Allocator>::destroy and
|
||
then the storage is deallocated[.](#assign-2.2.sentence-1)
|
||
|
||
- [(2.3)](#assign-2.3)
|
||
|
||
Otherwise,
|
||
if *alloc* == other.*alloc* is true and*this is not valueless,
|
||
equivalent to **this = *other[.](#assign-2.3.sentence-1)
|
||
|
||
- [(2.4)](#assign-2.4)
|
||
|
||
Otherwise a new owned object is constructed in *this using allocator_traits<Allocator>::con
|
||
struct with
|
||
the owned object from other as the argument,
|
||
using either the allocator in *this or
|
||
the allocator in other if the allocator needs updating[.](#assign-2.4.sentence-1)
|
||
|
||
- [(2.5)](#assign-2.5)
|
||
|
||
The previously owned object in *this, if any,
|
||
is destroyed using allocator_traits<Allocator>::
|
||
destroy and
|
||
then the storage is deallocated[.](#assign-2.5.sentence-1)
|
||
|
||
- [(2.6)](#assign-2.6)
|
||
|
||
If the allocator needs updating,
|
||
the allocator in *this is replaced with
|
||
a copy of the allocator in other[.](#assign-2.6.sentence-1)
|
||
|
||
[3](#assign-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6415)
|
||
|
||
*Returns*: A reference to *this[.](#assign-3.sentence-1)
|
||
|
||
[4](#assign-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6419)
|
||
|
||
*Remarks*: If any exception is thrown,
|
||
the result of the expression this->valueless_after_move() remains unchanged[.](#assign-4.sentence-1)
|
||
|
||
If an exception is thrown during
|
||
the call to T's selected copy constructor, no effect[.](#assign-4.sentence-2)
|
||
|
||
If an exception is thrown during the call to T's copy assignment,
|
||
the state of its owned object
|
||
is as defined by the exception safety guarantee ofT's copy assignment[.](#assign-4.sentence-3)
|
||
|
||
[ð](#lib:operator=,indirect_)
|
||
|
||
`constexpr indirect& operator=(indirect&& other)
|
||
noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
|
||
allocator_traits<Allocator>::is_always_equal::value);
|
||
`
|
||
|
||
[5](#assign-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6440)
|
||
|
||
*Mandates*: is_copy_constructible_t<T> is true[.](#assign-5.sentence-1)
|
||
|
||
[6](#assign-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6444)
|
||
|
||
*Effects*: If addressof(other) == this is true, there are no effects[.](#assign-6.sentence-1)
|
||
|
||
Otherwise:
|
||
|
||
- [(6.1)](#assign-6.1)
|
||
|
||
The allocator needs updating ifallocator_traits<Allocator>::propagate_on_container_move_assignment::value is true[.](#assign-6.1.sentence-1)
|
||
|
||
- [(6.2)](#assign-6.2)
|
||
|
||
If other is valueless,*this becomes valueless and
|
||
the owned object in *this, if any,
|
||
is destroyed using allocator_traits<Allocator>::destroy and
|
||
then the storage is deallocated[.](#assign-6.2.sentence-1)
|
||
|
||
- [(6.3)](#assign-6.3)
|
||
|
||
Otherwise,
|
||
if *alloc* == other.*alloc* is true,
|
||
swaps the owned objects in *this and other;
|
||
the owned object in other, if any,
|
||
is then destroyed using allocator_traits<Allocator>::destroy and
|
||
then the storage is deallocated[.](#assign-6.3.sentence-1)
|
||
|
||
- [(6.4)](#assign-6.4)
|
||
|
||
Otherwise,
|
||
constructs a new owned object with
|
||
the owned object of other as the argument as an rvalue,
|
||
using either
|
||
the allocator in *this or
|
||
the allocator in other if the allocator needs updating[.](#assign-6.4.sentence-1)
|
||
|
||
- [(6.5)](#assign-6.5)
|
||
|
||
The previously owned object in *this, if any,
|
||
is destroyed using allocator_traits<Allocator>::
|
||
destroy and
|
||
then the storage is deallocated[.](#assign-6.5.sentence-1)
|
||
|
||
- [(6.6)](#assign-6.6)
|
||
|
||
If the allocator needs updating,
|
||
the allocator in *this is replaced with
|
||
a copy of the allocator in other[.](#assign-6.6.sentence-1)
|
||
|
||
[7](#assign-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6493)
|
||
|
||
*Postconditions*: other is valueless[.](#assign-7.sentence-1)
|
||
|
||
[8](#assign-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6497)
|
||
|
||
*Returns*: A reference to *this[.](#assign-8.sentence-1)
|
||
|
||
[9](#assign-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6501)
|
||
|
||
*Remarks*: If any exception is thrown,
|
||
there are no effects on *this or other[.](#assign-9.sentence-1)
|
||
|
||
[ð](#lib:operator=,indirect__)
|
||
|
||
`template<class U = T>
|
||
constexpr indirect& operator=(U&& u);
|
||
`
|
||
|
||
[10](#assign-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6514)
|
||
|
||
*Constraints*:
|
||
|
||
- [(10.1)](#assign-10.1)
|
||
|
||
is_same_v<remove_cvref_t<U>, indirect> is false,
|
||
|
||
- [(10.2)](#assign-10.2)
|
||
|
||
is_constructible_v<T, U> is true, and
|
||
|
||
- [(10.3)](#assign-10.3)
|
||
|
||
is_assignable_v<T&, U> is true[.](#assign-10.sentence-1)
|
||
|
||
[11](#assign-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6525)
|
||
|
||
*Effects*: If *this is valueless then
|
||
constructs an owned object of type T with std::forward<U>(u) using the allocator *alloc*[.](#assign-11.sentence-1)
|
||
|
||
Otherwise,
|
||
equivalent to **this = std::forward<U>(u)[.](#assign-11.sentence-2)
|
||
|
||
[12](#assign-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6533)
|
||
|
||
*Returns*: A reference to *this[.](#assign-12.sentence-1)
|
||
|
||
#### [20.4.1.6](#obs) Observers [[indirect.obs]](indirect.obs)
|
||
|
||
[ð](#lib:operator*,indirect)
|
||
|
||
`constexpr const T& operator*() const & noexcept;
|
||
constexpr T& operator*() & noexcept;
|
||
`
|
||
|
||
[1](#obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6547)
|
||
|
||
*Preconditions*: *this is not valueless[.](#obs-1.sentence-1)
|
||
|
||
[2](#obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6551)
|
||
|
||
*Returns*: **p*[.](#obs-2.sentence-1)
|
||
|
||
[ð](#lib:operator*,indirect_)
|
||
|
||
`constexpr const T&& operator*() const && noexcept;
|
||
constexpr T&& operator*() && noexcept;
|
||
`
|
||
|
||
[3](#obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6563)
|
||
|
||
*Preconditions*: *this is not valueless[.](#obs-3.sentence-1)
|
||
|
||
[4](#obs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6567)
|
||
|
||
*Returns*: std::move(**p*)[.](#obs-4.sentence-1)
|
||
|
||
[ð](#lib:operator-%3e,indirect)
|
||
|
||
`constexpr const_pointer operator->() const noexcept;
|
||
constexpr pointer operator->() noexcept;
|
||
`
|
||
|
||
[5](#obs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6579)
|
||
|
||
*Preconditions*: *this is not valueless[.](#obs-5.sentence-1)
|
||
|
||
[6](#obs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6583)
|
||
|
||
*Returns*: *p*[.](#obs-6.sentence-1)
|
||
|
||
[ð](#lib:valueless_after_move,indirect)
|
||
|
||
`constexpr bool valueless_after_move() const noexcept;
|
||
`
|
||
|
||
[7](#obs-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6594)
|
||
|
||
*Returns*: true if *this is valueless, otherwise false[.](#obs-7.sentence-1)
|
||
|
||
[ð](#lib:get_allocator,indirect)
|
||
|
||
`constexpr allocator_type get_allocator() const noexcept;
|
||
`
|
||
|
||
[8](#obs-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6605)
|
||
|
||
*Returns*: *alloc*[.](#obs-8.sentence-1)
|
||
|
||
#### [20.4.1.7](#swap) Swap [[indirect.swap]](indirect.swap)
|
||
|
||
[ð](#lib:swap,indirect)
|
||
|
||
`constexpr void swap(indirect& other)
|
||
noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
|
||
allocator_traits<Allocator>::is_always_equal::value);
|
||
`
|
||
|
||
[1](#swap-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6620)
|
||
|
||
*Preconditions*: Ifallocator_traits<Allocator>::propagate_on_container_swap::value is true, thenAllocator meets the *Cpp17Swappable* requirements[.](#swap-1.sentence-1)
|
||
|
||
Otherwise get_allocator() == other.
|
||
get_allocator() is true[.](#swap-1.sentence-2)
|
||
|
||
[2](#swap-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6628)
|
||
|
||
*Effects*: Swaps the states of *this and other,
|
||
exchanging owned objects or valueless states[.](#swap-2.sentence-1)
|
||
|
||
If allocator_traits<Allocator>::propagate_on_container_swap::value is true,
|
||
then the allocators of *this and other are exchanged by calling swap as described in [[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")[.](#swap-2.sentence-2)
|
||
|
||
Otherwise,
|
||
the allocators are not swapped[.](#swap-2.sentence-3)
|
||
|
||
[*Note [1](#swap-note-1)*:
|
||
|
||
Does not call swap on the owned objects directly[.](#swap-2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#swap-itemdecl:2)
|
||
|
||
`constexpr void swap(indirect& lhs, indirect& rhs) noexcept(noexcept(lhs.swap(rhs)));
|
||
`
|
||
|
||
[3](#swap-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6650)
|
||
|
||
*Effects*: Equivalent to lhs.swap(rhs)[.](#swap-3.sentence-1)
|
||
|
||
#### [20.4.1.8](#relops) Relational operators [[indirect.relops]](indirect.relops)
|
||
|
||
[ð](#relops-itemdecl:1)
|
||
|
||
`template<class U, class AA>
|
||
constexpr bool operator==(const indirect& lhs, const indirect<U, AA>& rhs)
|
||
noexcept(noexcept(*lhs == *rhs));
|
||
`
|
||
|
||
[1](#relops-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6666)
|
||
|
||
*Mandates*: The expression *lhs == *rhs is well-formed and
|
||
its result is convertible to bool[.](#relops-1.sentence-1)
|
||
|
||
[2](#relops-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6671)
|
||
|
||
*Returns*: If lhs is valueless or rhs is valueless,lhs.valueless_after_move() == rhs.valueless_after_move();
|
||
otherwise *lhs == *rhs[.](#relops-2.sentence-1)
|
||
|
||
[ð](#relops-itemdecl:2)
|
||
|
||
`template<class U, class AA>
|
||
constexpr synth-three-way-result<T, U>
|
||
operator<=>(const indirect& lhs, const indirect<U, AA>& rhs);
|
||
`
|
||
|
||
[3](#relops-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6687)
|
||
|
||
*Returns*: If lhs is valueless or rhs is valueless,!lhs.valueless_after_move() <=> !rhs.valueless_after_move();
|
||
otherwise*synth-three-way*(*lhs, *rhs)[.](#relops-3.sentence-1)
|
||
|
||
#### [20.4.1.9](#comp.with.t) Comparison with T [[indirect.comp.with.t]](indirect.comp.with.t)
|
||
|
||
[ð](#comp.with.t-itemdecl:1)
|
||
|
||
`template<class U>
|
||
constexpr bool operator==(const indirect& lhs, const U& rhs) noexcept(noexcept(*lhs == rhs));
|
||
`
|
||
|
||
[1](#comp.with.t-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6705)
|
||
|
||
*Mandates*: The expression *lhs == rhs is well-formed and
|
||
its result is convertible to bool[.](#comp.with.t-1.sentence-1)
|
||
|
||
[2](#comp.with.t-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6710)
|
||
|
||
*Returns*: If lhs is valueless, false;
|
||
otherwise *lhs == rhs[.](#comp.with.t-2.sentence-1)
|
||
|
||
[ð](#comp.with.t-itemdecl:2)
|
||
|
||
`template<class U>
|
||
constexpr synth-three-way-result<T, U>
|
||
operator<=>(const indirect& lhs, const U& rhs);
|
||
`
|
||
|
||
[3](#comp.with.t-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6725)
|
||
|
||
*Returns*: If lhs is valueless, strong_ordering::less;
|
||
otherwise *synth-three-way*(*lhs, rhs)[.](#comp.with.t-3.sentence-1)
|
||
|
||
#### [20.4.1.10](#hash) Hash support [[indirect.hash]](indirect.hash)
|
||
|
||
[ð](#lib:hash,indirect)
|
||
|
||
`template<class T, class Allocator>
|
||
struct hash<indirect<T, Allocator>>;
|
||
`
|
||
|
||
[1](#hash-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6740)
|
||
|
||
The specialization hash<indirect<T, Allocator>> is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash")) if and only if hash<T> is enabled[.](#hash-1.sentence-1)
|
||
|
||
When enabled for an object i of type indirect<T, Allocator>,hash<indirect<T, Allocator>>()(i) evaluates to
|
||
either the same value as hash<T>()(*i),
|
||
if i is not valueless;
|
||
otherwise to animplementation-defined
|
||
value[.](#hash-1.sentence-2)
|
||
|
||
The member functions are not guaranteed to be noexcept[.](#hash-1.sentence-3)
|