_bitset.h
来自「stl的源码」· C头文件 代码 · 共 881 行 · 第 1/2 页
H
881 行
/* * Copyright (c) 1998 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */#ifndef _STLP_BITSET_H#define _STLP_BITSET_H// A bitset of size N has N % (sizeof(unsigned long) * CHAR_BIT) unused// bits. (They are the high- order bits in the highest word.) It is// a class invariant of class bitset<> that those unused bits are// always zero.// Most of the actual code isn't contained in bitset<> itself, but in the// base class _Base_bitset. The base class works with whole words, not with// individual bits. This allows us to specialize _Base_bitset for the// important special case where the bitset is only a single word.// The C++ standard does not define the precise semantics of operator[].// In this implementation the const version of operator[] is equivalent// to test(), except that it does no range checking. The non-const version// returns a reference to a bit, again without doing any range checking.#ifndef _STLP_INTERNAL_ALGOBASE_H# include <stl/_algobase.h>#endif#ifndef _STLP_INTERNAL_ALLOC_H# include <stl/_alloc.h>#endif#ifndef _STLP_INTERNAL_ITERATOR_H# include <stl/_iterator.h>#endif#ifndef _STLP_INTERNAL_UNINITIALIZED_H# include <stl/_uninitialized.h>#endif#ifndef _STLP_RANGE_ERRORS_H# include <stl/_range_errors.h>#endif#ifndef _STLP_INTERNAL_STRING_H# include <stl/_string.h>#endif#define __BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long))#define __BITSET_WORDS(__n) ((__n + __BITS_PER_WORD - 1)/__BITS_PER_WORD)_STLP_BEGIN_NAMESPACE_STLP_MOVE_TO_PRIV_NAMESPACE// structure to aid in counting bitsclass _STLP_CLASS_DECLSPEC _Bs_G{ public: //returns the number of bit set within the buffer between __beg and __end. static size_t _S_count(const unsigned char *__beg, const unsigned char *__end)#if defined (_STLP_USE_NO_IOSTREAMS) { size_t __result = 0; for (; __beg != __end; ++__beg) { for (size_t i = 0; i < (sizeof(unsigned char) * 8); ++i) { if ((*__beg & (1 << i)) != 0) { ++__result; } } } return __result; }#else ;#endif // Mapping from 8 bit unsigned integers to the index of the first one bit set: static unsigned char _S_first_one(unsigned char __x)#if defined (_STLP_USE_NO_IOSTREAMS) { for (unsigned char i = 0; i < (sizeof(unsigned char) * 8); ++i) { if ((__x & (1 << i)) != 0) { return i; } } return 0; }#else ;#endif};//// Base class: general case.//template<size_t _Nw>struct _Base_bitset { typedef unsigned long _WordT; _WordT _M_w[_Nw]; // 0 is the least significant word. _Base_bitset() { _M_do_reset(); } _Base_bitset(unsigned long __val) { _M_do_reset(); _M_w[0] = __val; } static size_t _STLP_CALL _S_whichword( size_t __pos ) { return __pos / __BITS_PER_WORD; } static size_t _STLP_CALL _S_whichbyte( size_t __pos ) { return (__pos % __BITS_PER_WORD) / CHAR_BIT; } static size_t _STLP_CALL _S_whichbit( size_t __pos ) { return __pos % __BITS_PER_WORD; } static _WordT _STLP_CALL _S_maskbit( size_t __pos ) { return __STATIC_CAST(_WordT,1) << _S_whichbit(__pos); } _WordT& _M_getword(size_t __pos) { return _M_w[_S_whichword(__pos)]; } _WordT _M_getword(size_t __pos) const { return _M_w[_S_whichword(__pos)]; } _WordT& _M_hiword() { return _M_w[_Nw - 1]; } _WordT _M_hiword() const { return _M_w[_Nw - 1]; } void _M_do_and(const _Base_bitset<_Nw>& __x) { for ( size_t __i = 0; __i < _Nw; __i++ ) { _M_w[__i] &= __x._M_w[__i]; } } void _M_do_or(const _Base_bitset<_Nw>& __x) { for ( size_t __i = 0; __i < _Nw; __i++ ) { _M_w[__i] |= __x._M_w[__i]; } } void _M_do_xor(const _Base_bitset<_Nw>& __x) { for ( size_t __i = 0; __i < _Nw; __i++ ) { _M_w[__i] ^= __x._M_w[__i]; } } void _M_do_left_shift(size_t __shift); void _M_do_right_shift(size_t __shift); void _M_do_flip() { for ( size_t __i = 0; __i < _Nw; __i++ ) { _M_w[__i] = ~_M_w[__i]; } } void _M_do_set() { for ( size_t __i = 0; __i < _Nw; __i++ ) { _M_w[__i] = ~__STATIC_CAST(_WordT,0); } } void _M_do_reset() { memset(_M_w, 0, _Nw * sizeof(_WordT)); } bool _M_is_equal(const _Base_bitset<_Nw>& __x) const { for (size_t __i = 0; __i < _Nw; ++__i) { if (_M_w[__i] != __x._M_w[__i]) return false; } return true; } bool _M_is_any() const { for ( size_t __i = 0; __i < _Nw ; __i++ ) { if ( _M_w[__i] != __STATIC_CAST(_WordT,0) ) return true; } return false; } size_t _M_do_count() const { const unsigned char* __byte_ptr = (const unsigned char*)_M_w; const unsigned char* __end_ptr = (const unsigned char*)(_M_w+_Nw); return _Bs_G::_S_count(__byte_ptr, __end_ptr); } unsigned long _M_do_to_ulong() const; // find first "on" bit size_t _M_do_find_first(size_t __not_found) const; // find the next "on" bit that follows "prev" size_t _M_do_find_next(size_t __prev, size_t __not_found) const;};//// Base class: specialization for a single word.//_STLP_TEMPLATE_NULLstruct _Base_bitset<1UL> { typedef unsigned long _WordT; typedef _Base_bitset<1UL> _Self; _WordT _M_w; _Base_bitset( void ) : _M_w(0) {} _Base_bitset(unsigned long __val) : _M_w(__val) {} static size_t _STLP_CALL _S_whichword( size_t __pos ) { return __pos / __BITS_PER_WORD ; } static size_t _STLP_CALL _S_whichbyte( size_t __pos ) { return (__pos % __BITS_PER_WORD) / CHAR_BIT; } static size_t _STLP_CALL _S_whichbit( size_t __pos ) { return __pos % __BITS_PER_WORD; } static _WordT _STLP_CALL _S_maskbit( size_t __pos ) { return (__STATIC_CAST(_WordT,1)) << _S_whichbit(__pos); } _WordT& _M_getword(size_t) { return _M_w; } _WordT _M_getword(size_t) const { return _M_w; } _WordT& _M_hiword() { return _M_w; } _WordT _M_hiword() const { return _M_w; } void _M_do_and(const _Self& __x) { _M_w &= __x._M_w; } void _M_do_or(const _Self& __x) { _M_w |= __x._M_w; } void _M_do_xor(const _Self& __x) { _M_w ^= __x._M_w; } void _M_do_left_shift(size_t __shift) { _M_w <<= __shift; } void _M_do_right_shift(size_t __shift) { _M_w >>= __shift; } void _M_do_flip() { _M_w = ~_M_w; } void _M_do_set() { _M_w = ~__STATIC_CAST(_WordT,0); } void _M_do_reset() { _M_w = 0; } bool _M_is_equal(const _Self& __x) const { return _M_w == __x._M_w; } bool _M_is_any() const { return _M_w != 0; } size_t _M_do_count() const { const unsigned char* __byte_ptr = (const unsigned char*)&_M_w; const unsigned char* __end_ptr = ((const unsigned char*)&_M_w)+sizeof(_M_w); return _Bs_G::_S_count(__byte_ptr, __end_ptr); } unsigned long _M_do_to_ulong() const { return _M_w; } inline size_t _M_do_find_first(size_t __not_found) const; // find the next "on" bit that follows "prev" inline size_t _M_do_find_next(size_t __prev, size_t __not_found) const;};// ------------------------------------------------------------//// Definitions of should-be-non-inline functions from the single-word version of// _Base_bitset.//inline size_t_Base_bitset<1UL>::_M_do_find_first(size_t __not_found) const { // typedef unsigned long _WordT; _WordT __thisword = _M_w; if ( __thisword != __STATIC_CAST(_WordT,0) ) { // find byte within word for ( size_t __j = 0; __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = __STATIC_CAST(unsigned char,(__thisword & (~(unsigned char)0))); if ( __this_byte ) return __j*CHAR_BIT + _Bs_G::_S_first_one(__this_byte); __thisword >>= CHAR_BIT; } } // not found, so return a value that indicates failure. return __not_found;}inline size_t_Base_bitset<1UL>::_M_do_find_next(size_t __prev, size_t __not_found ) const { // make bound inclusive ++__prev; // check out of bounds if ( __prev >= __BITS_PER_WORD ) return __not_found; // search first (and only) word _WordT __thisword = _M_w; // mask off bits below bound __thisword &= (~__STATIC_CAST(_WordT,0)) << _S_whichbit(__prev); if ( __thisword != __STATIC_CAST(_WordT,0) ) { // find byte within word // get first byte into place __thisword >>= _S_whichbyte(__prev) * CHAR_BIT; for ( size_t __j = _S_whichbyte(__prev); __j < sizeof(_WordT); __j++ ) { unsigned char __this_byte = __STATIC_CAST(unsigned char,(__thisword & (~(unsigned char)0))); if ( __this_byte ) return __j*CHAR_BIT + _Bs_G::_S_first_one(__this_byte); __thisword >>= CHAR_BIT; } } // not found, so return a value that indicates failure. return __not_found;} // end _M_do_find_next// ------------------------------------------------------------// Helper class to zero out the unused high-order bits in the highest word.template <size_t _Extrabits> struct _Sanitize { static void _STLP_CALL _M_do_sanitize(unsigned long& __val) { __val &= ~((~__STATIC_CAST(unsigned long,0)) << _Extrabits); }};_STLP_TEMPLATE_NULL struct _Sanitize<0UL> { static void _STLP_CALL _M_do_sanitize(unsigned long) {}};_STLP_MOVE_TO_STD_NAMESPACE// ------------------------------------------------------------// Class bitset.// _Nb may be any nonzero number of type size_t.template<size_t _Nb>class bitset : public _STLP_PRIV _Base_bitset<__BITSET_WORDS(_Nb) > {public: enum { _Words = __BITSET_WORDS(_Nb) } ;private: typedef _STLP_PRIV _Base_bitset< _Words > _Base; void _M_do_sanitize() { _STLP_PRIV _Sanitize<_Nb%__BITS_PER_WORD >::_M_do_sanitize(this->_M_hiword()); }public: typedef unsigned long _WordT; struct reference; friend struct reference; // bit reference: struct reference { typedef _STLP_PRIV _Base_bitset<_Words > _Bitset_base; typedef bitset<_Nb> _Bitset; // friend _Bitset; _WordT *_M_wp; size_t _M_bpos; // should be left undefined reference() {} reference( _Bitset& __b, size_t __pos ) { _M_wp = &__b._M_getword(__pos); _M_bpos = _Bitset_base::_S_whichbit(__pos); } public: ~reference() {} // for b[i] = __x; reference& operator=(bool __x) { if ( __x ) *_M_wp |= _Bitset_base::_S_maskbit(_M_bpos); else *_M_wp &= ~_Bitset_base::_S_maskbit(_M_bpos); return *this; } // for b[i] = b[__j]; reference& operator=(const reference& __j) { if ( (*(__j._M_wp) & _Bitset_base::_S_maskbit(__j._M_bpos)) ) *_M_wp |= _Bitset_base::_S_maskbit(_M_bpos); else *_M_wp &= ~_Bitset_base::_S_maskbit(_M_bpos); return *this; } // flips the bit bool operator~() const { return (*(_M_wp) & _Bitset_base::_S_maskbit(_M_bpos)) == 0; } // for __x = b[i]; operator bool() const { return (*(_M_wp) & _Bitset_base::_S_maskbit(_M_bpos)) != 0; } // for b[i].flip(); reference& flip() { *_M_wp ^= _Bitset_base::_S_maskbit(_M_bpos); return *this; } }; // 23.3.5.1 constructors: bitset() {} bitset(unsigned long __val) : _STLP_PRIV _Base_bitset<_Words>(__val) { _M_do_sanitize(); }#if defined (_STLP_MEMBER_TEMPLATES) template<class _CharT, class _Traits, class _Alloc> explicit bitset(const basic_string<_CharT,_Traits,_Alloc>& __s, size_t __pos = 0) : _STLP_PRIV _Base_bitset<_Words >() { if (__pos > __s.size()) __stl_throw_out_of_range("bitset"); _M_copy_from_string(__s, __pos, basic_string<_CharT, _Traits, _Alloc>::npos); } template<class _CharT, class _Traits, class _Alloc> bitset(const basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos, size_t __n) : _STLP_PRIV _Base_bitset<_Words >() { if (__pos > __s.size()) __stl_throw_out_of_range("bitset"); _M_copy_from_string(__s, __pos, __n); }#else /* _STLP_MEMBER_TEMPLATES */ explicit bitset(const string& __s, size_t __pos = 0, size_t __n = (size_t)-1)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?