C++ named requirements: Allocator
Encapsulates strategies for access/addressing, allocation/deallocation and construction/destruction of objects.
Every standard library component that may need to allocate or release storage, from std::string, std::vector, and every container except std::array, to std::shared_ptr and std::function, does so through an Allocator: an object of a class type that satisfies the following requirements.
Some requirements are optional: the template std::allocator_traits supplies the default implementations for all optional requirements, and all standard library containers and other allocator-aware classes access the allocator through std::allocator_traits, not directly.
Requirements
Given.
-  T, a cv-unqualified object type
-  A, an Allocator type for typeT
-  a, an object of typeA
-  B, the corresponding Allocator type for some cv-unqualified object typeU(as obtained by rebindingA)
-  b, an object of typeB
-  ptr, a value of typeallocator_traits<A>::pointer, obtained by callingallocator_traits<A>::allocate()
-  cptr, a value of typeallocator_traits<A>::const_pointer, obtained by conversion fromptr
-  vptr, a value of typeallocator_traits<A>::void_pointer, obtained by conversion fromptr
-  cvptr, a value of typeallocator_traits<A>::const_void_pointer, obtained by conversion fromcptror fromvptr
-  xptr, a dereferencable pointer to some cv-unqualified object typeX,
-  r, an lvalue of typeTobtained by the expression*ptr
-  n, a value of typeallocator_traits<A>::size_type
| Expression | Requirements | Return type | 
|---|---|---|
| A::pointer(optional) | Satisfies NullablePointer, LegacyRandomAccessIterator, and LegacyContiguousIterator (see fancy pointers below) | |
| A::const_pointer(optional) | A::pointeris convertible toA::const_pointer. Satisfies NullablePointer, LegacyRandomAccessIterator, and LegacyContiguousIterator | |
| A::void_pointer(optional) | A::pointeris convertible toA::void_pointer
 | |
| A::const_void_pointer(optional) | A::pointer,A::const_pointer, andA::void_pointerare convertible toA::const_void_pointer
 | |
| A::value_type | the type T | |
| A::size_type(optional) | A::size_typecan represent the size of the largest objectAcan allocate | unsigned integer type | 
| A::difference_type(optional) | A::difference_typecan represent the difference of any two pointers to the objects allocated byA | signed integer type | 
| A::template rebind<U>::other(optional)[1] | for any U,B::template rebind<T>::otherisA | the type B | 
| *ptr | T& | |
| *cptr | *cptrand*ptridentify the same object | const T& | 
| ptr->m | same as (*ptr).m, if(*ptr).mis well-defined | the type of T::m | 
| cptr->m | same as (*cptr).m, if(*cptr).mis well-defined | the type of T::m | 
| static_cast<A::pointer>(vptr) | static_cast<A::pointer>(vptr) == ptr | A::pointer | 
| static_cast<A::const_pointer>(cvptr) | static_cast<A::const_pointer>(cvptr) == cptr | A::const_pointer | 
| std::pointer_traits<A::pointer>::pointer_to(r) | A::pointer | |
| a.allocate(n) | allocates storage suitable for nobjects of typeT, but does not construct them. May throw exceptions. | A::pointer | 
| a.allocate(n, cvptr)(optional) | same as a.allocate(n), but may usecvptr(a pointer obtained froma.allocate()ornullptr_t) in unspecified manner to aid locality | A::pointer | 
| a.deallocate(ptr, n) | deallocates storage pointed to ptr, which must be a value returned by a previous call toallocatethat has not been invalidated by an intervening call todeallocate.nmust match the value previously passed toallocate. Does not throw exceptions. | (not used) | 
| a.max_size()(optional) | the largest value that can be passed to A::allocate() | A::size_type | 
| a1 == a2 | returns trueonly if the storage allocated by the allocatora1can be deallocated througha2. Establishes reflexive, symmetric, and transitive relationship. Does not throw exceptions. | bool | 
| a1 != a2 | same as !(a1==a2) | bool | 
| A a1(a)
 | Copy-constructs a1such thata1 == a. Does not throw exceptions. (Note: every Allocator also satisfies CopyConstructible) | |
