Skip to content
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

P1518R2 Stop Overconstraining Allocators In Container Deduction Guides #2032

Merged
merged 14 commits into from
Aug 27, 2021
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>
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

Expand Down Expand Up @@ -657,7 +658,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
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
: _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 @@ -706,7 +712,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 @@ -580,7 +581,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 @@ -611,8 +617,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 @@ -864,7 +865,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 @@ -885,7 +891,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 @@ -134,9 +134,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 @@ -354,7 +352,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>;
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
4 changes: 1 addition & 3 deletions stl/inc/stack
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,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 @@ -520,7 +521,12 @@ public:
_Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast);
}

_CONSTEXPR20 vector(const vector& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
#if _HAS_CXX17
_CONSTEXPR20 vector(const vector& _Right, const _Identity_t<_Alloc>& _Al)
#else
_CONSTEXPR20 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 @@ -535,8 +541,12 @@ public:
_Mypair._Myval2._Swap_proxy_and_iterators(_Right._Mypair._Myval2);
}

_CONSTEXPR20 vector(vector&& _Right, const _Alloc& _Al_) noexcept(
_Alty_traits::is_always_equal::value) // strengthened
#if _HAS_CXX17
_CONSTEXPR20 vector(vector&& _Right, const _Identity_t<_Alloc>& _Al_)
#else
_CONSTEXPR20 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 @@ -2472,7 +2482,13 @@ public:

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

_CONSTEXPR20 vector(const vector& _Right, const _Alloc& _Al) : _Mybase(_Right, _Al) {}
#if _HAS_CXX17
_CONSTEXPR20 vector(const vector& _Right, const _Identity_t<_Alloc>& _Al)
#else
_CONSTEXPR20 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 vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc()) : _Mybase(_Al) {
Expand All @@ -2489,8 +2505,12 @@ public:
this->_Swap_proxy_and_iterators(_Right);
}

_CONSTEXPR20 vector(vector&& _Right, const _Alloc& _Al) noexcept(
is_nothrow_constructible_v<_Mybase, _Mybase, const _Alloc&>)
#if _HAS_CXX17
_CONSTEXPR20 vector(vector&& _Right, const _Identity_t<_Alloc>& _Al)
#else
_CONSTEXPR20 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 @@ -426,6 +426,7 @@ tests\P1208R6_source_location
tests\P1423R3_char8_t_remediation
tests\P1425R4_queue_stack_constructors
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,131 @@
// 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 <utility>
#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&&...) {}

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

void test_deque(pmr::deque<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<deque>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<deque>::test(move(px), &mr);
}

void test_forward_list(pmr::forward_list<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<forward_list>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<forward_list>::test(move(px), &mr);
}

void test_list(pmr::list<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<list>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<list>::test(move(px), &mr);
}

void test_vector(pmr::vector<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<vector>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<vector>::test(move(px), &mr);
}

void test_vector_bool(pmr::vector<bool>& px) {
[[maybe_unused]] auto x = SfinaeTester<vector>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<vector>::test(move(px), &mr);
}

void test_map(pmr::map<int, int>& px) {
[[maybe_unused]] auto x = SfinaeTester<map>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<map>::test(px, &mr);
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
}

void test_multimap(pmr::multimap<int, int>& px) {
[[maybe_unused]] auto x = SfinaeTester<multimap>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<multimap>::test(move(px), &mr);
}

void test_multiset(pmr::multiset<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<multiset>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<multiset>::test(move(px), &mr);
}

void test_set(pmr::set<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<set>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<set>::test(move(px), &mr);
}

void test_unordered_map(pmr::unordered_map<int, int>& px) {
[[maybe_unused]] auto x = SfinaeTester<unordered_map>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<unordered_map>::test(move(px), &mr);
}

void test_unordered_multimap(pmr::unordered_multimap<int, int>& px) {
[[maybe_unused]] auto x = SfinaeTester<unordered_multimap>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<unordered_multimap>::test(move(px), &mr);
}

void test_unordered_multiset(pmr::unordered_multiset<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<unordered_multiset>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<unordered_multiset>::test(move(px), &mr);
}

void test_unordered_set(pmr::unordered_set<int>& px) {
[[maybe_unused]] auto x = SfinaeTester<unordered_set>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<unordered_set>::test(move(px), &mr);
}

void test_priority_queue1(priority_queue<int, pmr::vector<int>>& px) {
[[maybe_unused]] auto x = SfinaeTester<priority_queue>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<priority_queue>::test(move(px), &mr);
}

void test_queue1(queue<int, pmr::deque<int>>& px) {
[[maybe_unused]] auto x = SfinaeTester<queue>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<queue>::test(move(px), &mr);
}

void test_stack1(stack<int, pmr::vector<int>>& px) {
[[maybe_unused]] auto x = SfinaeTester<stack>::test(px, &mr);
[[maybe_unused]] auto y = SfinaeTester<stack>::test(move(px), &mr);
}

void test_priority_queue2(less<int> comp, pmr::vector<int>& pc) {
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
[[maybe_unused]] auto x = SfinaeTester<priority_queue>::test(comp, pc, &mr);
[[maybe_unused]] auto y = SfinaeTester<priority_queue>::test(comp, move(pc), &mr);
fsb4000 marked this conversation as resolved.
Show resolved Hide resolved
}

void test_queue2(pmr::deque<int>& pc) {
[[maybe_unused]] auto x = SfinaeTester<queue>::test(pc, &mr);
[[maybe_unused]] auto y = SfinaeTester<queue>::test(move(pc), &mr);
}

void test_stack2(pmr::vector<int>& pc) {
[[maybe_unused]] auto x = SfinaeTester<stack>::test(pc, &mr);
[[maybe_unused]] auto y = SfinaeTester<stack>::test(move(pc), &mr);
}

int main() {} // COMPILE-ONLY