Skip to content

Commit 2711618

Browse files
authoredJul 28, 2024
[libc++][memory_resource] Implements LWG3683. (llvm#100775)
The polymorphic_allocator was added in C++17. This issue was filed in 2022 so well after C++20. This issue adds an operator==. Starting with C++20 this adds a compiler generated operator!=. To have the same behaviour in C++17 and C++20 (and later) a manual operator!= is defined in C++17. Implements - LWG3683 operator== for polymorphic_allocator cannot deduce template argument in common cases
1 parent 6907ab4 commit 2711618

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed
 

‎libcxx/docs/Status/Cxx23Issues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@
166166
"`3670 <https://wg21.link/LWG3670>`__","``Cpp17InputIterators`` don't have integer-class difference types","July 2022","","","|ranges|"
167167
"`3671 <https://wg21.link/LWG3671>`__","``atomic_fetch_xor`` missing from ``stdatomic.h``","July 2022","",""
168168
"`3672 <https://wg21.link/LWG3672>`__","``common_iterator::operator->()`` should return by value","July 2022","|Complete|","19.0","|ranges|"
169-
"`3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","",""
169+
"`3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","|Complete|","20.0"
170170
"`3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","July 2022","|Complete|","16.0"
171171
"`3692 <https://wg21.link/LWG3692>`__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","July 2022","","","|ranges| |spaceship|"
172172
"`3701 <https://wg21.link/LWG3701>`__","Make ``formatter<remove_cvref_t<const charT[N]>, charT>`` requirement explicit","July 2022","|Complete|","15.0","|format|"

‎libcxx/include/__memory_resource/polymorphic_allocator.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
174174

175175
_LIBCPP_HIDE_FROM_ABI memory_resource* resource() const noexcept { return __res_; }
176176

177+
friend bool operator==(const polymorphic_allocator& __lhs, const polymorphic_allocator& __rhs) noexcept {
178+
return *__lhs.resource() == *__rhs.resource();
179+
}
180+
181+
# if _LIBCPP_STD_VER <= 17
182+
// This overload is not specified, it was added due to LWG3683.
183+
friend bool operator!=(const polymorphic_allocator& __lhs, const polymorphic_allocator& __rhs) noexcept {
184+
return *__lhs.resource() != *__rhs.resource();
185+
}
186+
# endif
187+
177188
private:
178189
template <class... _Args, size_t... _Is>
179190
_LIBCPP_HIDE_FROM_ABI tuple<_Args&&...>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14
10+
// UNSUPPORTED: availability-pmr-missing
11+
12+
// <memory_resource>
13+
14+
// template <class T> class polymorphic_allocator
15+
16+
// friend bool operator==(const polymorphic_allocator& a,
17+
// const polymorphic_allocator& b) noexcept
18+
19+
#include <memory_resource>
20+
#include <cassert>
21+
#include <vector>
22+
23+
#include "test_macros.h"
24+
25+
int main(int, char**) {
26+
std::pmr::unsynchronized_pool_resource a;
27+
std::pmr::vector<int> vec(&a);
28+
29+
assert(vec.get_allocator() == &a);
30+
static_assert(noexcept(vec.get_allocator() == &a));
31+
32+
// LWG3683 added operator== after C++20. In C++20 operator!= is generated by
33+
// the compiler. Libc++ adds operator!= in C++17 as an extension. MSVC STL
34+
// and libstdc++ have done the same so test this extension unconditionally.
35+
std::pmr::unsynchronized_pool_resource b;
36+
37+
assert(vec.get_allocator() != &b);
38+
static_assert(noexcept(vec.get_allocator() != &b));
39+
40+
return 0;
41+
}

0 commit comments

Comments
 (0)
Please sign in to comment.