20 General utilities library [utilities]

20.7 Memory [memory]

20.7.9 The default allocator [default.allocator]

namespace std {
  template <class T> class allocator;

  // specialize for void:
  template <> class allocator<void> {
  public:
    typedef void*   pointer;
    typedef const void* const_pointer;
    // reference-to-void members are impossible.
    typedef void  value_type;
    template <class U> struct rebind { typedef allocator<U> other; };
  };

  template <class T> class allocator {
   public:
    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;
    typedef T*        pointer;
    typedef const T*  const_pointer;
    typedef T&        reference;
    typedef const T&  const_reference;
    typedef T         value_type;
    template <class U> struct rebind { typedef allocator<U> other; };
    typedef true_type propagate_on_container_move_assignment;
    
    allocator() noexcept;
    allocator(const allocator&) noexcept;
    template <class U> allocator(const allocator<U>&) noexcept;
   ~allocator();

    pointer address(reference x) const noexcept;
    const_pointer address(const_reference x) const noexcept;

    pointer allocate(
      size_type, allocator<void>::const_pointer hint = 0);
    void deallocate(pointer p, size_type n);
    size_type max_size() const noexcept;

    template<class U, class... Args>
      void construct(U* p, Args&&... args);
    template <class U>
      void destroy(U* p);
  };
}

20.7.9.1 allocator members [allocator.members]

Except for the destructor, member functions of the default allocator shall not introduce data races ([intro.multithread]) as a result of concurrent calls to those member functions from different threads. Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.

pointer address(reference x) const noexcept;

Returns: The actual address of the object referenced by x, even in the presence of an overloaded operator&.

const_pointer address(const_reference x) const noexcept;

Returns: The actual address of the object referenced by x, even in the presence of an overloaded operator&.

pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);

Note: In a container member function, the address of an adjacent element is often a good choice to pass for the hint argument.  — end note ]

Returns: A pointer to the initial element of an array of storage of size n * sizeof(T), aligned appropriately for objects of type T. It is implementation-defined whether over-aligned types are supported ([basic.align]).

Remark: the storage is obtained by calling ::operator new(std::size_t) ([new.delete]), but it is unspecified when or how often this function is called. The use of hint is unspecified, but intended as an aid to locality if an implementation so desires.

Throws: bad_alloc if the storage cannot be obtained.

void deallocate(pointer p, size_type n);

Requires: p shall be a pointer value obtained from allocate(). n shall equal the value passed as the first argument to the invocation of allocate which returned p.

Effects: Deallocates the storage referenced by p .

Remarks: Uses ::operator delete(void*, std::size_t) ([new.delete]), but it is unspecified when this function is called.

size_type max_size() const noexcept;

Returns: The largest value N for which the call allocate(N,0) might succeed.

template <class U, class... Args> void construct(U* p, Args&&... args);

Effects: ::new((void *)p) U(std::forward<Args>(args)...)

template <class U> void destroy(U* p);

Effects: p->~U()

20.7.9.2 allocator globals [allocator.globals]

template <class T1, class T2> bool operator==(const allocator<T1>&, const allocator<T2>&) noexcept;

Returns: true.

template <class T1, class T2> bool operator!=(const allocator<T1>&, const allocator<T2>&) noexcept;

Returns: false.