зеркало из https://github.com/microsoft/STL.git
Implement P2417R2 More `constexpr` `bitset` (#2972)
Co-authored-by: Daniel Marshall <xandan@gmail.com> Co-authored-by: A. Jiang <de34@live.cn> Co-authored-by: Casey Carter <cartec69@gmail.com> Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Родитель
9567121b15
Коммит
b8371b04df
124
stl/inc/bitset
124
stl/inc/bitset
|
@ -32,41 +32,41 @@ public:
|
|||
friend bitset<_Bits>;
|
||||
|
||||
public:
|
||||
~reference() noexcept {} // TRANSITION, ABI
|
||||
_CONSTEXPR23 ~reference() noexcept {} // TRANSITION, ABI
|
||||
|
||||
reference& operator=(bool _Val) noexcept {
|
||||
_CONSTEXPR23 reference& operator=(const bool _Val) noexcept {
|
||||
_Pbitset->_Set_unchecked(_Mypos, _Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference& operator=(const reference& _Bitref) noexcept {
|
||||
_CONSTEXPR23 reference& operator=(const reference& _Bitref) noexcept {
|
||||
_Pbitset->_Set_unchecked(_Mypos, static_cast<bool>(_Bitref));
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference& flip() noexcept {
|
||||
_CONSTEXPR23 reference& flip() noexcept {
|
||||
_Pbitset->_Flip_unchecked(_Mypos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_NODISCARD bool operator~() const noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bool operator~() const noexcept {
|
||||
return !_Pbitset->_Subscript(_Mypos);
|
||||
}
|
||||
|
||||
operator bool() const noexcept {
|
||||
_CONSTEXPR23 operator bool() const noexcept {
|
||||
return _Pbitset->_Subscript(_Mypos);
|
||||
}
|
||||
|
||||
private:
|
||||
reference() noexcept : _Pbitset(nullptr), _Mypos(0) {}
|
||||
_CONSTEXPR23 reference() noexcept : _Pbitset(nullptr), _Mypos(0) {}
|
||||
|
||||
reference(bitset<_Bits>& _Bitset, size_t _Pos) : _Pbitset(&_Bitset), _Mypos(_Pos) {}
|
||||
_CONSTEXPR23 reference(bitset<_Bits>& _Bitset, const size_t _Pos) noexcept : _Pbitset(&_Bitset), _Mypos(_Pos) {}
|
||||
|
||||
bitset<_Bits>* _Pbitset;
|
||||
size_t _Mypos; // position of element in bitset
|
||||
};
|
||||
|
||||
static void _Validate(size_t _Pos) { // verify that _Pos is within bounds
|
||||
static _CONSTEXPR23 void _Validate(const size_t _Pos) noexcept { // verify that _Pos is within bounds
|
||||
#if _ITERATOR_DEBUG_LEVEL == 0
|
||||
(void) _Pos;
|
||||
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 ^^^ // vvv _ITERATOR_DEBUG_LEVEL != 0 vvv
|
||||
|
@ -87,7 +87,7 @@ public:
|
|||
#endif // _ITERATOR_DEBUG_LEVEL == 0
|
||||
}
|
||||
|
||||
_NODISCARD reference operator[](size_t _Pos) {
|
||||
_NODISCARD _CONSTEXPR23 reference operator[](const size_t _Pos) noexcept /* strengthened */ {
|
||||
_Validate(_Pos);
|
||||
return reference(*this, _Pos);
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
constexpr bitset(unsigned long long _Val) noexcept : _Array{static_cast<_Ty>(_Need_mask ? _Val & _Mask : _Val)} {}
|
||||
|
||||
template <class _Traits, class _Elem>
|
||||
void _Construct(const _Elem* const _Ptr, size_t _Count, const _Elem _Elem0, const _Elem _Elem1) {
|
||||
_CONSTEXPR23 void _Construct(const _Elem* const _Ptr, size_t _Count, const _Elem _Elem0, const _Elem _Elem1) {
|
||||
if (_Count > _Bits) {
|
||||
for (size_t _Idx = _Bits; _Idx < _Count; ++_Idx) {
|
||||
const auto _Ch = _Ptr[_Idx];
|
||||
|
@ -146,7 +146,7 @@ public:
|
|||
}
|
||||
|
||||
template <class _Elem, class _Traits, class _Alloc>
|
||||
explicit bitset(const basic_string<_Elem, _Traits, _Alloc>& _Str,
|
||||
_CONSTEXPR23 explicit bitset(const basic_string<_Elem, _Traits, _Alloc>& _Str,
|
||||
typename basic_string<_Elem, _Traits, _Alloc>::size_type _Pos = 0,
|
||||
typename basic_string<_Elem, _Traits, _Alloc>::size_type _Count = basic_string<_Elem, _Traits, _Alloc>::npos,
|
||||
_Elem _Elem0 = static_cast<_Elem>('0'), _Elem _Elem1 = static_cast<_Elem>('1')) {
|
||||
|
@ -163,7 +163,8 @@ public:
|
|||
}
|
||||
|
||||
template <class _Elem>
|
||||
explicit bitset(const _Elem* _Ntcts, typename basic_string<_Elem>::size_type _Count = basic_string<_Elem>::npos,
|
||||
_CONSTEXPR23 explicit bitset(const _Elem* _Ntcts,
|
||||
typename basic_string<_Elem>::size_type _Count = basic_string<_Elem>::npos,
|
||||
_Elem _Elem0 = static_cast<_Elem>('0'), _Elem _Elem1 = static_cast<_Elem>('1')) {
|
||||
if (_Count == basic_string<_Elem>::npos) {
|
||||
_Count = char_traits<_Elem>::length(_Ntcts);
|
||||
|
@ -172,7 +173,7 @@ public:
|
|||
_Construct<char_traits<_Elem>>(_Ntcts, _Count, _Elem0, _Elem1);
|
||||
}
|
||||
|
||||
bitset& operator&=(const bitset& _Right) noexcept {
|
||||
_CONSTEXPR23 bitset& operator&=(const bitset& _Right) noexcept {
|
||||
for (size_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
_Array[_Wpos] &= _Right._Array[_Wpos];
|
||||
}
|
||||
|
@ -180,7 +181,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& operator|=(const bitset& _Right) noexcept {
|
||||
_CONSTEXPR23 bitset& operator|=(const bitset& _Right) noexcept {
|
||||
for (size_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
_Array[_Wpos] |= _Right._Array[_Wpos];
|
||||
}
|
||||
|
@ -188,7 +189,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& operator^=(const bitset& _Right) noexcept {
|
||||
_CONSTEXPR23 bitset& operator^=(const bitset& _Right) noexcept {
|
||||
for (size_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
_Array[_Wpos] ^= _Right._Array[_Wpos];
|
||||
}
|
||||
|
@ -196,7 +197,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& operator<<=(size_t _Pos) noexcept { // shift left by _Pos, first by words then by bits
|
||||
_CONSTEXPR23 bitset& operator<<=(size_t _Pos) noexcept { // shift left by _Pos, first by words then by bits
|
||||
const auto _Wordshift = static_cast<ptrdiff_t>(_Pos / _Bitsperword);
|
||||
if (_Wordshift != 0) {
|
||||
for (ptrdiff_t _Wpos = _Words; 0 <= _Wpos; --_Wpos) {
|
||||
|
@ -215,7 +216,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& operator>>=(size_t _Pos) noexcept { // shift right by _Pos, first by words then by bits
|
||||
_CONSTEXPR23 bitset& operator>>=(size_t _Pos) noexcept { // shift right by _Pos, first by words then by bits
|
||||
const auto _Wordshift = static_cast<ptrdiff_t>(_Pos / _Bitsperword);
|
||||
if (_Wordshift != 0) {
|
||||
for (ptrdiff_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
|
@ -233,13 +234,22 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& set() noexcept { // set all bits true
|
||||
_CSTD memset(&_Array, 0xFF, sizeof(_Array));
|
||||
_CONSTEXPR23 bitset& set() noexcept { // set all bits true
|
||||
#if _HAS_CXX23
|
||||
if (_STD is_constant_evaluated()) {
|
||||
for (auto& _El : _Array) {
|
||||
_El = static_cast<_Ty>(-1);
|
||||
}
|
||||
} else
|
||||
#endif // _HAS_CXX23
|
||||
{
|
||||
_CSTD memset(&_Array, 0xFF, sizeof(_Array));
|
||||
}
|
||||
_Trim();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset& set(size_t _Pos, bool _Val = true) { // set bit at _Pos to _Val
|
||||
_CONSTEXPR23 bitset& set(const size_t _Pos, bool _Val = true) { // set bit at _Pos to _Val
|
||||
if (_Bits <= _Pos) {
|
||||
_Xran(); // _Pos off end
|
||||
}
|
||||
|
@ -247,22 +257,31 @@ public:
|
|||
return _Set_unchecked(_Pos, _Val);
|
||||
}
|
||||
|
||||
bitset& reset() noexcept { // set all bits false
|
||||
_CSTD memset(&_Array, 0, sizeof(_Array));
|
||||
_CONSTEXPR23 bitset& reset() noexcept { // set all bits false
|
||||
#if _HAS_CXX23
|
||||
if (_STD is_constant_evaluated()) {
|
||||
for (auto& _El : _Array) {
|
||||
_El = 0;
|
||||
}
|
||||
} else
|
||||
#endif // _HAS_CXX23
|
||||
{
|
||||
_CSTD memset(&_Array, 0, sizeof(_Array));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bitset& reset(size_t _Pos) { // set bit at _Pos to false
|
||||
_CONSTEXPR23 bitset& reset(const size_t _Pos) { // set bit at _Pos to false
|
||||
return set(_Pos, false);
|
||||
}
|
||||
|
||||
_NODISCARD bitset operator~() const noexcept { // flip all bits
|
||||
_NODISCARD _CONSTEXPR23 bitset operator~() const noexcept { // flip all bits
|
||||
bitset _Tmp = *this;
|
||||
_Tmp.flip();
|
||||
return _Tmp;
|
||||
}
|
||||
|
||||
bitset& flip() noexcept { // flip all bits
|
||||
_CONSTEXPR23 bitset& flip() noexcept { // flip all bits
|
||||
for (size_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
_Array[_Wpos] = ~_Array[_Wpos];
|
||||
}
|
||||
|
@ -271,7 +290,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& flip(size_t _Pos) { // flip bit at _Pos
|
||||
_CONSTEXPR23 bitset& flip(const size_t _Pos) { // flip bit at _Pos
|
||||
if (_Bits <= _Pos) {
|
||||
_Xran(); // _Pos off end
|
||||
}
|
||||
|
@ -279,7 +298,7 @@ public:
|
|||
return _Flip_unchecked(_Pos);
|
||||
}
|
||||
|
||||
_NODISCARD unsigned long to_ulong() const {
|
||||
_NODISCARD _CONSTEXPR23 unsigned long to_ulong() const noexcept(_Bits <= 32) /* strengthened */ {
|
||||
constexpr bool _Bits_zero = _Bits == 0;
|
||||
constexpr bool _Bits_small = _Bits <= 32;
|
||||
constexpr bool _Bits_large = _Bits > 64;
|
||||
|
@ -304,7 +323,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_NODISCARD unsigned long long to_ullong() const {
|
||||
_NODISCARD _CONSTEXPR23 unsigned long long to_ullong() const noexcept(_Bits <= 64) /* strengthened */ {
|
||||
constexpr bool _Bits_zero = _Bits == 0;
|
||||
constexpr bool _Bits_large = _Bits > 64;
|
||||
if constexpr (_Bits_zero) {
|
||||
|
@ -323,8 +342,8 @@ public:
|
|||
}
|
||||
|
||||
template <class _Elem = char, class _Tr = char_traits<_Elem>, class _Alloc = allocator<_Elem>>
|
||||
_NODISCARD basic_string<_Elem, _Tr, _Alloc> to_string(
|
||||
_Elem _Elem0 = static_cast<_Elem>('0'), _Elem _Elem1 = static_cast<_Elem>('1')) const {
|
||||
_NODISCARD _CONSTEXPR23 basic_string<_Elem, _Tr, _Alloc> to_string(
|
||||
const _Elem _Elem0 = static_cast<_Elem>('0'), const _Elem _Elem1 = static_cast<_Elem>('1')) const {
|
||||
// convert bitset to string
|
||||
basic_string<_Elem, _Tr, _Alloc> _Str;
|
||||
_Str.reserve(_Bits);
|
||||
|
@ -336,7 +355,7 @@ public:
|
|||
return _Str;
|
||||
}
|
||||
|
||||
_NODISCARD size_t count() const noexcept { // count number of set bits
|
||||
_NODISCARD _CONSTEXPR23 size_t count() const noexcept { // count number of set bits
|
||||
return _Select_popcount_impl<_Ty>([this](auto _Popcount_impl) {
|
||||
size_t _Val = 0;
|
||||
for (size_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
|
@ -351,8 +370,20 @@ public:
|
|||
return _Bits;
|
||||
}
|
||||
|
||||
_NODISCARD bool operator==(const bitset& _Right) const noexcept {
|
||||
return _CSTD memcmp(&_Array[0], &_Right._Array[0], sizeof(_Array)) == 0;
|
||||
_NODISCARD _CONSTEXPR23 bool operator==(const bitset& _Right) const noexcept {
|
||||
#if _HAS_CXX23
|
||||
if (_STD is_constant_evaluated()) {
|
||||
for (size_t _Index = 0; _Index <= _Words; ++_Index) {
|
||||
if (_Array[_Index] != _Right._Array[_Index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
#endif // _HAS_CXX23
|
||||
{
|
||||
return _CSTD memcmp(&_Array[0], &_Right._Array[0], sizeof(_Array)) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if !_HAS_CXX20
|
||||
|
@ -361,7 +392,7 @@ public:
|
|||
}
|
||||
#endif // !_HAS_CXX20
|
||||
|
||||
_NODISCARD bool test(size_t _Pos) const {
|
||||
_NODISCARD _CONSTEXPR23 bool test(const size_t _Pos) const {
|
||||
if (_Bits <= _Pos) {
|
||||
_Xran(); // _Pos off end
|
||||
}
|
||||
|
@ -369,7 +400,7 @@ public:
|
|||
return _Subscript(_Pos);
|
||||
}
|
||||
|
||||
_NODISCARD bool any() const noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bool any() const noexcept {
|
||||
for (size_t _Wpos = 0; _Wpos <= _Words; ++_Wpos) {
|
||||
if (_Array[_Wpos] != 0) {
|
||||
return true;
|
||||
|
@ -379,11 +410,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
_NODISCARD bool none() const noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bool none() const noexcept {
|
||||
return !any();
|
||||
}
|
||||
|
||||
_NODISCARD bool all() const noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bool all() const noexcept {
|
||||
constexpr bool _Zero_length = _Bits == 0;
|
||||
if constexpr (_Zero_length) { // must test for this, otherwise would count one full word
|
||||
return true;
|
||||
|
@ -399,13 +430,13 @@ public:
|
|||
return _No_padding || _Array[_Words] == (static_cast<_Ty>(1) << (_Bits % _Bitsperword)) - 1;
|
||||
}
|
||||
|
||||
_NODISCARD bitset operator<<(size_t _Pos) const noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bitset operator<<(const size_t _Pos) const noexcept {
|
||||
bitset _Tmp = *this;
|
||||
_Tmp <<= _Pos;
|
||||
return _Tmp;
|
||||
}
|
||||
|
||||
_NODISCARD bitset operator>>(size_t _Pos) const noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bitset operator>>(const size_t _Pos) const noexcept {
|
||||
bitset _Tmp = *this;
|
||||
_Tmp >>= _Pos;
|
||||
return _Tmp;
|
||||
|
@ -421,14 +452,15 @@ private:
|
|||
static constexpr ptrdiff_t _Bitsperword = CHAR_BIT * sizeof(_Ty);
|
||||
static constexpr ptrdiff_t _Words = _Bits == 0 ? 0 : (_Bits - 1) / _Bitsperword; // NB: number of words - 1
|
||||
|
||||
void _Trim() noexcept { // clear any trailing bits in last word
|
||||
_CONSTEXPR23 void _Trim() noexcept { // clear any trailing bits in last word
|
||||
constexpr bool _Work_to_do = _Bits == 0 || _Bits % _Bitsperword != 0;
|
||||
if constexpr (_Work_to_do) {
|
||||
_Array[_Words] &= (_Ty{1} << _Bits % _Bitsperword) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
bitset& _Set_unchecked(size_t _Pos, bool _Val) noexcept { // set bit at _Pos to _Val, no checking
|
||||
_CONSTEXPR23 bitset& _Set_unchecked(const size_t _Pos, const bool _Val) noexcept {
|
||||
// set bit at _Pos to _Val, no checking
|
||||
auto& _Selected_word = _Array[_Pos / _Bitsperword];
|
||||
const auto _Bit = _Ty{1} << _Pos % _Bitsperword;
|
||||
if (_Val) {
|
||||
|
@ -440,7 +472,7 @@ private:
|
|||
return *this;
|
||||
}
|
||||
|
||||
bitset& _Flip_unchecked(size_t _Pos) noexcept { // flip bit at _Pos, no checking
|
||||
_CONSTEXPR23 bitset& _Flip_unchecked(const size_t _Pos) noexcept { // flip bit at _Pos, no checking
|
||||
_Array[_Pos / _Bitsperword] ^= _Ty{1} << _Pos % _Bitsperword;
|
||||
return *this;
|
||||
}
|
||||
|
@ -461,21 +493,21 @@ private:
|
|||
};
|
||||
|
||||
template <size_t _Bits>
|
||||
_NODISCARD bitset<_Bits> operator&(const bitset<_Bits>& _Left, const bitset<_Bits>& _Right) noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bitset<_Bits> operator&(const bitset<_Bits>& _Left, const bitset<_Bits>& _Right) noexcept {
|
||||
bitset<_Bits> _Ans = _Left;
|
||||
_Ans &= _Right;
|
||||
return _Ans;
|
||||
}
|
||||
|
||||
template <size_t _Bits>
|
||||
_NODISCARD bitset<_Bits> operator|(const bitset<_Bits>& _Left, const bitset<_Bits>& _Right) noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bitset<_Bits> operator|(const bitset<_Bits>& _Left, const bitset<_Bits>& _Right) noexcept {
|
||||
bitset<_Bits> _Ans = _Left;
|
||||
_Ans |= _Right;
|
||||
return _Ans;
|
||||
}
|
||||
|
||||
template <size_t _Bits>
|
||||
_NODISCARD bitset<_Bits> operator^(const bitset<_Bits>& _Left, const bitset<_Bits>& _Right) noexcept {
|
||||
_NODISCARD _CONSTEXPR23 bitset<_Bits> operator^(const bitset<_Bits>& _Left, const bitset<_Bits>& _Right) noexcept {
|
||||
bitset<_Bits> _Ans = _Left;
|
||||
_Ans ^= _Right;
|
||||
return _Ans;
|
||||
|
|
|
@ -321,6 +321,7 @@
|
|||
// P2302R4 ranges::contains, ranges::contains_subrange
|
||||
// P2321R2 zip
|
||||
// (changes to pair, tuple, and vector<bool>::reference only)
|
||||
// P2417R2 More constexpr bitset
|
||||
// P2440R1 ranges::iota, ranges::shift_left, ranges::shift_right
|
||||
// P2441R2 views::join_with
|
||||
// P2442R1 Windowing Range Adaptors: views::chunk, views::slide
|
||||
|
@ -1488,6 +1489,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
|
|||
|
||||
#define __cpp_lib_associative_heterogeneous_erasure 202110L
|
||||
#define __cpp_lib_byteswap 202110L
|
||||
#define __cpp_lib_constexpr_bitset 202207L
|
||||
#define __cpp_lib_constexpr_typeinfo 202106L
|
||||
|
||||
#ifdef __cpp_lib_concepts
|
||||
|
|
|
@ -492,6 +492,7 @@ tests\P2321R2_proxy_reference
|
|||
tests\P2401R0_conditional_noexcept_for_exchange
|
||||
tests\P2408R5_ranges_iterators_to_classic_algorithms
|
||||
tests\P2415R2_owning_view
|
||||
tests\P2417R2_constexpr_bitset
|
||||
tests\P2440R1_ranges_alg_shift_left
|
||||
tests\P2440R1_ranges_alg_shift_right
|
||||
tests\P2440R1_ranges_numeric_iota
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\usual_latest_matrix.lst
|
|
@ -0,0 +1,186 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
constexpr bool test() {
|
||||
bitset<5> x50;
|
||||
const bitset<5> x51{0xf};
|
||||
const bitset<5> x52{0x15};
|
||||
|
||||
assert(x50.to_ulong() == 0x00);
|
||||
assert(x51.to_ulong() == 0x0f);
|
||||
assert(x52.to_ulong() == 0x15);
|
||||
|
||||
// bitset operators
|
||||
{
|
||||
x50 = x50 | x51;
|
||||
assert(x50.to_ulong() == 0x0f);
|
||||
x50 = x50 ^ x52;
|
||||
assert(x50.to_ulong() == 0x1a);
|
||||
x50 = x50 & x51;
|
||||
assert(x50.to_ulong() == 0x0a);
|
||||
x50 = 0x00;
|
||||
}
|
||||
|
||||
// bit reference
|
||||
{
|
||||
bitset<5>::reference ref1 = x50[2];
|
||||
assert(~ref1);
|
||||
const bitset<5>::reference ref2 = ref1;
|
||||
assert(~ref2);
|
||||
ref1 = true;
|
||||
assert(ref1);
|
||||
ref1.flip();
|
||||
assert(~ref1);
|
||||
|
||||
x50 = 0x02;
|
||||
x50[3] = x50[1];
|
||||
assert(x50.to_ulong() == 0x0a);
|
||||
x50 = 0x00;
|
||||
}
|
||||
|
||||
// [bitset.cons], constructors
|
||||
{
|
||||
bitset<5> test_str1(string{"10101"});
|
||||
bitset<5> test_str2(string{"ab10101"}, 2);
|
||||
bitset<5> test_str3(string{"ab10101cd"}, 2, 5);
|
||||
bitset<5> test_str4(string{"ab1o1o1cd"}, 2, 5, 'o');
|
||||
bitset<5> test_str5(string{"abxoxoxcd"}, 2, 5, 'o', 'x');
|
||||
assert(test_str1.to_ulong() == 0x15);
|
||||
assert(test_str2.to_ulong() == 0x15);
|
||||
assert(test_str3.to_ulong() == 0x15);
|
||||
assert(test_str4.to_ulong() == 0x15);
|
||||
assert(test_str5.to_ulong() == 0x15);
|
||||
}
|
||||
{
|
||||
bitset<5> test_ptr1("10101");
|
||||
bitset<5> test_ptr2("10101abcd", 5);
|
||||
bitset<5> test_ptr3("1o1o1abcd", 5, 'o');
|
||||
bitset<5> test_ptr4("xoxoxabcd", 5, 'o', 'x');
|
||||
assert(test_ptr1.to_ulong() == 0x15);
|
||||
assert(test_ptr2.to_ulong() == 0x15);
|
||||
assert(test_ptr3.to_ulong() == 0x15);
|
||||
assert(test_ptr4.to_ulong() == 0x15);
|
||||
}
|
||||
|
||||
// [bitset.members], bitset operations
|
||||
{
|
||||
x50 |= x51;
|
||||
assert(x50.to_ulong() == 0x0f);
|
||||
x50 ^= x52;
|
||||
assert(x50.to_ulong() == 0x1a);
|
||||
x50 &= x51;
|
||||
assert(x50.to_ulong() == 0x0a);
|
||||
x50 <<= 2;
|
||||
assert(x50.to_ulong() == 0x08);
|
||||
x50 >>= 3;
|
||||
assert(x50.to_ulong() == 0x01);
|
||||
x50.set(2);
|
||||
assert(x50.to_ulong() == 0x05);
|
||||
x50.set(0, false);
|
||||
assert(x50.to_ulong() == 0x04);
|
||||
x50.set();
|
||||
assert(x50.to_ulong() == 0x1f);
|
||||
x50.reset(3);
|
||||
assert(x50.to_ulong() == 0x17);
|
||||
x50.reset();
|
||||
assert(x50.to_ulong() == 0x00);
|
||||
assert((~x50).to_ulong() == 0x1f);
|
||||
assert(x50.to_ulong() == 0x00);
|
||||
x50.flip(2);
|
||||
assert(x50.to_ulong() == 0x04);
|
||||
x50.flip();
|
||||
assert(x50.to_ulong() == 0x1b);
|
||||
|
||||
// element access
|
||||
bitset<5>::reference ref1 = x50[1];
|
||||
|
||||
assert(x50.to_ulong() == 0x1b);
|
||||
assert(x50.to_ullong() == 0x1b);
|
||||
assert(x50.to_string() == "11011");
|
||||
assert(x50.to_string('o') == "11o11");
|
||||
assert(x50.to_string('o', 'x') == "xxoxx");
|
||||
|
||||
assert(x50.count() == 4);
|
||||
assert(x50.size() == 5);
|
||||
|
||||
assert(x50 == x50);
|
||||
assert(x50 != x51);
|
||||
|
||||
assert(x50.test(1));
|
||||
assert(!x50.test(2));
|
||||
assert(x50.any());
|
||||
assert(!x50.all());
|
||||
assert(!x50.none());
|
||||
x50.reset();
|
||||
assert(!x50.any());
|
||||
assert(!x50.all());
|
||||
assert(x50.none());
|
||||
x50.flip();
|
||||
assert(x50.any());
|
||||
assert(x50.all());
|
||||
assert(!x50.none());
|
||||
|
||||
x50 = x51;
|
||||
assert((x50 << 2).to_ulong() == 0x1c);
|
||||
assert((x50 >> 2).to_ulong() == 0x03);
|
||||
}
|
||||
|
||||
{
|
||||
// bitset<150> stores two full 64-bit words and one partial 64-bit word.
|
||||
|
||||
// Test to_ulong() and to_ullong() for large bitsets:
|
||||
bitset<150> big1{0x1234'5678};
|
||||
assert(big1.to_ulong() == 0x1234'5678);
|
||||
assert(big1.to_ullong() == 0x1234'5678);
|
||||
|
||||
bitset<150> big2{0x1234'5678'90ab'cdef};
|
||||
assert(big2.to_ullong() == 0x1234'5678'90ab'cdef);
|
||||
|
||||
// Test is_constant_evaluated() codepaths:
|
||||
assert(!big1.none());
|
||||
assert(big1.any());
|
||||
assert(!big1.all());
|
||||
|
||||
big1.set();
|
||||
assert(!big1.none());
|
||||
assert(big1.any());
|
||||
assert(big1.all());
|
||||
|
||||
big1.reset();
|
||||
assert(big1.none());
|
||||
assert(!big1.any());
|
||||
assert(!big1.all());
|
||||
|
||||
// Test operator==() by setting bits in each word:
|
||||
big2.reset();
|
||||
assert(big1 == big2);
|
||||
|
||||
big1[3] = true;
|
||||
assert(big1 != big2);
|
||||
big2[3] = true;
|
||||
assert(big1 == big2);
|
||||
|
||||
big1[70] = true;
|
||||
assert(big1 != big2);
|
||||
big2[70] = true;
|
||||
assert(big1 == big2);
|
||||
|
||||
big1[145] = true;
|
||||
assert(big1 != big2);
|
||||
big2[145] = true;
|
||||
assert(big1 == big2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
static_assert(test());
|
||||
assert(test());
|
||||
}
|
|
@ -472,6 +472,20 @@ STATIC_ASSERT(__cpp_lib_constexpr_algorithms == 201806L);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if _HAS_CXX23
|
||||
#ifndef __cpp_lib_constexpr_bitset
|
||||
#error __cpp_lib_constexpr_bitset is not defined
|
||||
#elif __cpp_lib_constexpr_bitset != 202207L
|
||||
#error __cpp_lib_constexpr_bitset is not 202207L
|
||||
#else
|
||||
STATIC_ASSERT(__cpp_lib_constexpr_bitset == 202207L);
|
||||
#endif
|
||||
#else
|
||||
#ifdef __cpp_lib_constexpr_bitset
|
||||
#error __cpp_lib_constexpr_bitset is defined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _HAS_CXX20
|
||||
#ifndef __cpp_lib_constexpr_complex
|
||||
#error __cpp_lib_constexpr_complex is not defined
|
||||
|
|
Загрузка…
Ссылка в новой задаче