From: Nikolas Klauser Date: Sat, 9 Apr 2022 07:48:21 +0000 (+0200) Subject: [libc++] `bitset::operator[] const` should return bool X-Git-Tag: upstream/15.0.7~10513 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=667925d45a9ebd9c6e4ba7cac76d82fb9b735274;p=platform%2Fupstream%2Fllvm.git [libc++] `bitset::operator[] const` should return bool Fixes https://github.com/llvm/llvm-project/issues/10686 Reviewed By: Mordante, ldionne, var-const, #libc Spies: jloser, libcxx-commits, arphaman Differential Revision: https://reviews.llvm.org/D122092 --- diff --git a/libcxx/include/__config b/libcxx/include/__config index 7a4d574..660e98f 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -114,6 +114,8 @@ # define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON // Remove vector base class # define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON +// According to the Standard, `bitset::operator[] const` returns bool +# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support diff --git a/libcxx/include/bitset b/libcxx/include/bitset index 28862d8e..7fac7aa 100644 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -715,9 +715,12 @@ public: bitset& flip(size_t __pos); // element access: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - const_reference operator[](size_t __p) const {return base::__make_ref(__p);} - _LIBCPP_INLINE_VISIBILITY reference operator[](size_t __p) {return base::__make_ref(__p);} +#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {return base::__make_ref(__p);} +#else + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const {return base::__make_ref(__p);} +#endif + _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __p) {return base::__make_ref(__p);} _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const; _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/include/vector b/libcxx/include/vector index e7d183c..165b21d 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -2079,7 +2079,11 @@ private: __compressed_pair __cap_alloc_; public: typedef __bit_reference reference; +#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL + using const_reference = bool; +#else typedef __bit_const_reference const_reference; +#endif private: _LIBCPP_INLINE_VISIBILITY size_type& __cap() _NOEXCEPT @@ -2276,7 +2280,6 @@ public: iterator insert(const_iterator __position, const value_type& __x); iterator insert(const_iterator __position, size_type __n, const value_type& __x); - iterator insert(const_iterator __position, size_type __n, const_reference __x); template typename enable_if < @@ -2365,8 +2368,10 @@ private: reference __make_ref(size_type __pos) _NOEXCEPT {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY - const_reference __make_ref(size_type __pos) const _NOEXCEPT - {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + const_reference __make_ref(size_type __pos) const _NOEXCEPT { + return __bit_const_reference(__begin_ + __pos / __bits_per_word, + __storage_type(1) << __pos % __bits_per_word); + } _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_type __pos) _NOEXCEPT {return iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} diff --git a/libcxx/test/std/containers/sequences/vector.bool/const_reference.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/const_reference.pass.cpp new file mode 100644 index 0000000..68b2747 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/const_reference.pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +#include +#include + +#include "test_macros.h" + +bool test() { + using CRefT = std::vector::const_reference; +#if !defined(_LIBCPP_VERSION) || defined(_LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL) + ASSERT_SAME_TYPE(CRefT, bool); +#else + ASSERT_SAME_TYPE(CRefT, std::__bit_const_reference >); + std::vector vec; + vec.push_back(true); + CRefT ref = vec[0]; + assert(ref); + vec[0] = false; + assert(!ref); +#endif + + return true; +} + +int main(int, char**) { + test(); + + return 0; +} diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp index 25ba219..db2c464 100644 --- a/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp +++ b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp @@ -42,6 +42,7 @@ void test_index() { assert(r == false); assert(v1.test(N/2) == false); } + ASSERT_SAME_TYPE(decltype(v1[0]), typename std::bitset::reference); } } @@ -56,5 +57,11 @@ int main(int, char**) { test_index<65>(); test_index<1000>(); + std::bitset<1> set; + set[0] = false; + auto b = set[0]; + set[0] = true; + assert(b); + return 0; } diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp index 19ccb97..4c0830b 100644 --- a/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp +++ b/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp @@ -25,6 +25,11 @@ void test_index_const() { assert(v[N/2] == v.test(N/2)); } } +#if !defined(_LIBCPP_VERSION) || defined(_LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL) + ASSERT_SAME_TYPE(decltype(cases[0][0]), bool); +#else + ASSERT_SAME_TYPE(decltype(cases[0][0]), typename std::bitset::const_reference); +#endif } int main(int, char**) { @@ -38,5 +43,16 @@ int main(int, char**) { test_index_const<65>(); test_index_const<1000>(); + std::bitset<1> set_; + set_[0] = false; + const auto& set = set_; + auto b = set[0]; + set_[0] = true; +#if !defined(_LIBCPP_VERSION) || defined(_LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL) + assert(!b); +#else + assert(b); +#endif + return 0; }