Skip to content

P1518R2 Stop Overconstraining Allocators In Container Deduction Guides #2032

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Aug 27, 2021
Merged
15 changes: 13 additions & 2 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <xmemory>

#if _HAS_CXX17
#include <type_traits>
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

Expand Down Expand Up @@ -652,7 +653,12 @@ public:
_Proxy._Release();
}

deque(const deque& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
deque(const deque& _Right, const _Identity_t<_Alloc>& _Al)
#else
deque(const deque& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mypair(_One_then_variadic_args_t{}, _Al) {
_Alproxy_ty _Alproxy(_Getal());
_Container_proxy_ptr12<_Alproxy_ty> _Proxy(_Alproxy, _Get_data());
_Construct(_Right._Unchecked_begin(), _Right._Unchecked_end());
Expand Down Expand Up @@ -701,7 +707,12 @@ public:
_Take_contents(_Right);
}

deque(deque&& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
deque(deque&& _Right, const _Identity_t<_Alloc>& _Al)
#else
deque(deque&& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mypair(_One_then_variadic_args_t{}, _Al) {
_Alproxy_ty _Alproxy(_Getal());
if constexpr (!_Alty_traits::is_always_equal::value) {
if (_Getal() != _Right._Getal()) {
Expand Down
16 changes: 13 additions & 3 deletions stl/inc/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <xmemory>

#if _HAS_CXX17
#include <type_traits>
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

Expand Down Expand Up @@ -587,7 +588,12 @@ public:
_Insert_op._Attach_after(_Mypair._Myval2._Before_head());
}

forward_list(const forward_list& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
forward_list(const forward_list& _Right, const _Identity_t<_Alloc>& _Al)
#else
forward_list(const forward_list& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mypair(_One_then_variadic_args_t{}, _Al) {
_Flist_insert_after_op2<_Alnode> _Insert_op(_Getal());
_Insert_op._Append_range_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end());
_Alloc_proxy();
Expand Down Expand Up @@ -618,8 +624,12 @@ public:
_Take_head(_Right);
}

forward_list(forward_list&& _Right, const _Alloc& _Al) noexcept(
_Alnode_traits::is_always_equal::value) // strengthened
#if _HAS_CXX17
forward_list(forward_list&& _Right, const _Identity_t<_Alloc>& _Al)
#else
forward_list(forward_list&& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
noexcept(_Alnode_traits::is_always_equal::value) // strengthened
: _Mypair(_One_then_variadic_args_t{}, _Al) {
if constexpr (!_Alty_traits::is_always_equal::value) {
if (_Getal() != _Right._Getal()) {
Expand Down
15 changes: 13 additions & 2 deletions stl/inc/list
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <xmemory>

#if _HAS_CXX17
#include <type_traits>
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

Expand Down Expand Up @@ -873,7 +874,12 @@ public:
_Construct_range_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end());
}

list(const list& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
list(const list& _Right, const _Identity_t<_Alloc>& _Al)
#else
list(const list& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mypair(_One_then_variadic_args_t{}, _Al) {
_Construct_range_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end());
}

Expand All @@ -894,7 +900,12 @@ public:
_Swap_val(_Right);
}

list(list&& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
list(list&& _Right, const _Identity_t<_Alloc>& _Al)
#else
list(list&& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mypair(_One_then_variadic_args_t{}, _Al) {
if constexpr (!_Alnode_traits::is_always_equal::value) {
if (_Getal() != _Right._Getal()) {
_Construct_range_unchecked(_STD make_move_iterator(_Right._Unchecked_begin()),
Expand Down
6 changes: 2 additions & 4 deletions stl/inc/queue
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ template <class _Container, enable_if_t<!_Is_allocator<_Container>::value, int>
queue(_Container) -> queue<typename _Container::value_type, _Container>;

template <class _Container, class _Alloc,
enable_if_t<
conjunction_v<negation<_Is_allocator<_Container>>, _Is_allocator<_Alloc>, uses_allocator<_Container, _Alloc>>,
int> = 0>
enable_if_t<conjunction_v<negation<_Is_allocator<_Container>>, uses_allocator<_Container, _Alloc>>, int> = 0>
queue(_Container, _Alloc) -> queue<typename _Container::value_type, _Container>;
#endif // _HAS_CXX17

Expand Down Expand Up @@ -307,7 +305,7 @@ priority_queue(_Iter, _Iter, _Pr = _Pr(), _Container = _Container())
-> priority_queue<_Iter_value_t<_Iter>, _Container, _Pr>;

template <class _Pr, class _Container, class _Alloc,
enable_if_t<conjunction_v<negation<_Is_allocator<_Pr>>, negation<_Is_allocator<_Container>>, _Is_allocator<_Alloc>,
enable_if_t<conjunction_v<negation<_Is_allocator<_Pr>>, negation<_Is_allocator<_Container>>,
uses_allocator<_Container, _Alloc>>,
int> = 0>
priority_queue(_Pr, _Container, _Alloc) -> priority_queue<typename _Container::value_type, _Container, _Pr>;
Expand Down
4 changes: 1 addition & 3 deletions stl/inc/stack
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ template <class _Container, enable_if_t<!_Is_allocator<_Container>::value, int>
stack(_Container) -> stack<typename _Container::value_type, _Container>;

template <class _Container, class _Alloc,
enable_if_t<
conjunction_v<negation<_Is_allocator<_Container>>, _Is_allocator<_Alloc>, uses_allocator<_Container, _Alloc>>,
int> = 0>
enable_if_t<conjunction_v<negation<_Is_allocator<_Container>>, uses_allocator<_Container, _Alloc>>, int> = 0>
stack(_Container, _Alloc) -> stack<typename _Container::value_type, _Container>;
#endif // _HAS_CXX17

Expand Down
32 changes: 26 additions & 6 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <xmemory>

#if _HAS_CXX17
#include <type_traits>
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

Expand Down Expand Up @@ -527,7 +528,12 @@ public:
_Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast);
}

_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Identity_t<_Alloc>& _Al)
#else
_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mypair(_One_then_variadic_args_t{}, _Al) {
const auto& _Right_data = _Right._Mypair._Myval2;
const auto _Count = static_cast<size_type>(_Right_data._Mylast - _Right_data._Myfirst);
_Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast);
Expand All @@ -542,8 +548,12 @@ public:
_Mypair._Myval2._Swap_proxy_and_iterators(_Right._Mypair._Myval2);
}

_CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al_) noexcept(
_Alty_traits::is_always_equal::value) // strengthened
#if _HAS_CXX17
_CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Identity_t<_Alloc>& _Al_)
#else
_CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al_)
#endif // _HAS_CXX17
noexcept(_Alty_traits::is_always_equal::value) // strengthened
: _Mypair(_One_then_variadic_args_t{}, _Al_) {
_Alty& _Al = _Getal();
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al);
Expand Down Expand Up @@ -2487,7 +2497,13 @@ public:

_CONSTEXPR20_CONTAINER vector(const vector& _Right) : _Mybase(_Right) {}

_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Alloc& _Al) : _Mybase(_Right, _Al) {}
#if _HAS_CXX17
_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Identity_t<_Alloc>& _Al)
#else
_CONSTEXPR20_CONTAINER vector(const vector& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
: _Mybase(_Right, _Al) {
}

template <class _Iter, enable_if_t<_Is_iterator_v<_Iter>, int> = 0>
_CONSTEXPR20_CONTAINER vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc()) : _Mybase(_Al) {
Expand All @@ -2504,8 +2520,12 @@ public:
this->_Swap_proxy_and_iterators(_Right);
}

_CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al) noexcept(
is_nothrow_constructible_v<_Mybase, _Mybase, const _Alloc&>)
#if _HAS_CXX17
_CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Identity_t<_Alloc>& _Al)
#else
_CONSTEXPR20_CONTAINER vector(vector&& _Right, const _Alloc& _Al)
#endif // _HAS_CXX17
noexcept(is_nothrow_constructible_v<_Mybase, _Mybase, const _Alloc&>)
: _Mybase(_STD move(_Right), _Al) {
if constexpr (!_Alvbase_traits::is_always_equal::value) {
if (this->_Getal() != _Right._Getal()) {
Expand Down
1 change: 1 addition & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
// P0858R0 Constexpr Iterator Requirements
// P1065R2 constexpr INVOKE
// (the std::invoke function only; other components like bind and reference_wrapper are C++20 only)
// P1518R2 Stop Overconstraining Allocators In Container Deduction Guides
// P2162R2 Inheriting From variant

// _HAS_CXX17 indirectly controls:
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ tests\P1165R1_consistently_propagating_stateful_allocators
tests\P1208R6_source_location
tests\P1423R3_char8_t_remediation
tests\P1502R1_standard_library_header_units
tests\P1518R2_stop_overconstraining_allocators
tests\P1614R2_spaceship
tests\P1645R1_constexpr_numeric
tests\P1682R3_to_underlying
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_17_matrix.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <deque>
#include <forward_list>
#include <list>
#include <map>
#include <memory_resource>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

extern pmr::monotonic_buffer_resource mr;

template <template <class...> class Ctr>
struct SfinaeTester {
template <class... Args>
static auto f(int, Args&&... args) -> decltype(Ctr(static_cast<Args&&>(args)...)) {
return Ctr(static_cast<Args&&>(args)...);
}
template <class... Args>
static void f(long, Args&&... /*args*/) {}

template <class... Args>
static auto test(Args&&... args) {
return f(0, static_cast<Args&&>(args)...);
}
};

auto test_deque(pmr::deque<int>& px) {
auto x = SfinaeTester<deque>::test(px, &mr);
}

auto test_forward_list(pmr::forward_list<int>& px) {
auto x = SfinaeTester<forward_list>::test(px, &mr);
}

auto test_list(pmr::list<int>& px) {
auto x = SfinaeTester<list>::test(px, &mr);
}

auto test_vector(pmr::vector<int>& px) {
auto x = SfinaeTester<vector>::test(px, &mr);
}

auto test_map(pmr::map<int, int>& px) {
auto x = SfinaeTester<map>::test(px, &mr);
}

auto test_multimap(pmr::multimap<int, int>& px) {
auto x = SfinaeTester<multimap>::test(px, &mr);
}

auto test_multiset(pmr::multiset<int>& px) {
auto x = SfinaeTester<multiset>::test(px, &mr);
}

auto test_set(pmr::set<int>& px) {
auto x = SfinaeTester<set>::test(px, &mr);
}

auto test_unordered_map(pmr::unordered_map<int, int>& px) {
auto x = SfinaeTester<unordered_map>::test(px, &mr);
}

auto test_unordered_multimap(pmr::unordered_multimap<int, int>& px) {
auto x = SfinaeTester<unordered_multimap>::test(px, &mr);
}

auto test_unordered_multiset(pmr::unordered_multiset<int>& px) {
auto x = SfinaeTester<unordered_multiset>::test(px, &mr);
}

auto test_unordered_set(pmr::unordered_set<int>& px) {
auto x = SfinaeTester<unordered_set>::test(px, &mr);
}

auto test_priority_queue1(priority_queue<int, pmr::vector<int>>& px) {
auto x = SfinaeTester<priority_queue>::test(px, &mr);
}

auto test_queue1(queue<int, pmr::deque<int>>& px) {
auto x = SfinaeTester<queue>::test(px, &mr);
}

auto test_stack1(stack<int, pmr::vector<int>>& px) {
auto x = SfinaeTester<stack>::test(px, &mr);
}

auto test_priority_queue2(less<int> comp, pmr::vector<int>& pc) {
auto x = SfinaeTester<priority_queue>::test(comp, pc, &mr);
}

auto test_queue2(pmr::deque<int>& pc) {
auto x = SfinaeTester<queue>::test(pc, &mr);
}

auto test_stack2(pmr::vector<int>& pc) {
auto x = SfinaeTester<stack>::test(pc, &mr);
}

int main() {} // COMPILE-ONLY