20 Memory management library [mem]

20.4 Types for composite class design [mem.composite.types]

20.4.1 Class template indirect [indirect]

20.4.1.5 Assignment [indirect.asgn]

constexpr indirect& operator=(const indirect& other);
Mandates:
  • is_copy_assignable_v<T> is true, and
  • is_copy_constructible_v<T> is true.
Effects: If addressof(other) == this is true, there are no effects.
Otherwise:
  • The allocator needs updating if allocator_traits<Allocator>​::​propagate_on_container_copy_assignment​::​value is true.
  • 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.
  • Otherwise, if alloc == other.alloc is true and *this is not valueless, equivalent to **this = *other.
  • 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.
  • The previously owned object in *this, if any, is destroyed using allocator_traits<Allocator>​::​
    destroy
    and then the storage is deallocated.
  • If the allocator needs updating, the allocator in *this is replaced with a copy of the allocator in other.
Returns: A reference to *this.
Remarks: If any exception is thrown, the result of the expression this->valueless_after_move() remains unchanged.
If an exception is thrown during the call to T's selected copy constructor, no effect.
If an exception is thrown during the call to T's copy assignment, the state of its contained value is as defined by the exception safety guarantee of T's copy assignment.
constexpr indirect& operator=(indirect&& other) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
Mandates: is_copy_constructible_t<T> is true.
Effects: If addressof(other) == this is true, there are no effects.
Otherwise:
  • The allocator needs updating if allocator_traits<Allocator>​::​propagate_on_container_move_assignment​::​value is true.
  • 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.
  • 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.
  • 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.
  • The previously owned object in *this, if any, is destroyed using allocator_traits<Allocator>​::​
    destroy
    and then the storage is deallocated.
  • If the allocator needs updating, the allocator in *this is replaced with a copy of the allocator in other.
Postconditions: other is valueless.
Returns: A reference to *this.
Remarks: If any exception is thrown, there are no effects on *this or other.
template<class U = T> constexpr indirect& operator=(U&& u);
Constraints:
  • is_same_v<remove_cvref_t<U>, indirect> is false,
  • is_constructible_v<T, U> is true, and
  • is_assignable_v<T&, U> is true.
Effects: If *this is valueless then constructs an owned object of type T with std​::​forward<U>(u) using the allocator alloc.
Otherwise, equivalent to **this = std​::​forward<U>(u).
Returns: A reference to *this.