Skip to content

Commit

Permalink
P1518R2 Stop Overconstraining Allocators In Container Deduction Guides (
Browse files Browse the repository at this point in the history
#2032)

Co-authored-by: Michael Schellenberger Costa <[email protected]>
Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
3 people authored Aug 27, 2021
1 parent 96a4c16 commit d46c27f
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 18 deletions.
4 changes: 2 additions & 2 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ public:
_Proxy._Release();
}

deque(const deque& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
deque(const deque& _Right, const _Identity_t<_Alloc>& _Al) : _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 +706,7 @@ public:
_Take_contents(_Right);
}

deque(deque&& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
deque(deque&& _Right, const _Identity_t<_Alloc>& _Al) : _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
5 changes: 3 additions & 2 deletions stl/inc/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,8 @@ 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) {
forward_list(const forward_list& _Right, const _Identity_t<_Alloc>& _Al)
: _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,7 +612,7 @@ public:
_Take_head(_Right);
}

forward_list(forward_list&& _Right, const _Alloc& _Al) noexcept(
forward_list(forward_list&& _Right, const _Identity_t<_Alloc>& _Al) noexcept(
_Alnode_traits::is_always_equal::value) // strengthened
: _Mypair(_One_then_variadic_args_t{}, _Al) {
if constexpr (!_Alty_traits::is_always_equal::value) {
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/list
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ public:
_Construct_range_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end());
}

list(const list& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
list(const list& _Right, const _Identity_t<_Alloc>& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
_Construct_range_unchecked(_Right._Unchecked_begin(), _Right._Unchecked_end());
}

Expand All @@ -885,7 +885,7 @@ public:
_Swap_val(_Right);
}

list(list&& _Right, const _Alloc& _Al) : _Mypair(_One_then_variadic_args_t{}, _Al) {
list(list&& _Right, const _Identity_t<_Alloc>& _Al) : _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
8 changes: 3 additions & 5 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>;
Expand All @@ -368,7 +366,7 @@ template <class _Iter, class _Compare, class _Alloc, class _Container = vector<_
priority_queue(_Iter, _Iter, _Compare, _Alloc) -> priority_queue<_Iter_value_t<_Iter>, _Container, _Compare>;

template <class _Iter, class _Compare, class _Container, class _Alloc,
enable_if_t<conjunction_v<_Is_iterator<_Iter>, _Is_allocator<_Alloc>, uses_allocator<_Container, _Alloc>>, int> = 0>
enable_if_t<conjunction_v<_Is_iterator<_Iter>, uses_allocator<_Container, _Alloc>>, int> = 0>
priority_queue(_Iter, _Iter, _Compare, _Container, _Alloc)
-> priority_queue<typename _Container::value_type, _Container, _Compare>;
#endif // _HAS_CXX17
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
9 changes: 5 additions & 4 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,8 @@ 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) {
_CONSTEXPR20 vector(const vector& _Right, const _Identity_t<_Alloc>& _Al)
: _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,7 +536,7 @@ public:
_Mypair._Myval2._Swap_proxy_and_iterators(_Right._Mypair._Myval2);
}

_CONSTEXPR20 vector(vector&& _Right, const _Alloc& _Al_) noexcept(
_CONSTEXPR20 vector(vector&& _Right, const _Identity_t<_Alloc>& _Al_) noexcept(
_Alty_traits::is_always_equal::value) // strengthened
: _Mypair(_One_then_variadic_args_t{}, _Al_) {
_Alty& _Al = _Getal();
Expand Down Expand Up @@ -2472,7 +2473,7 @@ public:

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

_CONSTEXPR20 vector(const vector& _Right, const _Alloc& _Al) : _Mybase(_Right, _Al) {}
_CONSTEXPR20 vector(const vector& _Right, const _Identity_t<_Alloc>& _Al) : _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,7 +2490,7 @@ public:
this->_Swap_proxy_and_iterators(_Right);
}

_CONSTEXPR20 vector(vector&& _Right, const _Alloc& _Al) noexcept(
_CONSTEXPR20 vector(vector&& _Right, const _Identity_t<_Alloc>& _Al) noexcept(
is_nothrow_constructible_v<_Mybase, _Mybase, const _Alloc&>)
: _Mybase(_STD move(_Right), _Al) {
if constexpr (!_Alvbase_traits::is_always_equal::value) {
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,137 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <deque>
#include <forward_list>
#include <functional>
#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;

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(move(px), &mr);
}

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) {
[[maybe_unused]] auto x = SfinaeTester<priority_queue>::test(comp, pc, &mr);
[[maybe_unused]] auto y = SfinaeTester<priority_queue>::test(comp, move(pc), &mr);
}

void test_priority_queue3(int* begin, int* end, less<int> comp, pmr::vector<int>& pc) {
[[maybe_unused]] auto x = SfinaeTester<priority_queue>::test(begin, end, comp, pc, &mr);
[[maybe_unused]] auto y = SfinaeTester<priority_queue>::test(begin, end, comp, move(pc), &mr);
}

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

0 comments on commit d46c27f

Please sign in to comment.