Files
project_6/cccl_upstream/libcudacxx/include/cuda/std/bitset
EngineX CI 56fd68e7dd [INFRA] Import NVIDIA/CCCL upstream as optimization reference library
CCCL (CUDA C++ Core Libraries) provides:
- CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk)
- Thrust: high-level parallel algorithms (transform_reduce, sort, scan)
- libcudacxx: CUDA C++ standard library (atomics, barriers, memory)
- cudax: experimental features (memory resources, allocators)
- Tuning policies: per-SM hardware-specific algorithm parameters

Competition optimization vectors mapped to CCCL:
- Output TPS (83% weight): warp_reduce, block_reduce, device_topk
- Input TPS (14% weight): device_scan, block_load, prefetch
- Cache TPS (3% weight): prefix caching strategy patterns
- Memory (0.9 util): pooled/cached/buddy allocators

Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only)
License: Apache-2.0
2026-07-30 09:35:51 +00:00

985 lines
31 KiB
C++

// -*- 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 <cuda/std/detail/__config>
#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 <cuda/std/__algorithm/count.h>
#include <cuda/std/__algorithm/fill.h>
#include <cuda/std/__algorithm/find.h>
#include <cuda/std/__bit/reference.h>
#include <cuda/std/__exception/exception_macros.h>
#include <cuda/std/__functional/hash.h>
#include <cuda/std/__functional/unary_function.h>
#include <cuda/std/__host_stdlib/stdexcept>
#include <cuda/std/__string/char_traits.h>
#include <cuda/std/__type_traits/is_char_like_type.h>
#include <cuda/std/__utility/cmp.h>
#include <cuda/std/climits>
#include <cuda/std/cstddef>
#include <cuda/std/string_view>
#include <cuda/std/version>
// standard-mandated includes
// [bitset.syn]
#include <cuda/std/__fwd/ios.h>
#if defined(_LIBCUDACXX_HAS_STRING)
# include <cuda/std/string>
#endif // _LIBCUDACXX_HAS_STRING
#include <cuda/std/__cccl/prologue.h>
_CCCL_BEGIN_NAMESPACE_CUDA_STD
_CCCL_DIAG_PUSH
_CCCL_DIAG_SUPPRESS_MSVC(4146) // unary minus applied to an unsigned type
template <class _Int>
struct __avoid_promotions
{
using __base =
conditional_t<(sizeof(_Int) >= sizeof(int)), _Int, conditional_t<is_unsigned_v<_Int>, unsigned int, signed int>>;
_CCCL_HIDE_FROM_ABI constexpr __avoid_promotions() = default;
template <class _Tp, typename = enable_if_t<is_integral_v<_Tp>>>
_CCCL_API constexpr __avoid_promotions(_Tp __i)
: __data(static_cast<_Int>(__i))
{}
_CCCL_API constexpr explicit operator bool() const
{
return static_cast<bool>(__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 <class _Tp> \
_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 <class _Tp> \
_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 <class _Tp> \
_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<uint_least8_t>) == sizeof(uint_least8_t));
static_assert(sizeof(__avoid_promotions<uint_least16_t>) == sizeof(uint_least16_t));
static_assert(sizeof(__avoid_promotions<uint_least32_t>) == sizeof(uint_least32_t));
template <size_t _N_words, size_t _Size>
class __bitset
{
public:
using difference_type = ptrdiff_t;
using size_type = size_t;
using __storage_type = __avoid_promotions<uint32_t>;
protected:
using __self = __bitset;
using __storage_pointer = __storage_type*;
using __const_storage_pointer = const __storage_type*;
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];
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<bool, _Size <= sizeof(unsigned long) * CHAR_BIT>());
}
_CCCL_API constexpr unsigned long long to_ullong() const
{
return to_ullong(integral_constant<bool, _Size <= sizeof(unsigned long long) * CHAR_BIT>());
}
_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<bool, sizeof(__storage_type) <= sizeof(unsigned long)>());
}
_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<unsigned long>(__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<bool, sizeof(__storage_type) <= sizeof(unsigned long long)>());
}
_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<unsigned long long>(__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 <size_t _Size>
class __bitset<1, _Size>
{
public:
using difference_type = ptrdiff_t;
using size_type = size_t;
using __storage_type =
__avoid_promotions<conditional_t<_Size <= 8, uint8_t, conditional_t<_Size <= 16, uint16_t, uint32_t>>>;
protected:
using __self = __bitset;
using __storage_pointer = __storage_type*;
using __const_storage_pointer = const __storage_type*;
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_;
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<unsigned long>(__first_.__data) != __first_.__data)
{
_CCCL_THROW(::std::overflow_error, "bitset to_ulong overflow error");
}
return static_cast<unsigned long>(__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<bool>(~__first_ & __m);
}
_CCCL_API constexpr bool any() const noexcept
{
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
return static_cast<bool>(__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<uint32_t>;
protected:
using __self = __bitset;
using __storage_pointer = __storage_type*;
using __const_storage_pointer = const __storage_type*;
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>;
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 <size_t _Size>
class _CCCL_TYPE_VISIBILITY_DEFAULT bitset;
template <size_t _Size>
struct hash<bitset<_Size>>;
template <size_t _Size>
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 <class _CharT, class = enable_if_t<__cccl_is_char_like_type_v<_CharT>>>
_CCCL_API constexpr explicit bitset(
const _CharT* __str, size_t __n = static_cast<size_t>(-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 <class _CharT, class _Traits>
_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 <class _CharT, class _Traits, class _Allocator>
_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 <class _CharT, class _Traits, class _Allocator>
_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 <class _CharT, class _Traits>
_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 <class _CharT>
_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<char, char_traits<char>, allocator<char>>
to_string(char __zero = '0', char __one = '1') const
{
return to_string<char, char_traits<char>, allocator<char>>(__zero, __one);
}
#endif // defined(_LIBCUDACXX_HAS_STRING)
_CCCL_API constexpr size_t count() const noexcept
{
return static_cast<size_t>(::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 <class _CharT, class _Traits = char_traits<_CharT>>
_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<bitset>;
};
template <size_t _Size>
_CCCL_API constexpr bitset<_Size> operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) noexcept
{
bitset<_Size> __r = __x;
__r &= __y;
return __r;
}
template <size_t _Size>
_CCCL_API constexpr bitset<_Size> operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) noexcept
{
bitset<_Size> __r = __x;
__r |= __y;
return __r;
}
template <size_t _Size>
_CCCL_API constexpr 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 _CCCL_TYPE_VISIBILITY_DEFAULT hash<bitset<_Size>> : public __unary_function<bitset<_Size>, size_t>
{
_CCCL_API inline size_t operator()(const bitset<_Size>& __bs) const noexcept
{
return __bs.__hash_code();
}
};
template <class _CharT, class _Traits, size_t _Size>
_CCCL_API inline basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x);
template <class _CharT, class _Traits, size_t _Size>
_CCCL_API inline basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x);
_CCCL_END_NAMESPACE_CUDA_STD
#include <cuda/std/__cccl/epilogue.h>
#endif // _CUDA_STD_BITSET