[obj.lifetime]

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

## 20.2 Memory [[memory]](memory#obj.lifetime)

### 20.2.6 Explicit lifetime management [obj.lifetime]

[ð](#lib:start_lifetime_as)

`template<class T>
  T* start_lifetime_as(void* p) noexcept;
template<class T>
  const T* start_lifetime_as(const void* p) noexcept;
template<class T>
  volatile T* start_lifetime_as(volatile void* p) noexcept;
template<class T>
  const volatile T* start_lifetime_as(const volatile void* p) noexcept;
`

[1](#1)

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

*Mandates*: T is an implicit-lifetime type ([[basic.types.general]](basic.types.general#term.implicit.lifetime.type "6.9.1 General"))
and not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#1.sentence-1)

[2](#2)

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

*Preconditions*: [p, (char*)p + sizeof(T)) denotes a region of allocated storage
that is
a subset of the region of storage
reachable through ([[basic.compound]](basic.compound "6.9.4 Compound types")) p and
suitably aligned for the type T[.](#2.sentence-1)

[3](#3)

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

*Effects*: Implicitly creates objects ([[intro.object]](intro.object "6.8.2 Object model")) within the denoted region
consisting of an object *a* of type T whose address is p, and
objects nested within *a*,
as follows:
The object representation of *a* is the contents of the storage prior to the call to start_lifetime_as[.](#3.sentence-1)

The value of each created object *o* of trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General")) U is determined in the same manner as for a call
to bit_cast<U>(E) ([[bit.cast]](bit.cast "22.11.3 Function template bit_­cast")),
where E is an lvalue of type U denoting *o*,
except that the storage is not accessed[.](#3.sentence-2)

The value of any other created object is unspecified[.](#3.sentence-3)

[*Note [1](#note-1)*:

The unspecified value can be indeterminate[.](#3.sentence-4)

â *end note*]

[4](#4)

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

*Returns*: A pointer to the *a* defined in the *Effects* paragraph[.](#4.sentence-1)

[ð](#lib:start_lifetime_as_array)

`template<class T>
  T* start_lifetime_as_array(void* p, size_t n) noexcept;
template<class T>
  const T* start_lifetime_as_array(const void* p, size_t n) noexcept;
template<class T>
  volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept;
template<class T>
  const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept;
`

[5](#5)

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

*Mandates*: T is a complete type[.](#5.sentence-1)

[6](#6)

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

*Preconditions*: p is suitably aligned for an array of T or is null[.](#6.sentence-1)

n <= size_t(-1) / sizeof(T) is true[.](#6.sentence-2)

If n > 0 is true,
[(char*)p, (char*)p + (n * sizeof(T))) denotes
a region of allocated storage that is
a subset of the region of storage
reachable through ([[basic.compound]](basic.compound "6.9.4 Compound types")) p[.](#6.sentence-3)

[7](#7)

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

*Effects*: If n > 0 is true,
equivalent tostart_lifetime_as<U>(p) where U is the type âarray of n Tâ[.](#7.sentence-1)

Otherwise, there are no effects[.](#7.sentence-2)

[8](#8)

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

*Returns*: A pointer to the first element of the created array,
if any;
otherwise,
a pointer that compares equal to p ([[expr.eq]](expr.eq "7.6.10 Equality operators"))[.](#8.sentence-1)

[ð](#lib:trivially_relocate)

`template<class T>
  T* trivially_relocate(T* first, T* last, T* result);
`

[9](#9)

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

*Mandates*: is_trivially_relocatable_v<T> && !is_const_v<T> is true[.](#9.sentence-1)

T is not an array of unknown bound[.](#9.sentence-2)

[10](#10)

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

*Preconditions*: 

- [(10.1)](#10.1)

  [first, last) is a valid range[.](#10.1.sentence-1)

- [(10.2)](#10.2)

  [result, result + (last - first)) denotes a region of storage that
 is a subset of the region reachable through result ([[basic.compound]](basic.compound "6.9.4 Compound types"))
 and suitably aligned for the type T[.](#10.2.sentence-1)

- [(10.3)](#10.3)

  No element in the range [first, last) is a potentially-overlapping subobject[.](#10.3.sentence-1)

[11](#11)

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

*Postconditions*: No effect if result == first is true[.](#11.sentence-1)

Otherwise, the range denoted by [result, result + (last - first))
contains objects (including subobjects) whose lifetime has begun and whose
object representations are the original object representations of the
corresponding objects in the source range [first, last) except
for any parts of the object representations used by the implementation to
represent type information ([[intro.object]](intro.object "6.8.2 Object model"))[.](#11.sentence-2)

If any of the objects has
union type, its active member is the same as that of the corresponding object
in the source range[.](#11.sentence-3)

If any of the aforementioned objects has a non-static
data member of reference type, that reference refers to the same entity as
does the corresponding reference in the source range[.](#11.sentence-4)

The lifetimes of the
original objects in the source range have ended[.](#11.sentence-5)

[12](#12)

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

*Returns*: result + (last - first)[.](#12.sentence-1)

[13](#13)

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

*Throws*: Nothing[.](#13.sentence-1)

[14](#14)

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

*Complexity*: Linear in the length of the source range[.](#14.sentence-1)

[15](#15)

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

*Remarks*: The destination region of storage is considered reused ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#15.sentence-1)

No constructors or destructors are invoked[.](#15.sentence-2)

[*Note [2](#note-2)*:

Overlapping ranges are supported[.](#15.sentence-3)

â *end note*]

[ð](#lib:relocate)

`template<class T>
  constexpr T* relocate(T* first, T* last, T* result);
`

[16](#16)

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

*Mandates*: is_nothrow_relocatable_v<T> && !is_const_v<T> is true[.](#16.sentence-1)

T is not an array of unknown bound[.](#16.sentence-2)

[17](#17)

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

*Preconditions*: 

- [(17.1)](#17.1)

  [first, last) is a valid range[.](#17.1.sentence-1)

- [(17.2)](#17.2)

  [result, result + (last - first)) denotes a region of storage that is
 a subset of the region reachable through result ([[basic.compound]](basic.compound "6.9.4 Compound types"))
 and suitably aligned for the type T[.](#17.2.sentence-1)

- [(17.3)](#17.3)

  No element in the range [first, last) is a potentially-overlapping
 subobject[.](#17.3.sentence-1)

[18](#18)

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

*Effects*: 

- [(18.1)](#18.1)

If result == first is true, no effect;

- [(18.2)](#18.2)

otherwise, if not called during constant evaluation and is_trivially_relocatable_v<T> is true, then has
 effects equivalent to: trivially_relocate(first, last, result);

- [(18.3)](#18.3)

otherwise, for each integer i in [0, last - first),
  * [(18.3.1)](#18.3.1)

if T is an array type, equivalent to: relocate(begin(first[i]), end(first[i]), *start_lifetime_as<T>(result + i));

  * [(18.3.2)](#18.3.2)

otherwise, equivalent to: construct_at(result + i, std​::​move(first[i])); destroy_at(first + i);

[19](#19)

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

*Returns*: result + (last - first)[.](#19.sentence-1)

[20](#20)

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

*Throws*: Nothing[.](#20.sentence-1)

[*Note [3](#note-3)*:

Overlapping ranges are supported[.](#20.sentence-2)

â *end note*]
