// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of libcu++, the C++ Standard Library for your entire system, // 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 // SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// #ifndef _CUDA_STD_BITSET #define _CUDA_STD_BITSET #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // standard-mandated includes // [bitset.syn] #include #if defined(_LIBCUDACXX_HAS_STRING) # include #endif // _LIBCUDACXX_HAS_STRING #include _CCCL_BEGIN_NAMESPACE_CUDA_STD _CCCL_DIAG_PUSH _CCCL_DIAG_SUPPRESS_MSVC(4146) // unary minus applied to an unsigned type template struct __avoid_promotions { using __base = conditional_t<(sizeof(_Int) >= sizeof(int)), _Int, conditional_t, unsigned int, signed int>>; _CCCL_HIDE_FROM_ABI constexpr __avoid_promotions() = default; template >> _CCCL_API constexpr __avoid_promotions(_Tp __i) : __data(static_cast<_Int>(__i)) {} _CCCL_API constexpr explicit operator bool() const { return static_cast(__data); } // helper for fill_n _CCCL_API constexpr friend _Int __convert_to_integral(__avoid_promotions __self) { return __self.__data; } #define _DEFINE_UNARY(__op) \ _CCCL_API constexpr friend __avoid_promotions operator __op(__avoid_promotions __operand) \ { \ return __avoid_promotions(static_cast<_Int>(__op static_cast<__base>(__operand.__data))); \ } _DEFINE_UNARY(~) _DEFINE_UNARY(-) #undef _DEFINE_UNARY #define _DEFINE_SHIFT(__op) \ template \ _CCCL_API constexpr friend __avoid_promotions operator __op(__avoid_promotions __operand, _Tp __n) \ { \ return __avoid_promotions(static_cast<_Int>(static_cast<__base>(__operand.__data) __op static_cast<__base>(__n))); \ } \ template \ _CCCL_API constexpr friend __avoid_promotions operator __op( \ __avoid_promotions __operand, __avoid_promotions<_Tp> __n) \ { \ return __avoid_promotions( \ static_cast<_Int>(static_cast<__base>(__operand.__data) __op static_cast<__base>(__n.__data))); \ } _DEFINE_SHIFT(<<) _DEFINE_SHIFT(>>) #undef _DEFINE_SHIFT #define _DEFINE_SHIFT_ASSIGNMENT(__op) \ template \ _CCCL_API constexpr __avoid_promotions& operator __op##=(_Tp __n) \ { \ if (__n >= sizeof(_Int) * CHAR_BIT) \ { \ __data = 0; \ } \ else \ { \ __data = static_cast<_Int>(static_cast<__base>(__data) __op static_cast<__base>(__n)); \ } \ return *this; \ } _DEFINE_SHIFT_ASSIGNMENT(<<) _DEFINE_SHIFT_ASSIGNMENT(>>) #undef _DEFINE_SHIFT_ASSIGNMENT #define _DEFINE_BINARY(__op) \ _CCCL_API constexpr friend __avoid_promotions operator __op(__avoid_promotions __lhs, __avoid_promotions __rhs) \ { \ return __avoid_promotions( \ static_cast<_Int>(static_cast<__base>(__lhs.__data) __op static_cast<__base>(__rhs.__data))); \ } _DEFINE_BINARY(+) _DEFINE_BINARY(-) _DEFINE_BINARY(*) _DEFINE_BINARY(/) _DEFINE_BINARY(%) _DEFINE_BINARY(&) _DEFINE_BINARY(|) _DEFINE_BINARY(^) #undef _DEFINE_BINARY #define _DEFINE_ASSIGNMENT(__op) \ _CCCL_API constexpr __avoid_promotions& operator __op##=(__avoid_promotions __rhs) \ { \ __data = static_cast<_Int>(static_cast<__base>(__data) __op static_cast<__base>(__rhs.__data)); \ return *this; \ } _DEFINE_ASSIGNMENT(+) _DEFINE_ASSIGNMENT(-) _DEFINE_ASSIGNMENT(*) _DEFINE_ASSIGNMENT(/) _DEFINE_ASSIGNMENT(%) _DEFINE_ASSIGNMENT(&) _DEFINE_ASSIGNMENT(|) _DEFINE_ASSIGNMENT(^) #undef _DEFINE_ASSIGNMENT #define _DEFINE_COMPARISON(__op) \ _CCCL_API constexpr friend bool operator __op(__avoid_promotions __lhs, __avoid_promotions __rhs) \ { \ return static_cast<_Int>(static_cast<__base>(__lhs.__data) __op static_cast<__base>(__rhs.__data)); \ } _DEFINE_COMPARISON(<) _DEFINE_COMPARISON(>) _DEFINE_COMPARISON(==) #if _CCCL_STD_VER <= 2017 _DEFINE_COMPARISON(!=) #endif // _CCCL_STD_VER <= 2017 #undef _DEFINE_COMPARISON _Int __data; }; _CCCL_DIAG_POP static_assert(sizeof(__avoid_promotions) == sizeof(uint_least8_t)); static_assert(sizeof(__avoid_promotions) == sizeof(uint_least16_t)); static_assert(sizeof(__avoid_promotions) == sizeof(uint_least32_t)); template class __bitset { public: using difference_type = ptrdiff_t; using size_type = size_t; using __storage_type = __avoid_promotions; protected: using __self = __bitset; using __storage_pointer = __storage_type*; using __const_storage_pointer = const __storage_type*; static const unsigned __bits_per_word = static_cast(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]; using reference = __bit_reference<__bitset>; using const_reference = __bit_const_reference<__bitset>; using iterator = __bit_iterator<__bitset, false>; using const_iterator = __bit_iterator<__bitset, true>; _CCCL_API static constexpr __storage_type __clip_top_word_to_size(unsigned long long __v) { return _Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word) : static_cast<__storage_type>( (__v >> __bits_per_word) & ((__storage_type(1) << (_Size - __bits_per_word)) - 1)); } _CCCL_API constexpr __bitset() noexcept : __first_{0} {} _CCCL_API explicit constexpr __bitset(unsigned long long __v) noexcept : __first_{static_cast<__storage_type>(__v), __clip_top_word_to_size(__v)} {} _CCCL_API constexpr reference __make_ref(size_t __pos) noexcept { return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word); } _CCCL_API 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); } _CCCL_API constexpr iterator __make_iter(size_t __pos) noexcept { return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word); } _CCCL_API constexpr const_iterator __make_iter(size_t __pos) const noexcept { return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word); } _CCCL_API constexpr void operator&=(const __bitset& __v) noexcept { for (size_type __i = 0; __i < _N_words; ++__i) { __first_[__i] &= __v.__first_[__i]; } } _CCCL_API constexpr void operator|=(const __bitset& __v) noexcept { for (size_type __i = 0; __i < _N_words; ++__i) { __first_[__i] |= __v.__first_[__i]; } } _CCCL_API constexpr void operator^=(const __bitset& __v) noexcept { for (size_type __i = 0; __i < _N_words; ++__i) { __first_[__i] ^= __v.__first_[__i]; } } _CCCL_API constexpr __bitset& operator<<=(size_t __pos) noexcept { __pos = ::cuda::std::min(__pos, _Size); ::cuda::std::copy_backward(__make_iter(0), __make_iter(_Size - __pos), __make_iter(_Size)); ::cuda::std::fill_n(__make_iter(0), __pos, false); return *this; } _CCCL_API constexpr __bitset& operator>>=(size_t __pos) noexcept { __pos = ::cuda::std::min(__pos, _Size); ::cuda::std::copy(__make_iter(__pos), __make_iter(_Size), __make_iter(0)); ::cuda::std::fill_n(__make_iter(_Size - __pos), __pos, false); return *this; } _CCCL_API constexpr void flip() noexcept { // do middle whole words size_type __n = _Size; __storage_pointer __p = __first_; for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) { *__p = ~*__p; } // do last partial word if (__n > 0) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); __storage_type __b = *__p & __m; *__p &= ~__m; *__p |= ~__b & __m; } } _CCCL_API constexpr unsigned long to_ulong() const { return to_ulong(integral_constant()); } _CCCL_API constexpr unsigned long long to_ullong() const { return to_ullong(integral_constant()); } _CCCL_API constexpr bool all() const noexcept { // do middle whole words size_type __n = _Size; __const_storage_pointer __p = __first_; bool __result = true; for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) { if (~*__p) { __result = false; break; } } // do last partial word if (__n > 0 && __result) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); if (~*__p & __m) { return false; } } return __result; } _CCCL_API constexpr bool any() const noexcept { // do middle whole words size_type __n = _Size; __const_storage_pointer __p = __first_; bool __result = false; for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) { if (*__p) { __result = true; break; } } // do last partial word if (__n > 0 && !__result) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); if (*__p & __m) { return true; } } return __result; } _CCCL_API inline size_t __hash_code() const noexcept { size_t __h = 0; for (size_type __i = 0; __i < _N_words; ++__i) { __h ^= __first_[__i]; } return __h; } private: _CCCL_API constexpr unsigned long to_ulong(false_type) const { const_iterator __e = __make_iter(_Size); const_iterator __i = ::cuda::std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true); if (__i != __e) { _CCCL_THROW(::std::overflow_error, "bitset to_ulong overflow error"); } return to_ulong(true_type()); } _CCCL_API constexpr unsigned long to_ulong(true_type) const { return to_ulong(true_type(), integral_constant()); } _CCCL_API constexpr unsigned long to_ulong(true_type, false_type) const { return __first_[0].__data; } _CCCL_API constexpr unsigned long to_ulong(true_type, true_type) const { unsigned long __r = __first_[0].__data; for (size_t __i = 1; __i < sizeof(unsigned long) / sizeof(__storage_type); ++__i) { __r |= static_cast(__first_[__i].__data) << (__i * sizeof(__storage_type) * CHAR_BIT); } return __r; } _CCCL_API constexpr unsigned long long to_ullong(false_type) const { const_iterator __e = __make_iter(_Size); const_iterator __i = ::cuda::std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true); if (__i != __e) { _CCCL_THROW(::std::overflow_error, "bitset to_ullong overflow error"); } return to_ullong(true_type()); } _CCCL_API constexpr unsigned long long to_ullong(true_type) const { return to_ullong(true_type(), integral_constant()); } _CCCL_API constexpr unsigned long long to_ullong(true_type, false_type) const { return __first_[0].__data; } _CCCL_API constexpr unsigned long long to_ullong(true_type, true_type) const { unsigned long long __r = __first_[0].__data; for (size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i) { __r |= static_cast(__first_[__i].__data) << (__i * sizeof(__storage_type) * CHAR_BIT); } return __r; } }; _CCCL_DIAG_PUSH _CCCL_DIAG_SUPPRESS_MSVC(4293) // shift count negative or too big // MSVC is slightly overeager with diagnosing that here template class __bitset<1, _Size> { public: using difference_type = ptrdiff_t; using size_type = size_t; using __storage_type = __avoid_promotions>>; protected: using __self = __bitset; using __storage_pointer = __storage_type*; using __const_storage_pointer = const __storage_type*; static const unsigned __bits_per_word = static_cast(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_; using reference = __bit_reference<__bitset>; using const_reference = __bit_const_reference<__bitset>; using iterator = __bit_iterator<__bitset, false>; using const_iterator = __bit_iterator<__bitset, true>; _CCCL_API constexpr __bitset() noexcept : __first_(0) {} _CCCL_API explicit constexpr __bitset(unsigned long long __v) noexcept : __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v) : static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - __storage_type(1))) {} _CCCL_API constexpr reference __make_ref(size_t __pos) noexcept { return reference(&__first_, __storage_type(1) << __pos); } _CCCL_API constexpr const_reference __make_ref(size_t __pos) const noexcept { return const_reference(&__first_, __storage_type(1) << __pos); } _CCCL_API constexpr iterator __make_iter(size_t __pos) noexcept { return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word); } _CCCL_API constexpr const_iterator __make_iter(size_t __pos) const noexcept { return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word); } _CCCL_API constexpr void operator&=(const __bitset& __v) noexcept { __first_ &= __v.__first_; } _CCCL_API constexpr void operator|=(const __bitset& __v) noexcept { __first_ |= __v.__first_; } _CCCL_API constexpr void operator^=(const __bitset& __v) noexcept { __first_ ^= __v.__first_; } _CCCL_API constexpr void operator<<=(size_t __rhs) noexcept { __first_ <<= __rhs; __first_ &= ~__storage_type(0) >> (__bits_per_word - _Size); } _CCCL_API constexpr void operator>>=(size_t __rhs) noexcept { __first_ >>= __rhs; } _CCCL_API constexpr void flip() noexcept { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); __first_ = ~__first_; __first_ &= __m; } _CCCL_API constexpr unsigned long to_ulong() const { #if _CCCL_COMPILER(MSVC) if (static_cast(__first_.__data) != __first_.__data) { _CCCL_THROW(::std::overflow_error, "bitset to_ulong overflow error"); } return static_cast(__first_.__data); #else // ^^ _CCCL_COMPILER(MSVC) ^^ | vv !_CCCL_COMPILER(MSVC) vv return __first_.__data; #endif // !_CCCL_COMPILER(MSVC) } _CCCL_API constexpr unsigned long long to_ullong() const { return __first_.__data; } _CCCL_API constexpr bool all() const noexcept { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); return !static_cast(~__first_ & __m); } _CCCL_API constexpr bool any() const noexcept { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); return static_cast(__first_ & __m); } _CCCL_API inline size_t __hash_code() const noexcept { return __first_; } }; _CCCL_DIAG_POP template <> class __bitset<0, 0> { public: using difference_type = ptrdiff_t; using size_type = size_t; using __storage_type = __avoid_promotions; protected: using __self = __bitset; using __storage_pointer = __storage_type*; using __const_storage_pointer = const __storage_type*; static const unsigned __bits_per_word = static_cast(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>; using reference = __bit_reference<__bitset>; using const_reference = __bit_const_reference<__bitset>; using iterator = __bit_iterator<__bitset, false>; using const_iterator = __bit_iterator<__bitset, true>; _CCCL_API constexpr __bitset() noexcept {} _CCCL_API explicit constexpr __bitset(unsigned long long) noexcept {} _CCCL_API constexpr reference __make_ref(size_t) noexcept { return reference(nullptr, 1); } _CCCL_API constexpr const_reference __make_ref(size_t) const noexcept { return const_reference(nullptr, 1); } _CCCL_API constexpr iterator __make_iter(size_t) noexcept { return iterator(nullptr, 0); } _CCCL_API constexpr const_iterator __make_iter(size_t) const noexcept { return const_iterator(nullptr, 0); } _CCCL_API constexpr void operator&=(const __bitset&) noexcept {} _CCCL_API constexpr void operator|=(const __bitset&) noexcept {} _CCCL_API constexpr void operator^=(const __bitset&) noexcept {} _CCCL_API constexpr void operator<<=(size_t) noexcept {} _CCCL_API constexpr void operator>>=(size_t) noexcept {} _CCCL_API constexpr void flip() noexcept {} _CCCL_API constexpr unsigned long to_ulong() const { return 0; } _CCCL_API constexpr unsigned long long to_ullong() const { return 0; } _CCCL_API constexpr bool all() const noexcept { return true; } _CCCL_API constexpr bool any() const noexcept { return false; } _CCCL_API inline size_t __hash_code() const noexcept { return 0; } }; template class _CCCL_TYPE_VISIBILITY_DEFAULT bitset; template struct hash>; template class _CCCL_TYPE_VISIBILITY_DEFAULT bitset : private __bitset<_Size == 0 ? 0 : (_Size - 1) / 32 + 1, _Size> { public: static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / 32 + 1; using base = __bitset<__n_words, _Size>; public: using reference = typename base::reference; using const_reference = typename base::const_reference; // 23.3.5.1 constructors: _CCCL_API constexpr bitset() noexcept {} _CCCL_API constexpr bitset(unsigned long long __v) noexcept : base(__v) {} template >> _CCCL_API constexpr explicit bitset( const _CharT* __str, size_t __n = static_cast(-1), _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) { size_t __rlen = ::cuda::std::min(__n, char_traits<_CharT>::length(__str)); __init_from_cstr(__str, __rlen, __zero, __one); } template _CCCL_API 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()) { _CCCL_THROW(::std::out_of_range, "bitset string pos out of range"); } size_t __rlen = ::cuda::std::min(__n, __str.size() - __pos); __init_from_cstr(__str.data() + __pos, __rlen, __zero, __one); } #if defined(_LIBCUDACXX_HAS_STRING) template _CCCL_API 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')) { if (__pos > __str.size()) { _CCCL_THROW(::std::out_of_range, "bitset string pos out of range"); } size_t __rlen = ::cuda::std::min(__n, __str.size() - __pos); __init_from_cstr(__str.data() + __pos, __rlen, __zero, __one); } #endif // defined(_LIBCUDACXX_HAS_STRING) // 23.3.5.2 bitset operations: _CCCL_API constexpr bitset& operator&=(const bitset& __rhs) noexcept { base::operator&=(__rhs); return *this; } _CCCL_API constexpr bitset& operator|=(const bitset& __rhs) noexcept { base::operator|=(__rhs); return *this; } _CCCL_API constexpr bitset& operator^=(const bitset& __rhs) noexcept { base::operator^=(__rhs); return *this; } _CCCL_API constexpr bitset& operator<<=(size_t __rhs) noexcept { base::operator<<=(__rhs); return *this; } _CCCL_API constexpr bitset& operator>>=(size_t __rhs) noexcept { base::operator>>=(__rhs); return *this; } _CCCL_API constexpr bitset& set() noexcept { ::cuda::std::fill_n(base::__make_iter(0), _Size, true); return *this; } _CCCL_API constexpr bitset& set(size_t __pos, bool __val = true) { if (::cuda::std::cmp_greater_equal(__pos, _Size)) { _CCCL_THROW(::std::out_of_range, "bitset set argument out of range"); } (*this)[__pos] = __val; return *this; } _CCCL_API constexpr bitset& reset() noexcept { ::cuda::std::fill_n(base::__make_iter(0), _Size, false); return *this; } _CCCL_API constexpr bitset& reset(size_t __pos) { if (::cuda::std::cmp_greater_equal(__pos, _Size)) { _CCCL_THROW(::std::out_of_range, "bitset reset argument out of range"); } (*this)[__pos] = false; return *this; } _CCCL_API constexpr bitset operator~() const noexcept { bitset __x(*this); __x.flip(); return __x; } _CCCL_API constexpr bitset& flip() noexcept { base::flip(); return *this; } _CCCL_API constexpr bitset& flip(size_t __pos) { if (::cuda::std::cmp_greater_equal(__pos, _Size)) { _CCCL_THROW(::std::out_of_range, "bitset flip argument out of range"); } reference __r = base::__make_ref(__pos); __r = ~__r; return *this; } _CCCL_API constexpr const_reference operator[](size_t __p) const { return base::__make_ref(__p); } _CCCL_API constexpr reference operator[](size_t __p) { return base::__make_ref(__p); } _CCCL_API constexpr unsigned long to_ulong() const { return base::to_ulong(); } _CCCL_API constexpr unsigned long long to_ullong() const { return base::to_ullong(); } #if defined(_LIBCUDACXX_HAS_STRING) template _CCCL_API constexpr basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const { basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero); for (size_t __i = 0; __i != _Size; ++__i) { if ((*this)[__i]) { __r[_Size - 1 - __i] = __one; } } return __r; } template _CCCL_API constexpr basic_string<_CharT, _Traits, allocator<_CharT>> to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const { return to_string<_CharT, _Traits, allocator<_CharT>>(__zero, __one); } template _CCCL_API constexpr basic_string<_CharT, char_traits<_CharT>, allocator<_CharT>> to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const { return to_string<_CharT, char_traits<_CharT>, allocator<_CharT>>(__zero, __one); } _CCCL_API constexpr basic_string, allocator> to_string(char __zero = '0', char __one = '1') const { return to_string, allocator>(__zero, __one); } #endif // defined(_LIBCUDACXX_HAS_STRING) _CCCL_API constexpr size_t count() const noexcept { return static_cast(::cuda::std::count(base::__make_iter(0), base::__make_iter(_Size), true)); } _CCCL_API constexpr size_t size() const noexcept { return _Size; } _CCCL_API constexpr bool operator==(const bitset& __rhs) const noexcept { return ::cuda::std::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0)); } #if _CCCL_STD_VER <= 2017 _CCCL_API constexpr bool operator!=(const bitset& __rhs) const noexcept { return !(*this == __rhs); } #endif // _CCCL_STD_VER <= 2017 _CCCL_API constexpr bool test(size_t __pos) const { if (::cuda::std::cmp_greater_equal(__pos, _Size)) { _CCCL_THROW(::std::out_of_range, "bitset test argument out of range"); } return (*this)[__pos]; } _CCCL_API constexpr bool all() const noexcept { return base::all(); } _CCCL_API constexpr bool any() const noexcept { return base::any(); } _CCCL_API constexpr bool none() const noexcept { return !any(); } _CCCL_API constexpr bitset operator<<(size_t __pos) const noexcept { bitset __r = *this; __r <<= __pos; return __r; } _CCCL_API constexpr bitset operator>>(size_t __pos) const noexcept { bitset __r = *this; __r >>= __pos; return __r; } private: template > _CCCL_API constexpr void __init_from_cstr(const _CharT* __str, size_t __size, _CharT __zero, _CharT __one) { for (size_t __i = 0; __i < __size; ++__i) { if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one)) { _CCCL_THROW(::std::invalid_argument, "bitset string ctor has invalid argument"); } } size_t __mp = ::cuda::std::min(__size, _Size); size_t __i = 0; for (; __i < __mp; ++__i) { _CharT __c = __str[__mp - 1 - __i]; (*this)[__i] = _Traits::eq(__c, __one); } ::cuda::std::fill(base::__make_iter(__i), base::__make_iter(_Size), false); } _CCCL_API inline size_t __hash_code() const noexcept { return base::__hash_code(); } friend struct hash; }; template _CCCL_API constexpr bitset<_Size> operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) noexcept { bitset<_Size> __r = __x; __r &= __y; return __r; } template _CCCL_API constexpr bitset<_Size> operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) noexcept { bitset<_Size> __r = __x; __r |= __y; return __r; } template _CCCL_API constexpr bitset<_Size> operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) noexcept { bitset<_Size> __r = __x; __r ^= __y; return __r; } template struct _CCCL_TYPE_VISIBILITY_DEFAULT hash> : public __unary_function, size_t> { _CCCL_API inline size_t operator()(const bitset<_Size>& __bs) const noexcept { return __bs.__hash_code(); } }; template _CCCL_API inline basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x); template _CCCL_API inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x); _CCCL_END_NAMESPACE_CUDA_STD #include #endif // _CUDA_STD_BITSET