This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

3185. Uses-allocator construction functions missing constexpr and noexcept

Section: 20.10.8.2 [allocator.uses.construction] Status: WP Submitter: Pablo Halpern Opened: 2019-01-29 Last modified: 2019-07-27

Priority: 0

View other active issues in [allocator.uses.construction].

View all other issues in [allocator.uses.construction].

View all issues with WP status.

Discussion:

The uses-allocator construction functions introduced into WP when P0591r4 was accepted (Nov 2018, San Diego) should all be constexpr. All but two should also be noexcept. Getting this right is an important part of correctly adding constexpr memory allocation into the WP.

The minimal change is to add the constexpr to all of the new functions except uninitialized_construct_using_allocator and noexcept to all of the overloads of uses_allocator_construction_args. Optionally, we could consider adding conditional noexcept to the remaining two functions. If p0784 is accepted, then also add constexpr to uninitialized_construct_using_allocator.

[2019-02-12 Priority to 0 and Status to Tentatively Ready after six positive votes on the reflector.]

Proposed resolution:

This wording is relative to N4800.

  1. Change header <memory> synopsis, 20.10.2 [memory.syn], as indicated:

    […]
    // 20.10.8.2 [allocator.uses.construction], uses-allocator construction
    template <class T, class Alloc, class... Args>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept -> see below;
    template <class T, class Alloc, class Tuple1, class Tuple2>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
                                          Tuple1&& x, Tuple2&& y) noexcept -> see below;
    template <class T, class Alloc>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
    template <class T, class Alloc, class U, class V>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) noexcept -> see below;
    template <class T, class Alloc, class U, class V>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair<U,V>& pr) noexcept -> see below;
    template <class T, class Alloc, class U, class V>
    constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair<U,V>&& pr) noexcept -> see below;
    template <class T, class Alloc, class... Args>
    constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
    template <class T, class Alloc, class... Args>
    T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
    […]
    
  2. Change 20.10.8.2 [allocator.uses.construction] as indicated:

    template <class T, class Alloc, class... Args>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class Tuple1, class Tuple2>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
                                            Tuple1&& x, Tuple2&& y) noexcept -> see below;
    

    […]

    template <class T, class Alloc>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class U, class V>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class U, class V>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair<U,V>& pr) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class U, class V>
      constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair<U,V>&& pr) noexcept -> see below;
    

    […]

    template <class T, class Alloc, class... Args>
      constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
    

    […]

    template <class T, class Alloc, class... Args>
      T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
    

    […]