diff --git a/libcxx/include/__config b/libcxx/include/__config --- 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_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 --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -714,9 +714,12 @@ 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_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/test/std/utilities/template.bitset/bitset.members/index.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp --- 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 @@ assert(r == false); assert(v1.test(N/2) == false); } + ASSERT_SAME_TYPE(decltype(v1[0]), typename std::bitset::reference); } } 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 --- 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 @@ assert(v[N/2] == v.test(N/2)); } } +#if !defined(_LIBCPP_VERSION) || defined(_LIBCPP_ABI_BITSET_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 @@ 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_CONST_SUBSCRIPT_RETURN_BOOL) + assert(!b); +#else + assert(b); +#endif // _LIBCPP_ABI_BITSET_CONST_SUBSCRIPT_RETURN_BOOL + return 0; }