Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion libcxx/docs/ReleaseNotes/21.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,20 @@ Deprecations and Removals

- ``std::is_pod`` and ``std::is_pod_v`` are deprecated in C++20 and later.

- libc++ no long adds ``constexpr`` to ``std::hash<std::vector<bool, A>>::operator()``. The ``constexpr`` addition
since C++20 was an unintended extension. The ``_LIBCPP_ENABLE_REMOVED_CONSTEXPR_HASH_VECTOR_BOOL`` macro can be
defined to temporarily re-enable this extension. This macro will be honored for one release and ignored starting in
LLVM 22.

Upcoming Deprecations and Removals
----------------------------------

LLVM 22
~~~~~~~

- TODO
- TODO: The ``constexpr`` addition to ``std::hash<std::vector<bool, A>>::operator()`` will be removed entirely, and the
``_LIBCPP_ENABLE_REMOVED_CONSTEXPR_HASH_VECTOR_BOOL`` macro that was used to re-enable this extension will be ignored
in LLVM 22.


ABI Affecting Changes
Expand Down
15 changes: 12 additions & 3 deletions libcxx/include/__vector/vector_bool.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ _LIBCPP_PUSH_MACROS

_LIBCPP_BEGIN_NAMESPACE_STD

// TODO(LLVM 22): Remove the escape hatch
#ifdef _LIBCPP_ENABLE_REMOVED_CONSTEXPR_HASH_VECTOR_BOOL
# define _LIBCPP_CONSTEXPR_HASH_VECTOR_BOOL _LIBCPP_CONSTEXPR_SINCE_CXX20
#else
# define _LIBCPP_CONSTEXPR_HASH_VECTOR_BOOL
#endif

template <class _Allocator>
struct hash<vector<bool, _Allocator> >;

Expand Down Expand Up @@ -512,7 +519,7 @@ class _LIBCPP_TEMPLATE_VIS vector<bool, _Allocator> {

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign_alloc(vector&, false_type) _NOEXCEPT {}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t __hash_code() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_HASH_VECTOR_BOOL size_t __hash_code() const _NOEXCEPT;

friend class __bit_reference<vector>;
friend class __bit_const_reference<vector>;
Expand Down Expand Up @@ -1093,7 +1100,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 bool vector<bool, _Allocator>::__invariants() cons
}

template <class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 size_t vector<bool, _Allocator>::__hash_code() const _NOEXCEPT {
_LIBCPP_CONSTEXPR_HASH_VECTOR_BOOL size_t vector<bool, _Allocator>::__hash_code() const _NOEXCEPT {
size_t __h = 0;
// do middle whole words
size_type __n = __size_;
Expand All @@ -1111,12 +1118,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t vector<bool, _Allocator>::__hash_code() con
template <class _Allocator>
struct _LIBCPP_TEMPLATE_VIS hash<vector<bool, _Allocator> >
: public __unary_function<vector<bool, _Allocator>, size_t> {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_HASH_VECTOR_BOOL size_t
operator()(const vector<bool, _Allocator>& __vec) const _NOEXCEPT {
return __vec.__hash_code();
}
};

#undef _LIBCPP_CONSTEXPR_HASH_VECTOR_BOOL

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// REQUIRES: std-at-least-c++20

// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_REMOVED_CONSTEXPR_HASH_VECTOR_BOOL

// <vector>

// template<class Allocator> struct hash<vector<bool, Allocator>>;

// Since LLVM 16, libc++ has made the operator() of this partial specialization constexpr since C++20,
// which is a conforming extension. However, such extension was unintended, and is being removed.

#include <cassert>
#include <functional>
#include <vector>

#include "min_allocator.h"

template <class VBType>
constexpr void test() {
bool ba[]{true, false, true, true, false};
VBType vb(std::begin(ba), std::end(ba));

const std::hash<VBType> h{};
const auto hash_value = h(vb);
assert(hash_value == h(vb));
assert(hash_value != 0);
}

constexpr bool test() {
test<std::vector<bool>>();
test<std::vector<bool, min_allocator<bool>>>();

return true;
}

int main(int, char**) {
test();
static_assert(test());

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,14 @@
#include "test_macros.h"
#include "min_allocator.h"

TEST_CONSTEXPR_CXX20 bool test() {
void test() {
test_hash_enabled<std::vector<bool> >();
test_hash_enabled<std::vector<bool, min_allocator<bool>>>();

return true;
}

int main(int, char**) {
test_library_hash_specializations_available();
test();
#if TEST_STD_VER > 17
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// size_t operator()(T val) const;
// };

// Not very portable

#include <vector>
#include <cassert>
#include <iterator>
Expand All @@ -37,7 +35,9 @@ TEST_CONSTEXPR_CXX20 bool tests() {
bool ba[] = {true, false, true, true, false};
T vb(std::begin(ba), std::end(ba));
H h;
assert(h(vb) != 0);
if (!TEST_IS_CONSTANT_EVALUATED) {
assert(h(vb) == h(vb));
}
}
#if TEST_STD_VER >= 11
{
Expand All @@ -51,7 +51,9 @@ TEST_CONSTEXPR_CXX20 bool tests() {
bool ba[] = {true, false, true, true, false};
T vb(std::begin(ba), std::end(ba));
H h;
assert(h(vb) != 0);
if (!TEST_IS_CONSTANT_EVALUATED) {
assert(h(vb) == h(vb));
}
}
#endif

Expand Down