Issue 2969: polymorphic_allocator::construct() shouldn't pass resource() (original) (raw)
This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
2969. polymorphic_allocator::construct() shouldn't pass resource()
Section: 20.5.3.3 [mem.poly.allocator.mem] Status: C++20 Submitter: Pablo Halpern Opened: 2017-05-30 Last modified: 2021-02-25
Priority: 2
View all other issues in [mem.poly.allocator.mem].
View all issues with C++20 status.
Discussion:
Section 20.5.3.3 [mem.poly.allocator.mem] defines the effect of polymorphic_allocator<T>::construct as:
Effects: Construct a
Tobject in the storage whose address is represented bypby uses-allocator construction with allocatorresource()and constructor argumentsstd::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.
- Edit 20.5.3.3 [mem.poly.allocator.mem] as indicated:
template <class T, class... Args>
void construct(T* p, Args&&... args);-5- Requires: Uses-allocator construction of
Twith allocator~~resource()~~*this(see 20.2.8.2 [allocator.uses.construction]) and constructor argumentsstd::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
Tobject in the storage whose address is represented bypby uses-allocator construction with allocator~~resource()~~*thisand constructor argumentsstd::forward<Args>(args)....-7- Throws: Nothing unless the constructor for
Tthrows.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
constructmethods that follow are overloads for piecewise construction of pairs (22.3.2 [pairs.pair]). — _end note_]-9- Effects: Let
xprimebe atupleconstructed fromxaccording to the appropriate rule from the following list. [Note: The following description can be summarized as constructing apair<T1, T2>object in the storage whose address is represented byp, as if by separate uses-allocator construction with allocator~~resource()~~*this(20.2.8.2 [allocator.uses.construction]) ofp->firstusing the elements ofxandp->secondusing the elements ofy. — _end note_][…]
[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.
[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 amemory_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*, butstd::promise's allocator-taking constructor expects something that satisfies the allocator requirements, rather than a memory_resource*.
[2017-06-13, Daniel and Tim restore and improve the previously proposed wording]
[2017-07 Toronto Monday issue prioritization]
Priority 2; Dietmar to check the P/R before Albuquerque.
[2017-11 Albuquerque Wednesday issue processing]
Move to Ready.
[2018-3-17 Adopted in Jacksonville]
Proposed resolution:
This wording is relative to N4659.
- Edit 20.5.3.3 [mem.poly.allocator.mem] as indicated:
template <class T, class... Args>
void construct(T* p, Args&&... args);-5- Requires: Uses-allocator construction of
Twith allocator~~resource()~~*this(see 20.2.8.2 [allocator.uses.construction]) and constructor argumentsstd::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
Tobject in the storage whose address is represented bypby uses-allocator construction with allocator~~resource()~~*thisand constructor argumentsstd::forward<Args>(args)....-7- Throws: Nothing unless the constructor for
Tthrows.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
constructmethods that follow are overloads for piecewise construction of pairs (22.3.2 [pairs.pair]). — _end note_]-9- Effects: Let
xprimebe atupleconstructed fromxaccording to the appropriate rule from the following list. [Note: The following description can be summarized as constructing apair<T1, T2>object in the storage whose address is represented byp, as if by separate uses-allocator construction with allocator~~resource()~~*this(20.2.8.2 [allocator.uses.construction]) ofp->firstusing the elements ofxandp->secondusing the elements ofy. — _end note_]
- (9.1) — If
uses_allocator_v<T1,~~memory_resource*~~polymorphic_allocator>isfalseandis_constructible_v<T1,Args1...>istrue, thenxprimeisx.- (9.2) — Otherwise, if
uses_allocator_v<T1,~~memory_resource*~~polymorphic_allocator>istrueandis_constructible_v<T1,allocator_arg_t,~~memory_resource*~~polymorphic_allocator,Args1...>istrue, thenxprimeistuple_cat(make_tuple(allocator_arg, ~~resource()~~*this), std::move(x)).- (9.3) — Otherwise, if
uses_allocator_v<T1,~~memory_resource*~~polymorphic_allocator>istrueandis_constructible_v<T1,Args1...,~~memory_resource*~~polymorphic_allocator>istrue, thenxprimeistuple_cat(std::move(x), make_tuple(~~resource()~~*this)).- (9.4) — Otherwise the program is ill formed.
Let
yprimebe a tuple constructed fromyaccording to the appropriate rule from the following list:
- (9.5) — If
uses_allocator_v<T2,~~memory_resource*~~polymorphic_allocator>isfalseandis_constructible_v<T2,Args2...>istrue, thenyprimeisy.- (9.6) — Otherwise, if
uses_allocator_v<T2,~~memory_resource*~~polymorphic_allocator>istrueandis_constructible_v<T2,allocator_arg_t,~~memory_resource*~~polymorphic_allocator,Args2...>istrue, thenyprimeistuple_cat(make_tuple(allocator_arg, ~~resource()~~*this), std::move(y)).- (9.7) — Otherwise, if
uses_allocator_v<T2,~~memory_resource*~~polymorphic_allocator>istrueandis_constructible_v<T2,Args2...,~~memory_resource*~~polymorphic_allocator>istrue, thenyprimeistuple_cat(std::move(y), make_tuple(~~resource()~~*this)).- (9.8) — Otherwise the program is ill formed.