📄 bitset
字号:
// bitset standard header
#pragma once
#ifndef _BITSET_
#define _BITSET_
#ifndef RC_INVOKED
#include <string>
#include <xfunctional>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,3)
#pragma warning(disable: 4127)
#pragma warning(disable: 6294)
_STD_BEGIN
// TEMPLATE CLASS _Bitset_base
template<int>
struct _Bitset_base
{ // default element size
typedef _Uint32t _Ty;
};
template<>
struct _Bitset_base<8>
{ // eight-byte bitset
typedef _ULonglong _Ty;
};
// TEMPLATE CLASS bitset
template<size_t _Bits>
class bitset
: public _Bitset_base<_Bits <= 8 ? 1
: _Bits <= 16 ? 2
: _Bits <= 32 ? 4
: 8>
{ // store fixed-length sequence of Boolean elements
public:
enum {_EEN_BITS = _Bits}; // helper for expression evaluator
typedef _Bitset_base<_Bits <= 8 ? 1
: _Bits <= 16 ? 2
: _Bits <= 32 ? 4
: 8> _Mybase;
typedef typename // sic
_Mybase::_Ty _Ty;
typedef bool element_type; // retained
// CLASS reference
class reference
{ // proxy for an element
friend class bitset<_Bits>;
public:
reference& operator=(bool _Val)
{ // assign Boolean to element
_Pbitset->set(_Mypos, _Val);
return (*this);
}
reference& operator=(const reference& _Bitref)
{ // assign reference to element
_Pbitset->set(_Mypos, bool(_Bitref));
return (*this);
}
reference& flip()
{ // complement stored element
_Pbitset->flip(_Mypos);
return (*this);
}
bool operator~() const
{ // return complemented element
return (!_Pbitset->test(_Mypos));
}
operator bool() const
{ // return element
return (_Pbitset->test(_Mypos));
}
private:
reference(bitset<_Bits>& _Bitset, size_t _Pos)
: _Pbitset(&_Bitset), _Mypos(_Pos)
{ // construct from bitset reference and position
}
bitset<_Bits> *_Pbitset; // pointer to the bitset
size_t _Mypos; // position of element in bitset
};
bool at(size_t _Pos) const // retained
{ // subscript nonmutable sequence with checking
return (test(_Pos));
}
reference at(size_t _Pos) // retained
{ // subscript mutable sequence with checking
return (reference(*this, _Pos));
}
bool operator[](size_t _Pos) const
{ // subscript nonmutable sequence
return (test(_Pos));
}
reference operator[](size_t _Pos)
{ // subscript mutable sequence
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Bits <= _Pos)
_DEBUG_ERROR("bitset index outside range");
#elif _ITERATOR_DEBUG_LEVEL == 1
_SCL_SECURE_VALIDATE_RANGE(_Pos < _Bits);
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
return (reference(*this, _Pos));
}
bitset()
{ // construct with all false values
_Tidy();
}
#if _HAS_CPP0X
bitset(int _Ival)
{ // construct from bits in int
unsigned int _Val = (unsigned int)_Ival;
_Tidy();
for (size_t _Pos = 0; _Val != 0 && _Pos < _Bits; _Val >>= 1, ++_Pos)
if (_Val & 1)
set(_Pos);
}
bitset(_ULonglong _Val)
#else /* _HAS_CPP0X */
bitset(unsigned long _Val)
#endif /* _HAS_CPP0X */
{ // construct from bits in unsigned long
_Tidy();
for (size_t _Pos = 0; _Val != 0 && _Pos < _Bits; _Val >>= 1, ++_Pos)
if (_Val & 1)
set(_Pos);
}
#define _BITSET_SIZE_TYPE \
typename basic_string<_Elem, _Tr, _Alloc>::size_type
template<class _Elem,
class _Tr,
class _Alloc>
explicit bitset(const basic_string<_Elem, _Tr, _Alloc>& _Str,
_BITSET_SIZE_TYPE _Pos = 0)
{ // construct from [_Pos, ...) elements in string
_Construct(_Str, _Pos,
basic_string<_Elem, _Tr, _Alloc>::npos, (_Elem)'0', (_Elem)'1');
}
template<class _Elem,
class _Tr,
class _Alloc>
explicit bitset(const basic_string<_Elem, _Tr, _Alloc>& _Str,
_BITSET_SIZE_TYPE _Pos,
_BITSET_SIZE_TYPE _Count,
_Elem _E0 = (_Elem)'0',
_Elem _E1 = (_Elem)'1')
{ // construct from [_Pos, _Pos + _Count) elements in string
_Construct(_Str, _Pos, _Count, _E0, _E1);
}
explicit bitset(const char *_Ptr)
{ // initialize from NTBS
string _Str(_Ptr);
_Construct(_Str, 0, _Str.size(), '0', '1');
}
template<class _Elem,
class _Tr,
class _Alloc>
void _Construct(
const basic_string<_Elem, _Tr, _Alloc>& _Str,
_BITSET_SIZE_TYPE _Pos,
_BITSET_SIZE_TYPE _Count,
_Elem _E0,
_Elem _E1)
{ // initialize from [_Pos, _Pos + _Count) elements in string
typename basic_string<_Elem, _Tr, _Alloc>::size_type _Num;
if (_Str.size() < _Pos)
_Xran(); // _Pos off end
if (_Str.size() - _Pos < _Count)
_Count = _Str.size() - _Pos; // trim _Count to size
if (_Bits < _Count)
_Count = _Bits; // trim _Count to length of bitset
_Tidy();
for (_Pos += _Count, _Num = 0; _Num < _Count; ++_Num)
if (_Str[--_Pos] == _E1)
set(_Num);
else if (_Str[_Pos] != _E0)
_Xinv();
}
bitset<_Bits>& operator&=(const bitset<_Bits>& _Right)
{ // AND in _Right
for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
_Array[_Wpos] &= _Right._Getword(_Wpos);
return (*this);
}
bitset<_Bits>& operator|=(const bitset<_Bits>& _Right)
{ // OR in _Right
for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
_Array[_Wpos] |= _Right._Getword(_Wpos);
return (*this);
}
bitset<_Bits>& operator^=(const bitset<_Bits>& _Right)
{ // XOR in _Right
for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
_Array[_Wpos] ^= _Right._Getword(_Wpos);
return (*this);
}
bitset<_Bits>& operator<<=(size_t _Pos)
{ // shift left by _Pos
const int _Wordshift = (int)(_Pos / _Bitsperword);
if (_Wordshift != 0)
for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos) // shift by words
_Array[_Wpos] = _Wordshift <= _Wpos
? _Array[_Wpos - _Wordshift] : (_Ty)0;
if ((_Pos %= _Bitsperword) != 0)
{ // 0 < _Pos < _Bitsperword, shift by bits
for (int _Wpos = _Words; 0 < _Wpos; --_Wpos)
_Array[_Wpos] = (_Ty)((_Array[_Wpos] << _Pos)
| (_Array[_Wpos - 1] >> (_Bitsperword - _Pos)));
_Array[0] <<= _Pos;
}
_Trim();
return (*this);
}
bitset<_Bits>& operator>>=(size_t _Pos)
{ // shift right by _Pos
const int _Wordshift = (int)(_Pos / _Bitsperword);
if (_Wordshift != 0)
for (int _Wpos = 0; _Wpos <= _Words; ++_Wpos) // shift by words
_Array[_Wpos] = _Wordshift <= _Words - _Wpos
? _Array[_Wpos + _Wordshift] : (_Ty)0;
if ((_Pos %= _Bitsperword) != 0)
{ // 0 < _Pos < _Bitsperword, shift by bits
for (int _Wpos = 0; _Wpos < _Words; ++_Wpos)
_Array[_Wpos] = (_Ty)((_Array[_Wpos] >> _Pos)
| (_Array[_Wpos + 1] << (_Bitsperword - _Pos)));
_Array[_Words] >>= _Pos;
}
return (*this);
}
bitset<_Bits>& set()
{ // set all bits true
_Tidy((_Ty)~0);
return (*this);
}
bitset<_Bits>& set(size_t _Pos,
bool _Val = true)
{ // set bit at _Pos to _Val
if (_Bits <= _Pos)
_Xran(); // _Pos off end
if (_Val)
_Array[_Pos / _Bitsperword] |= (_Ty)1 << _Pos % _Bitsperword;
else
_Array[_Pos / _Bitsperword] &= ~((_Ty)1 << _Pos % _Bitsperword);
return (*this);
}
bitset<_Bits>& reset()
{ // set all bits false
_Tidy();
return (*this);
}
bitset<_Bits>& reset(size_t _Pos)
{ // set bit at _Pos to false
return (set(_Pos, false));
}
bitset<_Bits> operator~() const
{ // flip all bits
return (bitset<_Bits>(*this).flip());
}
bitset<_Bits>& flip()
{ // flip all bits
for (int _Wpos = _Words; 0 <= _Wpos; --_Wpos)
_Array[_Wpos] = (_Ty)~_Array[_Wpos];
_Trim();
return (*this);
}
bitset<_Bits>& flip(size_t _Pos)
{ // flip bit at _Pos
if (_Bits <= _Pos)
_Xran(); // _Pos off end
_Array[_Pos / _Bitsperword] ^= (_Ty)1 << _Pos % _Bitsperword;
return (*this);
}
unsigned long to_ulong() const
{ // convert bitset to unsigned long
_ULonglong _Val = to_ullong();
unsigned long _Ans = (unsigned long)_Val;
if (_Ans != _Val)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -