Title
polymorphic_allocator::construct() shouldn't pass resource()
Status
c++20
Section
[mem.poly.allocator.mem]
Submitter
Pablo Halpern

Created on 2017-05-30.00:00:00 last changed 45 months ago

Messages

Date: 2018-03-18.16:03:30

Proposed resolution:

This wording is relative to N4659.

  1. Edit [mem.poly.allocator.mem] as indicated:

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

    -5- Requires: Uses-allocator construction of T with allocator resource()*this (see [allocator.uses.construction]) and constructor arguments std::forward<Args>(args)... is well-formed. [Note: Uses-allocator construction is always well formed for types that do not use allocators. — end note]

    -6- Effects: Construct a T object in the storage whose address is represented by p by uses-allocator construction with allocator resource()*this and constructor arguments std::forward<Args>(args)....

    -7- Throws: Nothing unless the constructor for T throws.

    template <class T1, class T2, class... Args1, class... Args2>
      void construct(pair<T1,T2>* p, piecewise_construct_t,
                     tuple<Args1...> x, tuple<Args2...> y);
    

    -8- [Note: This method and the construct methods that follow are overloads for piecewise construction of pairs ([pairs.pair]). — end note]

    -9- Effects: Let xprime be a tuple constructed from x according to the appropriate rule from the following list. [Note: The following description can be summarized as constructing a pair<T1, T2> object in the storage whose address is represented by p, as if by separate uses-allocator construction with allocator resource()*this ([allocator.uses.construction]) of p->first using the elements of x and p->second using the elements of y. — end note]

    1. (9.1) — If uses_allocator_v<T1,memory_resource*polymorphic_allocator> is false and is_constructible_v<T1,Args1...> is true, then xprime is x.

    2. (9.2) — Otherwise, if uses_allocator_v<T1,memory_resource*polymorphic_allocator> is true and is_constructible_v<T1,allocator_arg_t,memory_resource*polymorphic_allocator,Args1...> is true, then xprime is tuple_cat(make_tuple(allocator_arg, resource()*this), std::move(x)).

    3. (9.3) — Otherwise, if uses_allocator_v<T1,memory_resource*polymorphic_allocator> is true and is_constructible_v<T1,Args1...,memory_resource*polymorphic_allocator> is true, then xprime is tuple_cat(std::move(x), make_tuple(resource()*this)).

    4. (9.4) — Otherwise the program is ill formed.

    Let yprime be a tuple constructed from y according to the appropriate rule from the following list:

    1. (9.5) — If uses_allocator_v<T2,memory_resource*polymorphic_allocator> is false and is_constructible_v<T2,Args2...> is true, then yprime is y.

    2. (9.6) — Otherwise, if uses_allocator_v<T2,memory_resource*polymorphic_allocator> is true and is_constructible_v<T2,allocator_arg_t,memory_resource*polymorphic_allocator,Args2...> is true, then yprime is tuple_cat(make_tuple(allocator_arg, resource()*this), std::move(y)).

    3. (9.7) — Otherwise, if uses_allocator_v<T2,memory_resource*polymorphic_allocator> is true and is_constructible_v<T2,Args2...,memory_resource*polymorphic_allocator> is true, then yprime is tuple_cat(std::move(y), make_tuple(resource()*this)).

    4. (9.8) — Otherwise the program is ill formed.

Date: 2018-03-17.00:00:00

[ 2018-3-17 Adopted in Jacksonville ]

Date: 2017-11-10.03:05:33

[ 2017-11 Albuquerque Wednesday issue processing ]

Move to Ready.

Date: 2017-07-12.01:30:31

[ 2017-07 Toronto Monday issue prioritization ]

Priority 2; Dietmar to check the P/R before Albuquerque.

Date: 2017-06-15.00:00:00

[ 2017-06-13, Daniel and Tim restore and improve the previously proposed wording ]

Date: 2017-06-15.00:00:00

[ 2017-06-13, Tim Song reopens ]

While it is true that memory_resource* is convertible to polymorphic_allocator, uses-allocator construction still requires allocators, and a memory_resource* isn't an allocator.

To take a concrete example from the current WP, a pmr::vector<std::promise<int>>, as specified, will be attempting to uses-allocator construct a promise<int> with a memory_resource*, but std::promise's allocator-taking constructor expects something that satisfies the allocator requirements, rather than a memory_resource*.

Date: 2017-06-15.00:00:00

[ 2017-06-12, Pablo comments ]

The current description is correct and does not depend on changes to uses-allocator construction. It relies on the fact that memory_resource* is convertible to polymorphic_allocator.

Date: 2017-06-12.19:44:38

Section [mem.poly.allocator.mem] defines the effect of polymorphic_allocator<T>::construct as:

Effects: Construct a T object in the storage whose address is represented by p by uses-allocator construction with allocator resource() and constructor arguments std::forward<Args>(args)....

The use of resource() is a hold-over from the LFTS, which contains a modified definition of uses-allocator construction. This revised definition was not carried over into the C++17 WP when allocator_resource and polymorphic_allocator were moved over.

Previous resolution [SUPERSEDED]:

This wording is relative to N4659.

  1. Edit [mem.poly.allocator.mem] as indicated:

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

    -5- Requires: Uses-allocator construction of T with allocator resource()*this (see [allocator.uses.construction]) and constructor arguments std::forward<Args>(args)... is well-formed. [Note: Uses-allocator construction is always well formed for types that do not use allocators. — end note]

    -6- Effects: Construct a T object in the storage whose address is represented by p by uses-allocator construction with allocator resource()*this and constructor arguments std::forward<Args>(args)....

    -7- Throws: Nothing unless the constructor for T throws.

    template <class T1, class T2, class... Args1, class... Args2>
      void construct(pair<T1,T2>* p, piecewise_construct_t,
                     tuple<Args1...> x, tuple<Args2...> y);
    

    -8- [Note: This method and the construct methods that follow are overloads for piecewise construction of pairs ([pairs.pair]). — end note]

    -9- Effects: Let xprime be a tuple constructed from x according to the appropriate rule from the following list. [Note: The following description can be summarized as constructing a pair<T1, T2> object in the storage whose address is represented by p, as if by separate uses-allocator construction with allocator resource()*this ([allocator.uses.construction]) of p->first using the elements of x and p->second using the elements of y. — end note]

    […]

History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2018-03-18 16:03:30adminsetmessages: + msg9730
2018-03-18 16:03:30adminsetstatus: voting -> wp
2018-02-12 01:13:49adminsetstatus: ready -> voting
2017-11-10 03:05:33adminsetmessages: + msg9540
2017-11-10 03:05:33adminsetstatus: new -> ready
2017-07-12 01:30:31adminsetmessages: + msg9336
2017-06-13 19:51:37adminsetmessages: + msg9256
2017-06-13 19:51:37adminsetmessages: + msg9255
2017-06-13 19:51:37adminsetstatus: nad -> new
2017-06-12 19:44:38adminsetmessages: + msg9249
2017-06-12 19:44:38adminsetstatus: new -> nad
2017-06-10 20:40:14adminsetmessages: + msg9238
2017-05-30 00:00:00admincreate