[indirect.ctor]

# 20 Memory management library [[mem]](./#mem)

## 20.4 Types for composite class design [[mem.composite.types]](mem.composite.types#indirect.ctor)

### 20.4.1 Class template indirect [[indirect]](indirect#ctor)

#### 20.4.1.3 Constructors [indirect.ctor]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6059)

The following element applies to all functions in [indirect.ctor]:

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6063)

*Throws*: Nothing unless allocator_traits<Allocator>​::​allocate orallocator_traits<Allocator>​::​construct throws[.](#2.sentence-1)

[ð](#lib:indirect,constructor)

`constexpr explicit indirect();
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6075)

*Constraints*: is_default_constructible_v<Allocator> is true[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6079)

*Mandates*: is_default_constructible_v<T> is true[.](#4.sentence-1)

[5](#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*[.](#5.sentence-1)

[ð](#lib:indirect,constructor_)

`constexpr explicit indirect(allocator_arg_t, const Allocator& a);
`

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6095)

*Mandates*: is_default_constructible_v<T> is true[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6099)

*Effects*: *alloc* is direct-non-list-initialized with a[.](#7.sentence-1)

Constructs an owned object of type T with an empty argument list,
using the allocator *alloc*[.](#7.sentence-2)

[ð](#lib:indirect,constructor__)

`constexpr indirect(const indirect& other);
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6112)

*Mandates*: is_copy_constructible_v<T> is true[.](#8.sentence-1)

[9](#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*)[.](#9.sentence-1)

If other is valueless, *this is valueless[.](#9.sentence-2)

Otherwise,
constructs an owned object of type T with *other,
using the allocator *alloc*[.](#9.sentence-3)

[ð](#lib:indirect,constructor___)

`constexpr indirect(allocator_arg_t, const Allocator& a, const indirect& other);
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6132)

*Mandates*: is_copy_constructible_v<T> is true[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6136)

*Effects*: *alloc* is direct-non-list-initialized with a[.](#11.sentence-1)

If other is valueless, *this is valueless[.](#11.sentence-2)

Otherwise,
constructs an owned object of type T with *other,
using the allocator *alloc*[.](#11.sentence-3)

[ð](#lib:indirect,constructor____)

`constexpr indirect(indirect&& other) noexcept;
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6151)

*Effects*: *alloc* is direct-non-list-initialized fromstd​::​move(other.*alloc*)[.](#12.sentence-1)

If other is valueless, *this is valueless[.](#12.sentence-2)

Otherwise *this takes ownership of the owned object of other[.](#12.sentence-3)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6158)

*Postconditions*: other is valueless[.](#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](#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[.](#14.sentence-1)

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6175)

*Effects*: *alloc* is direct-non-list-initialized with a[.](#15.sentence-1)

If other is valueless, *this is valueless[.](#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[.](#15.sentence-3)

Otherwise,
constructs an owned object of type T with *std​::​move(other),
using the allocator *alloc*[.](#15.sentence-4)

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6187)

*Postconditions*: other is valueless[.](#16.sentence-1)

[ð](#lib:indirect,constructor______)

`template<class U = T>
  constexpr explicit indirect(U&& u);
`

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6199)

*Constraints*: 

- [(17.1)](#17.1)

is_same_v<remove_cvref_t<U>, indirect> is false,

- [(17.2)](#17.2)

is_same_v<remove_cvref_t<U>, in_place_t> is false,

- [(17.3)](#17.3)

is_constructible_v<T, U> is true, and

- [(17.4)](#17.4)

is_default_constructible_v<Allocator> is true[.](#17.sentence-1)

[18](#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*[.](#18.sentence-1)

[ð](#lib:indirect,constructor_______)

`template<class U = T>
  constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u);
`

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6225)

*Constraints*: 

- [(19.1)](#19.1)

is_same_v<remove_cvref_t<U>, indirect> is false,

- [(19.2)](#19.2)

is_same_v<remove_cvref_t<U>, in_place_t> is false, and

- [(19.3)](#19.3)

is_constructible_v<T, U> is true[.](#19.sentence-1)

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6236)

*Effects*: *alloc* is direct-non-list-initialized with a[.](#20.sentence-1)

Constructs an owned object of type T withstd​::​forward<U>(u),
using the allocator *alloc*[.](#20.sentence-2)

[ð](#lib:indirect,constructor________)

`template<class... Us>
  constexpr explicit indirect(in_place_t, Us&&... us);
`

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6251)

*Constraints*: 

- [(21.1)](#21.1)

is_constructible_v<T, Us...> is true, and

- [(21.2)](#21.2)

is_default_constructible_v<Allocator> is true[.](#21.sentence-1)

[22](#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*[.](#22.sentence-1)

[ð](#lib:indirect,constructor_________)

`template<class... Us>
  constexpr explicit indirect(allocator_arg_t, const Allocator& a,
                              in_place_t, Us&& ...us);
`

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6275)

*Constraints*: is_constructible_v<T, Us...> is true[.](#23.sentence-1)

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6279)

*Effects*: *alloc* is direct-non-list-initialized with a[.](#24.sentence-1)

Constructs an owned object of type T withstd​::​forward<Us>(us)...,
using the allocator *alloc*[.](#24.sentence-2)

[ð](#lib:indirect,constructor__________)

`template<class I, class... Us>
  constexpr explicit indirect(in_place_t, initializer_list<I> ilist, Us&&... us);
`

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6294)

*Constraints*: 

- [(25.1)](#25.1)

is_constructible_v<T, initializer_list<I>&, Us...> is true, and

- [(25.2)](#25.2)

is_default_constructible_v<Allocator> is true[.](#25.sentence-1)

[26](#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*[.](#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](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6318)

*Constraints*: is_constructible_v<T, initializer_list<I>&, Us...> is true[.](#27.sentence-1)

[28](#28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L6322)

*Effects*: *alloc* is direct-non-list-initialized with a[.](#28.sentence-1)

Constructs an owned object of type T with the argumentsilist, std​::​forward<Us>(us)...,
using the allocator *alloc*[.](#28.sentence-2)
