Files
llvm/libcxx/include/bitset
Nikolas Klauser 1b0553c9fa [libc++] Use _BitInt and __builtin_popcountg in bitset::count() (#160679)
This has multiple benefits:
1) The compiler has to do way less work to figure out things fold into a
simple `popcount`, improving compile times quite a bit
2) The compiler inlines better, since the compile doesn't have to do
complicated optimizations to get to the same point. Looking at the
pipeline, it seems that without this, LLVM has to go all the way to GVN
to get to the same code as there is after the first InstCombine pass
with this change.

Currently this applies only to `bitset`s with at most 64 bits, but that
is by far the most common case.
2025-09-25 20:16:27 +02:00

971 lines
41 KiB
C++

// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_BITSET
#define _LIBCPP_BITSET
// clang-format off
/*
bitset synopsis
namespace std
{
namespace std {
template <size_t N>
class bitset
{
public:
// bit reference:
class reference
{
friend class bitset;
reference() noexcept;
public:
~reference() noexcept;
reference& operator=(bool x) noexcept; // for b[i] = x;
reference& operator=(const reference&) noexcept; // for b[i] = b[j];
bool operator~() const noexcept; // flips the bit
operator bool() const noexcept; // for x = b[i];
reference& flip() noexcept; // for b[i].flip();
};
// 23.3.5.1 constructors:
constexpr bitset() noexcept;
constexpr bitset(unsigned long long val) noexcept;
template <class charT>
constexpr explicit bitset(const charT* str,
typename basic_string<charT>::size_type n = basic_string<charT>::npos,
charT zero = charT('0'), charT one = charT('1')); // until C++26, constexpr since C++23
template <class charT>
constexpr explicit bitset(const charT* str,
typename basic_string_view<charT>::size_type n = basic_string_view<charT>::npos,
charT zero = charT('0'), charT one = charT('1')); // since C++26
template<class charT, class traits>
explicit bitset(
const basic_string_view<charT,traits>& str,
typename basic_string_view<charT,traits>::size_type pos = 0,
typename basic_string_view<charT,traits>::size_type n = basic_string_view<charT,traits>::npos,
charT zero = charT('0'), charT one = charT('1')); // since C++26
template<class charT, class traits, class Allocator>
constexpr explicit bitset(
const basic_string<charT,traits,Allocator>& str,
typename basic_string<charT,traits,Allocator>::size_type pos = 0,
typename basic_string<charT,traits,Allocator>::size_type n = basic_string<charT,traits,Allocator>::npos,
charT zero = charT('0'), charT one = charT('1')); // constexpr since C++23
// 23.3.5.2 bitset operations:
bitset& operator&=(const bitset& rhs) noexcept; // constexpr since C++23
bitset& operator|=(const bitset& rhs) noexcept; // constexpr since C++23
bitset& operator^=(const bitset& rhs) noexcept; // constexpr since C++23
bitset& operator<<=(size_t pos) noexcept; // constexpr since C++23
bitset& operator>>=(size_t pos) noexcept; // constexpr since C++23
bitset& set() noexcept; // constexpr since C++23
bitset& set(size_t pos, bool val = true); // constexpr since C++23
bitset& reset() noexcept; // constexpr since C++23
bitset& reset(size_t pos); // constexpr since C++23
bitset operator~() const noexcept; // constexpr since C++23
bitset& flip() noexcept; // constexpr since C++23
bitset& flip(size_t pos); // constexpr since C++23
// element access:
constexpr bool operator[](size_t pos) const;
reference operator[](size_t pos); // constexpr since C++23
unsigned long to_ulong() const; // constexpr since C++23
unsigned long long to_ullong() const; // constexpr since C++23
template <class charT, class traits, class Allocator> // constexpr since C++23
basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
template <class charT, class traits> // constexpr since C++23
basic_string<charT, traits, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
template <class charT> // constexpr since C++23
basic_string<charT, char_traits<charT>, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
basic_string<char, char_traits<char>, allocator<char> > to_string(char zero = '0', char one = '1') const; // constexpr since C++23
size_t count() const noexcept; // constexpr since C++23
constexpr size_t size() const noexcept; // constexpr since C++23
bool operator==(const bitset& rhs) const noexcept; // constexpr since C++23
bool operator!=(const bitset& rhs) const noexcept; // removed in C++20
bool test(size_t pos) const; // constexpr since C++23
bool all() const noexcept; // constexpr since C++23
bool any() const noexcept; // constexpr since C++23
bool none() const noexcept; // constexpr since C++23
bitset<N> operator<<(size_t pos) const noexcept; // constexpr since C++23
bitset<N> operator>>(size_t pos) const noexcept; // constexpr since C++23
};
// 23.3.5.3 bitset operators:
template <size_t N>
bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept; // constexpr since C++23
template <size_t N>
bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept; // constexpr since C++23
template <size_t N>
bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept; // constexpr since C++23
template <class charT, class traits, size_t N>
basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
template <class charT, class traits, size_t N>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
template <size_t N> struct hash<std::bitset<N>>;
} // std
*/
// clang-format on
#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
# include <__cxx03/bitset>
#else
# include <__algorithm/copy.h>
# include <__algorithm/copy_backward.h>
# include <__algorithm/count.h>
# include <__algorithm/equal.h>
# include <__algorithm/fill.h>
# include <__algorithm/fill_n.h>
# include <__algorithm/find.h>
# include <__algorithm/min.h>
# include <__assert>
# include <__bit/countr.h>
# include <__bit/invert_if.h>
# include <__bit_reference>
# include <__config>
# include <__cstddef/ptrdiff_t.h>
# include <__cstddef/size_t.h>
# include <__functional/hash.h>
# include <__functional/identity.h>
# include <__functional/unary_function.h>
# include <__type_traits/enable_if.h>
# include <__type_traits/integral_constant.h>
# include <__type_traits/is_char_like_type.h>
# include <__utility/integer_sequence.h>
# include <climits>
# include <stdexcept>
# include <string_view>
# include <version>
// standard-mandated includes
// [bitset.syn]
# include <iosfwd>
# include <string>
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_PUSH_MACROS
# include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <size_t _N_words, size_t _Size>
class __bitset;
template <size_t _N_words, size_t _Size>
struct __has_storage_type<__bitset<_N_words, _Size> > {
static const bool value = true;
};
template <size_t _N_words, size_t _Size>
class __bitset {
public:
typedef size_t __storage_type;
protected:
typedef __bitset __self;
typedef __storage_type* __storage_pointer;
typedef const __storage_type* __const_storage_pointer;
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
friend class __bit_reference<__bitset>;
friend class __bit_const_reference<__bitset>;
friend class __bit_iterator<__bitset, false>;
friend class __bit_iterator<__bitset, true>;
friend struct __bit_array<__bitset>;
__storage_type __first_[_N_words];
typedef __bit_reference<__bitset> reference;
typedef __bit_const_reference<__bitset> __const_reference;
typedef __bit_iterator<__bitset, false> __iterator;
typedef __bit_iterator<__bitset, true> __const_iterator;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference __make_ref(size_t __pos) _NOEXCEPT {
return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference __make_ref(size_t __pos) const _NOEXCEPT {
return __const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t __pos) _NOEXCEPT {
return __iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t __pos) const _NOEXCEPT {
return __const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset& __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator|=(const __bitset& __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator^=(const __bitset& __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
if _LIBCPP_CONSTEXPR (_Size > sizeof(unsigned long) * CHAR_BIT) {
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
std::__throw_overflow_error("__bitset<_N_words, _Size>::to_ulong overflow error");
}
static_assert(sizeof(__storage_type) >= sizeof(unsigned long),
"libc++ only supports platforms where sizeof(size_t) >= sizeof(unsigned long), such as 32-bit and "
"64-bit platforms. If you're interested in supporting a platform where that is not the case, please "
"contact the libc++ developers.");
return static_cast<unsigned long>(__first_[0]);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
// Check for overflow if _Size does not fit in unsigned long long
if _LIBCPP_CONSTEXPR (_Size > sizeof(unsigned long long) * CHAR_BIT) {
if (auto __e = __make_iter(_Size);
std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
std::__throw_overflow_error("__bitset<_N_words, _Size>::to_ullong overflow error");
}
// At this point, the effective bitset size (excluding leading zeros) fits in unsigned long long
if _LIBCPP_CONSTEXPR (sizeof(__storage_type) >= sizeof(unsigned long long)) {
// If __storage_type is at least as large as unsigned long long, the result spans only one word
return static_cast<unsigned long long>(__first_[0]);
} else {
// Otherwise, the result spans multiple words which are concatenated
const size_t __ull_words = (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1;
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
for (size_t __i = 1; __i < __n_words; ++__i)
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
return __r;
}
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return !__scan_bits(__bit_not()); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
return __scan_bits(std::__identity());
}
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
template <bool _Sparse, class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
__to_string(_CharT __zero, _CharT __one) const {
basic_string<_CharT, _Traits, _Allocator> __r(_Size, _Sparse ? __zero : __one);
for (size_t __i = 0, __bits = 0; __i < _N_words; ++__i, __bits += __bits_per_word) {
__storage_type __word = std::__invert_if<!_Sparse>(__first_[__i]);
if (__i == _N_words - 1 && _Size - __bits < __bits_per_word)
__word &= (__storage_type(1) << (_Size - __bits)) - 1;
for (; __word; __word &= (__word - 1))
__r[_Size - 1 - (__bits + std::__countr_zero(__word))] = _Sparse ? __one : __zero;
}
return __r;
}
private:
struct __bit_not {
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp operator()(const _Tp& __x) const _NOEXCEPT {
return ~__x;
}
};
template <typename _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __scan_bits(_Proj __proj) const _NOEXCEPT {
size_t __n = _Size;
__const_storage_pointer __p = __first_;
// do middle whole words
for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
if (__proj(*__p))
return true;
// do last partial word
if (__n > 0) {
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
if (__proj(*__p) & __m)
return true;
}
return false;
}
# ifdef _LIBCPP_CXX03_LANG
void __init(unsigned long long __v, false_type) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
# else
template <size_t... _Indices>
_LIBCPP_HIDE_FROM_ABI constexpr __bitset(unsigned long long __v, __index_sequence<_Indices...>) _NOEXCEPT
: __first_{static_cast<__storage_type>(__v >> (_Indices * __bits_per_word))...} {}
# endif // _LIBCPP_CXX03_LANG
};
template <size_t _N_words, size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset() _NOEXCEPT
# ifndef _LIBCPP_CXX03_LANG
: __first_{0}
# endif
{
# ifdef _LIBCPP_CXX03_LANG
std::fill_n(__first_, _N_words, __storage_type(0));
# endif
}
# ifdef _LIBCPP_CXX03_LANG
template <size_t _N_words, size_t _Size>
void __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT {
const size_t __n_words = std::min((sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1, _N_words);
for (size_t __i = 0; __i < __n_words; ++__i, __v >>= __bits_per_word)
__first_[__i] = static_cast<__storage_type>(__v);
std::fill(__first_ + __n_words, __first_ + _N_words, __storage_type(0));
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT {
__first_[0] = __v;
std::fill(__first_ + 1, __first_ + _N_words, __storage_type(0));
}
# endif // _LIBCPP_CXX03_LANG
template <size_t _N_words, size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
# ifndef _LIBCPP_CXX03_LANG
: __bitset(__v,
__make_index_sequence<(_N_words < (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1)
? _N_words
: (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1>())
# endif
{
# ifdef _LIBCPP_CXX03_LANG
__init(__v, _BoolConstant<sizeof(unsigned long long) <= sizeof(__storage_type)>());
# endif
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT {
for (size_t __i = 0; __i < _N_words; ++__i)
__first_[__i] &= __v.__first_[__i];
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT {
for (size_t __i = 0; __i < _N_words; ++__i)
__first_[__i] |= __v.__first_[__i];
}
template <size_t _N_words, size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT {
for (size_t __i = 0; __i < _N_words; ++__i)
__first_[__i] ^= __v.__first_[__i];
}
template <size_t _N_words, size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Size>::flip() _NOEXCEPT {
// do middle whole words
size_t __n = _Size;
__storage_pointer __p = __first_;
for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
*__p = ~*__p;
// do last partial word
// Ensure trailing padding bits are zeroed as part of the ABI for consistent hashing behavior. std::hash<bitset>
// assumes trailing bits are zeroed; otherwise, identical bitsets could hash differently.
if (__n > 0)
*__p ^= (__storage_type(1) << __n) - 1;
}
template <size_t _N_words, size_t _Size>
inline size_t __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT {
size_t __h = 0;
for (size_t __i = 0; __i < _N_words; ++__i)
__h ^= __first_[__i];
return __h;
}
template <size_t _Size>
class __bitset<1, _Size> {
public:
typedef size_t __storage_type;
protected:
typedef __bitset __self;
typedef __storage_type* __storage_pointer;
typedef const __storage_type* __const_storage_pointer;
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
friend class __bit_reference<__bitset>;
friend class __bit_const_reference<__bitset>;
friend class __bit_iterator<__bitset, false>;
friend class __bit_iterator<__bitset, true>;
friend struct __bit_array<__bitset>;
__storage_type __first_;
typedef __bit_reference<__bitset> reference;
typedef __bit_const_reference<__bitset> __const_reference;
typedef __bit_iterator<__bitset, false> __iterator;
typedef __bit_iterator<__bitset, true> __const_iterator;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference __make_ref(size_t __pos) _NOEXCEPT {
return reference(&__first_, __storage_type(1) << __pos);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference __make_ref(size_t __pos) const _NOEXCEPT {
return __const_reference(&__first_, __storage_type(1) << __pos);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t __pos) _NOEXCEPT {
// Allow the == case to accommodate the past-the-end iterator.
_LIBCPP_ASSERT_INTERNAL(__pos <= __bits_per_word, "Out of bounds access in the single-word bitset implementation.");
return __pos != __bits_per_word ? __iterator(&__first_, __pos) : __iterator(&__first_ + 1, 0);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t __pos) const _NOEXCEPT {
// Allow the == case to accommodate the past-the-end iterator.
_LIBCPP_ASSERT_INTERNAL(__pos <= __bits_per_word, "Out of bounds access in the single-word bitset implementation.");
return __pos != __bits_per_word ? __const_iterator(&__first_, __pos) : __const_iterator(&__first_ + 1, 0);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset& __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator|=(const __bitset& __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator^=(const __bitset& __v) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
if _LIBCPP_CONSTEXPR (_Size > sizeof(unsigned long) * CHAR_BIT) {
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
__throw_overflow_error("__bitset<1, _Size>::to_ulong overflow error");
}
return static_cast<unsigned long>(__first_);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
// If _Size exceeds the size of unsigned long long, check for overflow
if _LIBCPP_CONSTEXPR (_Size > sizeof(unsigned long long) * CHAR_BIT) {
if (auto __e = __make_iter(_Size);
std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
__throw_overflow_error("__bitset<1, _Size>::to_ullong overflow error");
}
// If _Size fits or no overflow, directly cast to unsigned long long
return static_cast<unsigned long long>(__first_);
}
template <bool _Sparse, class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
__to_string(_CharT __zero, _CharT __one) const {
basic_string<_CharT, _Traits, _Allocator> __r(_Size, _Sparse ? __zero : __one);
__storage_type __word = std::__invert_if<!_Sparse>(__first_);
if (_Size < __bits_per_word)
__word &= (__storage_type(1) << _Size) - 1;
for (; __word; __word &= (__word - 1)) {
size_t __pos = std::__countr_zero(__word);
__r[_Size - 1 - __pos] = _Sparse ? __one : __zero;
}
return __r;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
};
template <size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0) {}
template <size_t _Size>
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
// TODO: We must refer to __bits_per_word in order to work around an issue with the GDB pretty-printers.
// Without it, the pretty-printers complain about a missing __bits_per_word member. This needs to
// be investigated further.
: __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v) : static_cast<__storage_type>(__v)) {}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT {
__first_ &= __v.__first_;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT {
__first_ |= __v.__first_;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT {
__first_ ^= __v.__first_;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Size>::flip() _NOEXCEPT {
__first_ ^= ~__storage_type(0) >> (__bits_per_word - _Size);
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<1, _Size>::all() const _NOEXCEPT {
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
return !(~__first_ & __m);
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<1, _Size>::any() const _NOEXCEPT {
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
return __first_ & __m;
}
template <size_t _Size>
inline size_t __bitset<1, _Size>::__hash_code() const _NOEXCEPT {
return __first_;
}
template <>
class __bitset<0, 0> {
public:
typedef size_t __storage_type;
protected:
typedef __bitset __self;
typedef __storage_type* __storage_pointer;
typedef const __storage_type* __const_storage_pointer;
static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
friend class __bit_reference<__bitset>;
friend class __bit_const_reference<__bitset>;
friend class __bit_iterator<__bitset, false>;
friend class __bit_iterator<__bitset, true>;
friend struct __bit_array<__bitset>;
typedef __bit_reference<__bitset> reference;
typedef __bit_const_reference<__bitset> __const_reference;
typedef __bit_iterator<__bitset, false> __iterator;
typedef __bit_iterator<__bitset, true> __const_iterator;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference __make_ref(size_t) _NOEXCEPT {
return reference(nullptr, 1);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference __make_ref(size_t) const _NOEXCEPT {
return __const_reference(nullptr, 1);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t) _NOEXCEPT {
return __iterator(nullptr, 0);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t) const _NOEXCEPT {
return __const_iterator(nullptr, 0);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset&) _NOEXCEPT {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator|=(const __bitset&) _NOEXCEPT {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator^=(const __bitset&) _NOEXCEPT {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0; }
template <bool _Sparse, class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
__to_string(_CharT, _CharT) const {
return basic_string<_CharT, _Traits, _Allocator>();
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return true; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return false; }
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT { return 0; }
};
inline _LIBCPP_CONSTEXPR __bitset<0, 0>::__bitset() _NOEXCEPT {}
inline _LIBCPP_CONSTEXPR __bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT {}
template <size_t _Size>
class bitset;
template <size_t _Size>
struct hash<bitset<_Size> >;
template <size_t _Size>
class bitset : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size> {
public:
static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1;
typedef __bitset<__n_words, _Size> __base;
typedef typename __base::reference reference;
typedef typename __base::__const_reference __const_reference;
// 23.3.5.1 constructors:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT
: __base(sizeof(unsigned long long) * CHAR_BIT <= _Size ? __v : __v & ((1ULL << _Size) - 1)) {}
template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
const _CharT* __str,
size_t __n = basic_string<_CharT>::npos,
_CharT __zero = _CharT('0'),
_CharT __one = _CharT('1')) {
if (__n == basic_string<_CharT>::npos)
__init_from_string_view(basic_string_view<_CharT>(__str), __zero, __one);
else
__init_from_string_view(basic_string_view<_CharT>(__str, __n), __zero, __one);
}
# if _LIBCPP_STD_VER >= 26
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI constexpr explicit bitset(
basic_string_view<_CharT, _Traits> __str,
typename basic_string_view<_CharT, _Traits>::size_type __pos = 0,
typename basic_string_view<_CharT, _Traits>::size_type __n = basic_string_view<_CharT, _Traits>::npos,
_CharT __zero = _CharT('0'),
_CharT __one = _CharT('1')) {
if (__pos > __str.size())
std::__throw_out_of_range("bitset string pos out of range");
size_t __rlen = std::min(__n, __str.size() - __pos);
__init_from_string_view(basic_string_view<_CharT, _Traits>(__str.data() + __pos, __rlen), __zero, __one);
}
# endif
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
const basic_string<_CharT, _Traits, _Allocator>& __str,
typename basic_string<_CharT, _Traits, _Allocator>::size_type __pos = 0,
typename basic_string<_CharT, _Traits, _Allocator>::size_type __n =
basic_string<_CharT, _Traits, _Allocator>::npos,
_CharT __zero = _CharT('0'),
_CharT __one = _CharT('1')) {
if (__pos > __str.size())
std::__throw_out_of_range("bitset string pos out of range");
size_t __rlen = std::min(__n, __str.size() - __pos);
__init_from_string_view(basic_string_view<_CharT, _Traits>(__str.data() + __pos, __rlen), __zero, __one);
}
// 23.3.5.2 bitset operations:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& operator&=(const bitset& __rhs) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& operator|=(const bitset& __rhs) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& operator^=(const bitset& __rhs) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& operator<<=(size_t __pos) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& operator>>=(size_t __pos) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& set() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& set(size_t __pos, bool __val = true);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& reset(size_t __pos);
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator~() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip() _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset& flip(size_t __pos);
// element access:
# ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
# else
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __const_reference operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
# endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return __base::to_ulong(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
return __base::to_ullong();
}
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> >
to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> >
to_string(char __zero = '0', char __one = '1') const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t count() const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT { return _Size; }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const bitset& __rhs) const _NOEXCEPT;
# if _LIBCPP_STD_VER <= 17
_LIBCPP_HIDE_FROM_ABI bool operator!=(const bitset& __rhs) const _NOEXCEPT;
# endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return __base::all(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return __base::any(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
private:
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
__init_from_string_view(basic_string_view<_CharT, _Traits> __str, _CharT __zero, _CharT __one) {
for (size_t __i = 0; __i < __str.size(); ++__i)
if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
std::__throw_invalid_argument("bitset string ctor has invalid argument");
size_t __mp = std::min(__str.size(), _Size);
size_t __i = 0;
for (; __i < __mp; ++__i) {
_CharT __c = __str[__mp - 1 - __i];
(*this)[__i] = _Traits::eq(__c, __one);
}
}
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT { return __base::__hash_code(); }
friend struct hash<bitset>;
};
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>&
bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT {
__base::operator&=(__rhs);
return *this;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>&
bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT {
__base::operator|=(__rhs);
return *this;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>&
bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT {
__base::operator^=(__rhs);
return *this;
}
template <size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT {
__pos = std::min(__pos, _Size);
std::copy_backward(__base::__make_iter(0), __base::__make_iter(_Size - __pos), __base::__make_iter(_Size));
std::fill_n(__base::__make_iter(0), __pos, false);
return *this;
}
template <size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT {
__pos = std::min(__pos, _Size);
std::copy(__base::__make_iter(__pos), __base::__make_iter(_Size), __base::__make_iter(0));
std::fill_n(__base::__make_iter(_Size - __pos), __pos, false);
return *this;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::set() _NOEXCEPT {
std::fill_n(__base::__make_iter(0), _Size, true);
return *this;
}
template <size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::set(size_t __pos, bool __val) {
if (__pos >= _Size)
std::__throw_out_of_range("bitset set argument out of range");
(*this)[__pos] = __val;
return *this;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::reset() _NOEXCEPT {
std::fill_n(__base::__make_iter(0), _Size, false);
return *this;
}
template <size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::reset(size_t __pos) {
if (__pos >= _Size)
std::__throw_out_of_range("bitset reset argument out of range");
(*this)[__pos] = false;
return *this;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size> bitset<_Size>::operator~() const _NOEXCEPT {
bitset __x(*this);
__x.flip();
return __x;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::flip() _NOEXCEPT {
__base::flip();
return *this;
}
template <size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>::flip(size_t __pos) {
if (__pos >= _Size)
std::__throw_out_of_range("bitset flip argument out of range");
reference __r = __base::__make_ref(__pos);
__r = ~__r;
return *this;
}
template <size_t _Size>
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
bitset<_Size>::to_string(_CharT __zero, _CharT __one) const {
bool __sparse = size_t(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true)) < _Size / 2;
if (__sparse)
return __base::template __to_string<true, _CharT, _Traits, _Allocator>(__zero, __one);
else
return __base::template __to_string<false, _CharT, _Traits, _Allocator>(__zero, __one);
}
template <size_t _Size>
template <class _CharT, class _Traits>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, allocator<_CharT> >
bitset<_Size>::to_string(_CharT __zero, _CharT __one) const {
return to_string<_CharT, _Traits, allocator<_CharT> >(__zero, __one);
}
template <size_t _Size>
template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
bitset<_Size>::to_string(_CharT __zero, _CharT __one) const {
return to_string<_CharT, char_traits<_CharT>, allocator<_CharT> >(__zero, __one);
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<char, char_traits<char>, allocator<char> >
bitset<_Size>::to_string(char __zero, char __one) const {
return to_string<char, char_traits<char>, allocator<char> >(__zero, __one);
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t bitset<_Size>::count() const _NOEXCEPT {
# if defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
if constexpr (_Size == 0) {
return 0;
} else if constexpr (_Size <= __base::__bits_per_word) {
return __builtin_popcountg(static_cast<unsigned _BitInt(_Size)>(__base::__first_));
} else
# endif
{
return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
}
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool
bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT {
return std::equal(__base::__make_iter(0), __base::__make_iter(_Size), __rhs.__make_iter(0));
}
# if _LIBCPP_STD_VER <= 17
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI bool bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT {
return !(*this == __rhs);
}
# endif
template <size_t _Size>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::test(size_t __pos) const {
if (__pos >= _Size)
std::__throw_out_of_range("bitset test argument out of range");
return (*this)[__pos];
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT {
bitset __r = *this;
__r <<= __pos;
return __r;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT {
bitset __r = *this;
__r >>= __pos;
return __r;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
bitset<_Size> __r = __x;
__r &= __y;
return __r;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
bitset<_Size> __r = __x;
__r |= __y;
return __r;
}
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT {
bitset<_Size> __r = __x;
__r ^= __y;
return __r;
}
template <size_t _Size>
struct hash<bitset<_Size> > : public __unary_function<bitset<_Size>, size_t> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT { return __bs.__hash_code(); }
};
template <class _CharT, class _Traits, size_t _Size>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x);
template <class _CharT, class _Traits, size_t _Size>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x);
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <concepts>
# include <cstdlib>
# include <optional>
# include <type_traits>
# endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#endif // _LIBCPP_BITSET