Title
uses_allocator_construction_args should have overload for pair-like
Status
c++23
Section
[allocator.uses.construction]
Submitter
Tim Song

Created on 2022-11-08.00:00:00 last changed 5 months ago

Messages

Date: 2023-02-13.10:17:57

Proposed resolution:

This wording is relative to N4917 after the application of LWG 3677.

  1. Edit [pairs.pair] as indicated:

    template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p);
    template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
    template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
    template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p);
    template<pair-like P> constexpr explicit(see below) pair(P&& p);
    

    -14- Let FWD(u) be static_cast<decltype(u)>(u).

    -15- Constraints:

    1. (15.?) — For the last overload, remove_cvref_t<P> is not a specialization of ranges::subrange,

    2. (15.1) — is_constructible_v<T1, decltype(get<0>(FWD(p)))> is true and

    3. (15.2) — is_constructible_v<T2, decltype(get<1>(FWD(p)))> is true.

    -16- Effects: Initializes first with get<0>(FWD(p)) and second with get<1>(FWD(p)).

  2. Edit [memory.syn], header <memory> synopsis, as indicated:

    namespace std {
      […]
      // [allocator.uses.construction], uses-allocator construction
      […]
      template<class T, class Alloc, class U, class V>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc,
                                                        pair<U, V>& pr) noexcept;
    
      template<class T, class Alloc, class U, class V>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc,
                                                        const pair<U, V>& pr) noexcept;
    
      template<class T, class Alloc, class U, class V>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc,
                                                        pair<U, V>&& pr) noexcept;
    
      template<class T, class Alloc, class U, class V>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc,
                                                        const pair<U, V>&& pr) noexcept;
      template<class T, class Alloc, pair-like P>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
        
      template<class T, class Alloc, class U>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
      […]
    }
    
  3. Add the following to [allocator.uses.construction]:

      template<class T, class Alloc, pair-like P>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
    

    -?- Constraints: remove_cv_t<T> is a specialization of pair and remove_cvref_t<P> is not a specialization of ranges::subrange.

    -?- Effects: Equivalent to:

    
    return uses_allocator_construction_args<T>(alloc, piecewise_construct,
                                                forward_as_tuple(get<0>(std::forward<P>(p))),
                                                forward_as_tuple(get<1>(std::forward<P>(p))));
    
  4. Edit [allocator.uses.construction] p17:

      template<class T, class Alloc, class U>
        constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
    

    -16- Let FUN be the function template:

      template<class A, class B>
      void FUN(const pair<A, B>&);
    

    -17- Constraints: remove_cv_t<T> is a specialization of pair, and either:

    1. (17.1) — remove_cvref_t<U> is a specialization of ranges::subrange, or

    2. (17.2) — U does not satisfy pair-like and the expression FUN(u) is not well-formed when considered as an unevaluated operand..

Date: 2023-02-13.00:00:00

[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP. ]

Date: 2023-01-15.00:00:00

[ 2023-01-11; LWG telecon ]

Replace P with U in p17 and set status to Tentatively Ready (poll result: 8/0/0).

Date: 2022-11-12.01:08:30

[ Kona 2022-11-12; Set priority to 2 ]

Date: 2022-11-09.00:00:00

[ 2022-11-09 Tim updates wording following LWG review ]

During review of this issue LWG noticed that neither the constructor nor the new overload should accept subrange.

The remove_cv_t in the new paragraph is added for consistency with LWG 3677.

Date: 2022-11-08.00:00:00

P2165R4 added a pair-like constructor to std::pair but didn't add a corresponding uses_allocator_construction_args overload. It was in P2165R3 but incorrectly removed during the small group review.

Without LWG 3525, not having the overload would have caused emplacing a pair-like into a pmr::vector<pair> to be outright ill-formed.

With that issue's resolution, in cases where the constructor is not explicit we would create a temporary pair and then do uses-allocator construction using its pieces, and it still won't work when the constructor is explicit.

We should just do this properly.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 10:17:57adminsetmessages: + msg13362
2023-02-13 10:17:57adminsetstatus: voting -> wp
2023-02-06 15:33:48adminsetstatus: ready -> voting
2023-01-11 18:22:42adminsetmessages: + msg13198
2023-01-11 18:22:42adminsetstatus: open -> ready
2022-11-12 01:08:30adminsetmessages: + msg13038
2022-11-12 01:08:30adminsetstatus: new -> open
2022-11-10 01:10:30adminsetmessages: + msg12981
2022-11-08 21:40:53adminsetmessages: + msg12966
2022-11-08 00:00:00admincreate