| A a(b) | Constructs asuch thatB(a)==bandA(b)==a. Does not throw exceptions. (Note: this implies that all allocators related by rebind maintain each other's resources, such as memory pools) | |
| A a1(std::move(a))
 | Constructs a1such that it equals the prior value ofa. Does not throw exceptions. The value ofais unchanged anda1 == a. (since C++20) | |
| A a(std::move(b)) | Constructs asuch that it equals the prior value ofA(b). Does not throw exceptions. | |
| a.construct(xptr, args)(optional) | Constructs an object of type Xin previously-allocated storage at the address pointed to byxptr, using args as the constructor arguments | |
| a.destroy(xptr)(optional) | Destructs an object of type Xpointed to byxptr, but does not deallocate any storage. | |
| a.select_on_container_copy_construction()(optional) | Provides an instance of Ato be used by the container that is copy-constructed from the one that usesacurrently. Usually returns either a copy ofaor a default-constructedA(). | A | 
| A::propagate_on_container_copy_assignment(optional) | trueif the allocator of typeAneeds to be copied when the container that uses it is copy-assigned. Note that if the allocators of the source and the target containers do not compare equal, copy assignment has to deallocate the target's memory using the old allocator and then allocate it using the new allocator before copying the elements (and the allocator). | std::true_typeorstd::false_typeor derived from such | 
| A::propagate_on_container_move_assignment(optional) | trueif the allocator of typeAneeds to be moved when the container that uses it is move-assigned. If this member isfalseand the allocators of the source and the target containers do not compare equal, move assignment cannot take ownership of the source memory and must move-assign or move-construct the elements individually, resizing its own memory as needed. | std::true_typeorstd::false_typeor derived from such | 
| A::propagate_on_container_swap(optional) | trueif the allocators of typeAneed to be swapped when two containers that use them are swapped. If this member isfalseand the allocators of the two containers do not compare equal, the behavior of container swap is undefined. | std::true_typeorstd::false_typeor derived from such | 
| A::is_always_equal(since C++17) (optional) | trueif any two allocators of typeAalways compare equal. If not provided,std::allocator_traitsdefaults this to equalstd::is_empty<A>::type | std::true_typeorstd::false_typeor derived from such | 
Notes:
-  rebind is only optional (provided by std::allocator_traits) if this allocator is a template of the formSomeAllocator<T, Args>, whereArgsis zero or more additional template type parameters.
| Additionally, in order for the type  
 | (since C++17) | 
| Given. 
 Then, x1 and x2 are equivalently-valued pointer values, if and only if both  Given. 
 Then for the expression  Given. 
 Then, for the expressions  The above requirements make it possible to compare Container's iterators and const_iterators. | (since C++14) | 
| Allocator completeness requirementsAn allocator type  
 | (since C++17) | 
Fancy pointers
When the member type pointer is not a raw pointer type, it is commonly referred to as a "fancy pointer". Such pointers were introduced to support segmented memory architectures and are used today to access objects allocated in address spaces that differ from the homogeneous virtual address space that is accessed by raw pointers. An example of a fancy pointer is the mapping address-independent pointer boost::interprocess::offset_ptr, which makes it possible to allocate node-based data structures such as std::set in shared memory and memory mapped files mapped in different addresses in every process. Fancy pointers can be used independently of the allocator that provided them, through the class template std::pointer_traits.
Standard library
The following standard library components satisfy the Allocator requirements:
| the default allocator (class template) | |
| (C++11) | implements multi-level allocator for multi-level containers (class template) | 
| (C++17) | an allocator that supports run-time polymorphism based on the std::memory_resourceit is constructed with(class template) | 
Examples
A C++11 allocator, except for [[nodiscard]] added to match C++20 style.
#include <cstdlib>
#include <new>
template <class T>
struct Mallocator {
  typedef T value_type;
  Mallocator() = default;
  template <class U> constexpr Mallocator(const Mallocator<U>&) noexcept {}
  [[nodiscard]] T* allocate(std::size_t n) {
    if(n > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
    if(auto p = static_cast<T*>(std::malloc(n*sizeof(T)))) return p;
    throw std::bad_alloc();
  }
  void deallocate(T* p, std::size_t) noexcept { std::free(p); }
};
template <class T, class U>
bool operator==(const Mallocator<T>&, const Mallocator<U>&) { return true; }
template <class T, class U>
bool operator!=(const Mallocator<T>&, const Mallocator<U>&) { return false; }
    © cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
    http://en.cppreference.com/w/cpp/named_req/Allocator