23 #ifndef EASTL_BITSET_H
24 #define EASTL_BITSET_H
27 #include <EASTL/internal/config.h>
28 #include <EASTL/algorithm.h>
30 EA_DISABLE_ALL_VC_WARNINGS();
35 EA_RESTORE_ALL_VC_WARNINGS();
37 #if EASTL_EXCEPTIONS_ENABLED
38 EA_DISABLE_ALL_VC_WARNINGS();
42 EA_RESTORE_ALL_VC_WARNINGS();
45 EA_DISABLE_VC_WARNING(4127);
47 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
65 #if !defined(__GNUC__) || (__GNUC__ >= 3)
66 #define BITSET_WORD_COUNT(nBitCount, WordType) (nBitCount == 0 ? 1 : ((nBitCount - 1) / (8 * sizeof(WordType)) + 1))
68 #define BITSET_WORD_COUNT(nBitCount, WordType) ((nBitCount - 1) / (8 * sizeof(WordType)) + 1)
77 #if defined(__GNUC__) && (EA_COMPILER_VERSION > 4007) && defined(EA_PLATFORM_ANDROID)
78 #define EASTL_DISABLE_BITSET_ARRAYBOUNDS_WARNING 1
80 #define EASTL_DISABLE_BITSET_ARRAYBOUNDS_WARNING 0
89 template <
size_t NW,
typename WordType>
92 typedef WordType word_type;
94 #if EASTL_BITSET_SIZE_T
95 typedef size_t size_type;
97 typedef eastl_size_t size_type;
101 kBitsPerWord = (8 *
sizeof(word_type)),
102 kBitsPerWordMask = (kBitsPerWord - 1),
103 kBitsPerWordShift = ((kBitsPerWord == 8) ? 3 : ((kBitsPerWord == 16) ? 4 : ((kBitsPerWord == 32) ? 5 : (((kBitsPerWord == 64) ? 6 : 7)))))
118 void operator<<=(size_type n);
119 void operator>>=(size_type n);
123 void set(size_type i,
bool value);
126 bool operator==(
const this_type& x)
const;
129 size_type count()
const;
131 void from_uint32(uint32_t value);
132 void from_uint64(uint64_t value);
134 unsigned long to_ulong()
const;
135 uint32_t to_uint32()
const;
136 uint64_t to_uint64()
const;
138 word_type& DoGetWord(size_type i);
139 word_type DoGetWord(size_type i)
const;
141 size_type DoFindFirst()
const;
142 size_type DoFindNext(size_type last_find)
const;
144 size_type DoFindLast()
const;
145 size_type DoFindPrev(size_type last_find)
const;
155 template <
typename WordType>
158 typedef WordType word_type;
160 #if EASTL_BITSET_SIZE_T
161 typedef size_t size_type;
163 typedef eastl_size_t size_type;
167 kBitsPerWord = (8 *
sizeof(word_type)),
168 kBitsPerWordMask = (kBitsPerWord - 1),
169 kBitsPerWordShift = ((kBitsPerWord == 8) ? 3 : ((kBitsPerWord == 16) ? 4 : ((kBitsPerWord == 32) ? 5 : (((kBitsPerWord == 64) ? 6 : 7)))))
184 void operator<<=(size_type n);
185 void operator>>=(size_type n);
189 void set(size_type i,
bool value);
192 bool operator==(
const this_type& x)
const;
195 size_type count()
const;
197 void from_uint32(uint32_t value);
198 void from_uint64(uint64_t value);
200 unsigned long to_ulong()
const;
201 uint32_t to_uint32()
const;
202 uint64_t to_uint64()
const;
204 word_type& DoGetWord(size_type);
205 word_type DoGetWord(size_type)
const;
207 size_type DoFindFirst()
const;
208 size_type DoFindNext(size_type last_find)
const;
210 size_type DoFindLast()
const;
211 size_type DoFindPrev(size_type last_find)
const;
222 template <
typename WordType>
225 typedef WordType word_type;
227 #if EASTL_BITSET_SIZE_T
228 typedef size_t size_type;
230 typedef eastl_size_t size_type;
234 kBitsPerWord = (8 *
sizeof(word_type)),
235 kBitsPerWordMask = (kBitsPerWord - 1),
236 kBitsPerWordShift = ((kBitsPerWord == 8) ? 3 : ((kBitsPerWord == 16) ? 4 : ((kBitsPerWord == 32) ? 5 : (((kBitsPerWord == 64) ? 6 : 7)))))
251 void operator<<=(size_type n);
252 void operator>>=(size_type n);
256 void set(size_type i,
bool value);
259 bool operator==(
const this_type& x)
const;
262 size_type count()
const;
264 void from_uint32(uint32_t value);
265 void from_uint64(uint64_t value);
267 unsigned long to_ulong()
const;
268 uint32_t to_uint32()
const;
269 uint64_t to_uint64()
const;
271 word_type& DoGetWord(size_type);
272 word_type DoGetWord(size_type)
const;
274 size_type DoFindFirst()
const;
275 size_type DoFindNext(size_type last_find)
const;
277 size_type DoFindLast()
const;
278 size_type DoFindPrev(size_type last_find)
const;
302 template <
size_t N,
typename WordType = EASTL_BITSET_WORD_TYPE_DEFAULT>
308 typedef WordType word_type;
309 typedef typename base_type::size_type size_type;
313 kBitsPerWord = (8 *
sizeof(word_type)),
314 kBitsPerWordMask = (kBitsPerWord - 1),
315 kBitsPerWordShift = ((kBitsPerWord == 8) ? 3 : ((kBitsPerWord == 16) ? 4 : ((kBitsPerWord == 32) ? 5 : (((kBitsPerWord == 64) ? 6 : 7))))),
317 kWordSize =
sizeof(word_type),
318 kWordCount = BITSET_WORD_COUNT(N, WordType)
321 using base_type::mWord;
322 using base_type::DoGetWord;
323 using base_type::DoFindFirst;
324 using base_type::DoFindNext;
325 using base_type::DoFindLast;
326 using base_type::DoFindPrev;
327 using base_type::to_ulong;
328 using base_type::to_uint32;
329 using base_type::to_uint64;
330 using base_type::count;
331 using base_type::any;
344 friend class bitset<N, WordType>;
346 word_type* mpBitWord;
347 size_type mnBitIndex;
357 bool operator~()
const;
358 operator bool()
const
359 {
return (*mpBitWord & (
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask))) != 0; }
392 bool operator[](size_type i)
const;
394 const word_type* data()
const;
397 void from_uint32(uint32_t value);
398 void from_uint64(uint64_t value);
405 size_type size()
const;
407 bool operator==(
const this_type& x)
const;
408 bool operator!=(
const this_type& x)
const;
410 bool test(size_type i)
const;
419 size_type find_first()
const;
422 size_type find_next(size_type last_find)
const;
425 size_type find_last()
const;
428 size_type find_prev(size_type last_find)
const;
448 #if defined(__GNUC__) && (__GNUC__ == 3)
449 x = x - ((x >> 1) & 0x5555555555555555ULL);
450 x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
451 x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
452 return (uint32_t)((x * 0x0101010101010101ULL) >> 56);
454 x = x - ((x >> 1) & UINT64_C(0x5555555555555555));
455 x = (x & UINT64_C(0x3333333333333333)) + ((x >> 2) & UINT64_C(0x3333333333333333));
456 x = (x + (x >> 4)) & UINT64_C(0x0F0F0F0F0F0F0F0F);
457 return (uint32_t)((x * UINT64_C(0x0101010101010101)) >> 56);
463 x = x - ((x >> 1) & 0x55555555);
464 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
465 x = (x + (x >> 4)) & 0x0F0F0F0F;
466 return (uint32_t)((x * 0x01010101) >> 24);
481 #define EASTL_BITSET_COUNT_STRING "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4"
484 inline uint32_t GetFirstBit(uint8_t x)
490 if((x & 0x0000000F) == 0) { n += 4; x >>= 4; }
491 if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
493 return (uint32_t)(n - (x & 1));
499 inline uint32_t GetFirstBit(uint16_t x)
505 if((x & 0x000000FF) == 0) { n += 8; x >>= 8; }
506 if((x & 0x0000000F) == 0) { n += 4; x >>= 4; }
507 if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
509 return (uint32_t)(n - (x & 1));
515 inline uint32_t GetFirstBit(uint32_t x)
521 if((x & 0x0000FFFF) == 0) { n += 16; x >>= 16; }
522 if((x & 0x000000FF) == 0) { n += 8; x >>= 8; }
523 if((x & 0x0000000F) == 0) { n += 4; x >>= 4; }
524 if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
526 return (n - (x & 1));
532 inline uint32_t GetFirstBit(uint64_t x)
538 if((x & 0xFFFFFFFF) == 0) { n += 32; x >>= 32; }
539 if((x & 0x0000FFFF) == 0) { n += 16; x >>= 16; }
540 if((x & 0x000000FF) == 0) { n += 8; x >>= 8; }
541 if((x & 0x0000000F) == 0) { n += 4; x >>= 4; }
542 if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
544 return (n - ((uint32_t)x & 1));
551 #if EASTL_INT128_SUPPORTED
552 inline uint32_t GetFirstBit(eastl_uint128_t x)
558 if((x & UINT64_C(0xFFFFFFFFFFFFFFFF)) == 0) { n += 64; x >>= 64; }
559 if((x & 0xFFFFFFFF) == 0) { n += 32; x >>= 32; }
560 if((x & 0x0000FFFF) == 0) { n += 16; x >>= 16; }
561 if((x & 0x000000FF) == 0) { n += 8; x >>= 8; }
562 if((x & 0x0000000F) == 0) { n += 4; x >>= 4; }
563 if((x & 0x00000003) == 0) { n += 2; x >>= 2; }
565 return (n - ((uint32_t)x & 1));
572 inline uint32_t GetLastBit(uint8_t x)
578 if(x & 0xFFF0) { n += 4; x >>= 4; }
579 if(x & 0xFFFC) { n += 2; x >>= 2; }
580 if(x & 0xFFFE) { n += 1; }
588 inline uint32_t GetLastBit(uint16_t x)
594 if(x & 0xFF00) { n += 8; x >>= 8; }
595 if(x & 0xFFF0) { n += 4; x >>= 4; }
596 if(x & 0xFFFC) { n += 2; x >>= 2; }
597 if(x & 0xFFFE) { n += 1; }
605 inline uint32_t GetLastBit(uint32_t x)
611 if(x & 0xFFFF0000) { n += 16; x >>= 16; }
612 if(x & 0xFFFFFF00) { n += 8; x >>= 8; }
613 if(x & 0xFFFFFFF0) { n += 4; x >>= 4; }
614 if(x & 0xFFFFFFFC) { n += 2; x >>= 2; }
615 if(x & 0xFFFFFFFE) { n += 1; }
623 inline uint32_t GetLastBit(uint64_t x)
629 if(x & UINT64_C(0xFFFFFFFF00000000)) { n += 32; x >>= 32; }
630 if(x & 0xFFFF0000) { n += 16; x >>= 16; }
631 if(x & 0xFFFFFF00) { n += 8; x >>= 8; }
632 if(x & 0xFFFFFFF0) { n += 4; x >>= 4; }
633 if(x & 0xFFFFFFFC) { n += 2; x >>= 2; }
634 if(x & 0xFFFFFFFE) { n += 1; }
642 #if EASTL_INT128_SUPPORTED
643 inline uint32_t GetLastBit(eastl_uint128_t x)
649 eastl_uint128_t mask(UINT64_C(0xFFFFFFFF00000000));
652 if(x & mask) { n += 64; x >>= 64; }
653 if(x & UINT64_C(0xFFFFFFFF00000000)) { n += 32; x >>= 32; }
654 if(x & UINT64_C(0x00000000FFFF0000)) { n += 16; x >>= 16; }
655 if(x & UINT64_C(0x00000000FFFFFF00)) { n += 8; x >>= 8; }
656 if(x & UINT64_C(0x00000000FFFFFFF0)) { n += 4; x >>= 4; }
657 if(x & UINT64_C(0x00000000FFFFFFFC)) { n += 2; x >>= 2; }
658 if(x & UINT64_C(0x00000000FFFFFFFE)) { n += 1; }
683 template <
size_t NW,
typename WordType>
684 inline BitsetBase<NW, WordType>::BitsetBase()
690 template <
size_t NW,
typename WordType>
691 inline BitsetBase<NW, WordType>::BitsetBase(uint32_t value)
697 mWord[0] =
static_cast<word_type
>(value);
720 template <
size_t NW,
typename WordType>
721 inline void BitsetBase<NW, WordType>::operator&=(
const this_type& x)
723 for(
size_t i = 0; i < NW; i++)
724 mWord[i] &= x.mWord[i];
728 template <
size_t NW,
typename WordType>
729 inline void BitsetBase<NW, WordType>::operator|=(
const this_type& x)
731 for(
size_t i = 0; i < NW; i++)
732 mWord[i] |= x.mWord[i];
736 template <
size_t NW,
typename WordType>
737 inline void BitsetBase<NW, WordType>::operator^=(
const this_type& x)
739 for(
size_t i = 0; i < NW; i++)
740 mWord[i] ^= x.mWord[i];
744 template <
size_t NW,
typename WordType>
745 inline void BitsetBase<NW, WordType>::operator<<=(size_type n)
747 const size_type nWordShift = (size_type)(n >> kBitsPerWordShift);
751 for(
int i = (
int)(NW - 1); i >= 0; --i)
752 mWord[i] = (nWordShift <= (size_type)i) ? mWord[i - nWordShift] : (word_type)0;
755 if(n &= kBitsPerWordMask)
757 for(
size_t i = (NW - 1); i > 0; --i)
758 mWord[i] = (word_type)((mWord[i] << n) | (mWord[i - 1] >> (kBitsPerWord - n)));
766 template <
size_t NW,
typename WordType>
767 inline void BitsetBase<NW, WordType>::operator>>=(size_type n)
769 const size_type nWordShift = (size_type)(n >> kBitsPerWordShift);
773 for(
size_t i = 0; i < NW; ++i)
774 mWord[i] = ((nWordShift < (NW - i)) ? mWord[i + nWordShift] : (word_type)0);
777 if(n &= kBitsPerWordMask)
779 for(
size_t i = 0; i < (NW - 1); ++i)
780 mWord[i] = (word_type)((mWord[i] >> n) | (mWord[i + 1] << (kBitsPerWord - n)));
786 template <
size_t NW,
typename WordType>
787 inline void BitsetBase<NW, WordType>::flip()
789 for(
size_t i = 0; i < NW; i++)
790 mWord[i] = ~mWord[i];
795 template <
size_t NW,
typename WordType>
796 inline void BitsetBase<NW, WordType>::set()
798 for(
size_t i = 0; i < NW; i++)
799 mWord[i] =
static_cast<word_type
>(~
static_cast<word_type
>(0));
804 template <
size_t NW,
typename WordType>
805 inline void BitsetBase<NW, WordType>::set(size_type i,
bool value)
808 mWord[i >> kBitsPerWordShift] |= (
static_cast<word_type
>(1) << (i & kBitsPerWordMask));
810 mWord[i >> kBitsPerWordShift] &= ~(
static_cast<word_type
>(1) << (i & kBitsPerWordMask));
814 template <
size_t NW,
typename WordType>
815 inline void BitsetBase<NW, WordType>::reset()
820 memset(mWord, 0,
sizeof(mWord));
824 for(
size_t i = 0; i < NW; i++)
830 template <
size_t NW,
typename WordType>
831 inline bool BitsetBase<NW, WordType>::operator==(
const this_type& x)
const
833 for(
size_t i = 0; i < NW; i++)
835 if(mWord[i] != x.mWord[i])
842 template <
size_t NW,
typename WordType>
843 inline bool BitsetBase<NW, WordType>::any()
const
845 for(
size_t i = 0; i < NW; i++)
854 template <
size_t NW,
typename WordType>
855 inline typename BitsetBase<NW, WordType>::size_type
856 BitsetBase<NW, WordType>::count()
const
860 for(
size_t i = 0; i < NW; i++)
862 #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 304) && !defined(EA_PLATFORM_ANDROID)
863 #if(EA_PLATFORM_WORD_SIZE == 4)
864 n += (size_type)__builtin_popcountl(mWord[i]);
866 n += (size_type)__builtin_popcountll(mWord[i]);
868 #elif defined(__GNUC__) && (__GNUC__ < 3)
873 for(word_type w = mWord[i]; w; w >>= 4)
874 n += EASTL_BITSET_COUNT_STRING[w & 0xF];
885 template <
size_t NW,
typename WordType>
886 inline void BitsetBase<NW, WordType>::from_uint32(uint32_t value)
889 mWord[0] =
static_cast<word_type
>(value);
893 template <
size_t NW,
typename WordType>
894 inline void BitsetBase<NW, WordType>::from_uint64(uint64_t value)
898 #if(EA_PLATFORM_WORD_SIZE == 4)
899 mWord[0] =
static_cast<word_type
>(value);
901 EASTL_CT_ASSERT(NW > 2);
903 mWord[1] =
static_cast<word_type
>(value >> 32);
905 mWord[0] =
static_cast<word_type
>(value);
910 template <
size_t NW,
typename WordType>
911 inline unsigned long BitsetBase<NW, WordType>::to_ulong()
const
913 #if EASTL_EXCEPTIONS_ENABLED
914 for(
size_t i = 1; i < NW; ++i)
917 throw std::overflow_error(
"BitsetBase::to_ulong");
920 return (
unsigned long)mWord[0];
924 template <
size_t NW,
typename WordType>
925 inline uint32_t BitsetBase<NW, WordType>::to_uint32()
const
927 #if EASTL_EXCEPTIONS_ENABLED
929 for(
size_t i = 1; i < NW; ++i)
932 throw std::overflow_error(
"BitsetBase::to_uint32");
935 #if(EA_PLATFORM_WORD_SIZE > 4)
937 throw std::overflow_error(
"BitsetBase::to_uint32");
941 return (uint32_t)mWord[0];
945 template <
size_t NW,
typename WordType>
946 inline uint64_t BitsetBase<NW, WordType>::to_uint64()
const
948 #if EASTL_EXCEPTIONS_ENABLED
951 EASTL_CT_ASSERT(NW > 2);
952 for(
size_t i = 2; i < NW; ++i)
955 throw std::overflow_error(
"BitsetBase::to_uint64");
959 #if(EA_PLATFORM_WORD_SIZE == 4)
960 EASTL_CT_ASSERT(NW > 2);
961 return (mWord[1] << 32) | mWord[0];
963 return (uint64_t)mWord[0];
968 template <
size_t NW,
typename WordType>
969 inline typename BitsetBase<NW, WordType>::word_type&
970 BitsetBase<NW, WordType>::DoGetWord(size_type i)
972 return mWord[i >> kBitsPerWordShift];
976 template <
size_t NW,
typename WordType>
977 inline typename BitsetBase<NW, WordType>::word_type
978 BitsetBase<NW, WordType>::DoGetWord(size_type i)
const
980 return mWord[i >> kBitsPerWordShift];
984 template <
size_t NW,
typename WordType>
985 inline typename BitsetBase<NW, WordType>::size_type
986 BitsetBase<NW, WordType>::DoFindFirst()
const
988 for(size_type word_index = 0; word_index < NW; ++word_index)
990 const size_type fbiw = GetFirstBit(mWord[word_index]);
992 if(fbiw != kBitsPerWord)
993 return (word_index * kBitsPerWord) + fbiw;
996 return (size_type)NW * kBitsPerWord;
1000 #if EASTL_DISABLE_BITSET_ARRAYBOUNDS_WARNING
1001 EA_DISABLE_GCC_WARNING(-Warray-bounds)
1004 template <
size_t NW,
typename WordType>
1005 inline typename BitsetBase<NW, WordType>::size_type
1006 BitsetBase<NW, WordType>::DoFindNext(size_type last_find)
const
1012 size_type word_index =
static_cast<size_type
>(last_find >> kBitsPerWordShift);
1013 size_type bit_index =
static_cast<size_type
>(last_find & kBitsPerWordMask);
1019 word_type this_word = mWord[word_index] & (~static_cast<word_type>(0) << bit_index);
1023 const size_type fbiw = GetFirstBit(this_word);
1025 if(fbiw != kBitsPerWord)
1026 return (word_index * kBitsPerWord) + fbiw;
1028 if(++word_index < NW)
1029 this_word = mWord[word_index];
1035 return (size_type)NW * kBitsPerWord;
1038 #if EASTL_DISABLE_BITSET_ARRAYBOUNDS_WARNING
1039 EA_RESTORE_GCC_WARNING()
1044 template <
size_t NW,
typename WordType>
1045 inline typename BitsetBase<NW, WordType>::size_type
1046 BitsetBase<NW, WordType>::DoFindLast()
const
1048 for(size_type word_index = (size_type)NW; word_index > 0; --word_index)
1050 const size_type lbiw = GetLastBit(mWord[word_index - 1]);
1052 if(lbiw != kBitsPerWord)
1053 return ((word_index - 1) * kBitsPerWord) + lbiw;
1056 return (size_type)NW * kBitsPerWord;
1060 template <
size_t NW,
typename WordType>
1061 inline typename BitsetBase<NW, WordType>::size_type
1062 BitsetBase<NW, WordType>::DoFindPrev(size_type last_find)
const
1067 size_type word_index =
static_cast<size_type
>(last_find >> kBitsPerWordShift);
1068 size_type bit_index =
static_cast<size_type
>(last_find & kBitsPerWordMask);
1071 word_type mask = (~static_cast<word_type>(0) >> (kBitsPerWord - 1 - bit_index)) >> 1;
1072 word_type this_word = mWord[word_index] & mask;
1076 const size_type lbiw = GetLastBit(this_word);
1078 if(lbiw != kBitsPerWord)
1079 return (word_index * kBitsPerWord) + lbiw;
1082 this_word = mWord[--word_index];
1088 return (size_type)NW * kBitsPerWord;
1097 template <
typename WordType>
1098 inline BitsetBase<1, WordType>::BitsetBase()
1104 template <
typename WordType>
1105 inline BitsetBase<1, WordType>::BitsetBase(uint32_t value)
1110 mWord[0] =
static_cast<word_type
>(value);
1128 template <
typename WordType>
1129 inline void BitsetBase<1, WordType>::operator&=(
const this_type& x)
1131 mWord[0] &= x.mWord[0];
1135 template <
typename WordType>
1136 inline void BitsetBase<1, WordType>::operator|=(
const this_type& x)
1138 mWord[0] |= x.mWord[0];
1142 template <
typename WordType>
1143 inline void BitsetBase<1, WordType>::operator^=(
const this_type& x)
1145 mWord[0] ^= x.mWord[0];
1149 template <
typename WordType>
1150 inline void BitsetBase<1, WordType>::operator<<=(size_type n)
1157 template <
typename WordType>
1158 inline void BitsetBase<1, WordType>::operator>>=(size_type n)
1164 template <
typename WordType>
1165 inline void BitsetBase<1, WordType>::flip()
1167 mWord[0] = ~mWord[0];
1172 template <
typename WordType>
1173 inline void BitsetBase<1, WordType>::set()
1175 mWord[0] =
static_cast<word_type
>(~static_cast<word_type>(0));
1180 template <
typename WordType>
1181 inline void BitsetBase<1, WordType>::set(size_type i,
bool value)
1184 mWord[0] |= (
static_cast<word_type
>(1) << i);
1186 mWord[0] &= ~(
static_cast<word_type
>(1) << i);
1190 template <
typename WordType>
1191 inline void BitsetBase<1, WordType>::reset()
1197 template <
typename WordType>
1198 inline bool BitsetBase<1, WordType>::operator==(
const this_type& x)
const
1200 return mWord[0] == x.mWord[0];
1204 template <
typename WordType>
1205 inline bool BitsetBase<1, WordType>::any()
const
1207 return mWord[0] != 0;
1211 template <
typename WordType>
1212 inline typename BitsetBase<1, WordType>::size_type
1213 BitsetBase<1, WordType>::count()
const
1215 #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 304) && !defined(EA_PLATFORM_ANDROID)
1216 #if(EA_PLATFORM_WORD_SIZE == 4)
1217 return (size_type)__builtin_popcountl(mWord[0]);
1219 return (size_type)__builtin_popcountll(mWord[0]);
1221 #elif defined(__GNUC__) && (__GNUC__ < 3)
1225 for(word_type w = mWord[0]; w; w >>= 4)
1226 n += EASTL_BITSET_COUNT_STRING[w & 0xF];
1232 template <
typename WordType>
1233 inline void BitsetBase<1, WordType>::from_uint32(uint32_t value)
1235 mWord[0] =
static_cast<word_type
>(value);
1239 template <
typename WordType>
1240 inline void BitsetBase<1, WordType>::from_uint64(uint64_t value)
1242 #if(EA_PLATFORM_WORD_SIZE == 4)
1243 EASTL_ASSERT(value <= 0xffffffff);
1244 mWord[0] =
static_cast<word_type
>(value);
1246 mWord[0] =
static_cast<word_type
>(value);
1251 template <
typename WordType>
1252 inline unsigned long BitsetBase<1, WordType>::to_ulong()
const
1254 #if EASTL_EXCEPTIONS_ENABLED
1255 #if((EA_PLATFORM_WORD_SIZE > 4) && defined(EA_PLATFORM_MICROSOFT))
1258 throw std::overflow_error(
"BitsetBase::to_ulong");
1262 return static_cast<unsigned long>(mWord[0]);
1266 template <
typename WordType>
1267 inline uint32_t BitsetBase<1, WordType>::to_uint32()
const
1269 #if EASTL_EXCEPTIONS_ENABLED
1270 #if(EA_PLATFORM_WORD_SIZE > 4)
1273 throw std::overflow_error(
"BitsetBase::to_uint32");
1277 return static_cast<uint32_t
>(mWord[0]);
1281 template <
typename WordType>
1282 inline uint64_t BitsetBase<1, WordType>::to_uint64()
const
1285 return static_cast<uint64_t
>(mWord[0]);
1289 template <
typename WordType>
1290 inline typename BitsetBase<1, WordType>::word_type&
1291 BitsetBase<1, WordType>::DoGetWord(size_type)
1297 template <
typename WordType>
1298 inline typename BitsetBase<1, WordType>::word_type
1299 BitsetBase<1, WordType>::DoGetWord(size_type)
const
1305 template <
typename WordType>
1306 inline typename BitsetBase<1, WordType>::size_type
1307 BitsetBase<1, WordType>::DoFindFirst()
const
1309 return GetFirstBit(mWord[0]);
1313 template <
typename WordType>
1314 inline typename BitsetBase<1, WordType>::size_type
1315 BitsetBase<1, WordType>::DoFindNext(size_type last_find)
const
1317 if(++last_find < kBitsPerWord)
1320 const word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) << last_find);
1322 return GetFirstBit(this_word);
1325 return kBitsPerWord;
1329 template <
typename WordType>
1330 inline typename BitsetBase<1, WordType>::size_type
1331 BitsetBase<1, WordType>::DoFindLast()
const
1333 return GetLastBit(mWord[0]);
1337 template <
typename WordType>
1338 inline typename BitsetBase<1, WordType>::size_type
1339 BitsetBase<1, WordType>::DoFindPrev(size_type last_find)
const
1344 const word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) >> (kBitsPerWord - last_find));
1346 return GetLastBit(this_word);
1349 return kBitsPerWord;
1359 template <
typename WordType>
1360 inline BitsetBase<2, WordType>::BitsetBase()
1367 template <
typename WordType>
1368 inline BitsetBase<2, WordType>::BitsetBase(uint32_t value)
1373 mWord[0] =
static_cast<word_type
>(value);
1393 template <
typename WordType>
1394 inline void BitsetBase<2, WordType>::operator&=(
const this_type& x)
1396 mWord[0] &= x.mWord[0];
1397 mWord[1] &= x.mWord[1];
1401 template <
typename WordType>
1402 inline void BitsetBase<2, WordType>::operator|=(
const this_type& x)
1404 mWord[0] |= x.mWord[0];
1405 mWord[1] |= x.mWord[1];
1409 template <
typename WordType>
1410 inline void BitsetBase<2, WordType>::operator^=(
const this_type& x)
1412 mWord[0] ^= x.mWord[0];
1413 mWord[1] ^= x.mWord[1];
1417 template <
typename WordType>
1418 inline void BitsetBase<2, WordType>::operator<<=(size_type n)
1422 if(EASTL_UNLIKELY(n >= kBitsPerWord))
1424 mWord[1] = mWord[0];
1429 mWord[1] = (mWord[1] << n) | (mWord[0] >> (kBitsPerWord - n));
1436 template <
typename WordType>
1437 inline void BitsetBase<2, WordType>::operator>>=(size_type n)
1441 if(EASTL_UNLIKELY(n >= kBitsPerWord))
1443 mWord[0] = mWord[1];
1448 mWord[0] = (mWord[0] >> n) | (mWord[1] << (kBitsPerWord - n));
1454 template <
typename WordType>
1455 inline void BitsetBase<2, WordType>::flip()
1457 mWord[0] = ~mWord[0];
1458 mWord[1] = ~mWord[1];
1463 template <
typename WordType>
1464 inline void BitsetBase<2, WordType>::set()
1466 mWord[0] = ~static_cast<word_type>(0);
1467 mWord[1] = ~static_cast<word_type>(0);
1472 template <
typename WordType>
1473 inline void BitsetBase<2, WordType>::set(size_type i,
bool value)
1476 mWord[i >> kBitsPerWordShift] |= (
static_cast<word_type
>(1) << (i & kBitsPerWordMask));
1478 mWord[i >> kBitsPerWordShift] &= ~(
static_cast<word_type
>(1) << (i & kBitsPerWordMask));
1482 template <
typename WordType>
1483 inline void BitsetBase<2, WordType>::reset()
1490 template <
typename WordType>
1491 inline bool BitsetBase<2, WordType>::operator==(
const this_type& x)
const
1493 return (mWord[0] == x.mWord[0]) && (mWord[1] == x.mWord[1]);
1497 template <
typename WordType>
1498 inline bool BitsetBase<2, WordType>::any()
const
1501 return (mWord[0] | mWord[1]) != 0;
1504 template <
typename WordType>
1505 inline typename BitsetBase<2, WordType>::size_type
1506 BitsetBase<2, WordType>::count()
const
1508 #if (defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 304)) || defined(__clang__)
1509 #if(EA_PLATFORM_WORD_SIZE == 4)
1510 return (size_type)__builtin_popcountl(mWord[0]) + (size_type)__builtin_popcountl(mWord[1]);
1512 return (size_type)__builtin_popcountll(mWord[0]) + (size_type)__builtin_popcountll(mWord[1]);
1521 template <
typename WordType>
1522 inline void BitsetBase<2, WordType>::from_uint32(uint32_t value)
1524 mWord[0] =
static_cast<word_type
>(value);
1529 template <
typename WordType>
1530 inline void BitsetBase<2, WordType>::from_uint64(uint64_t value)
1532 #if(EA_PLATFORM_WORD_SIZE == 4)
1533 mWord[0] =
static_cast<word_type
>(value);
1534 mWord[1] =
static_cast<word_type
>(value >> 32);
1536 mWord[0] =
static_cast<word_type
>(value);
1542 template <
typename WordType>
1543 inline unsigned long BitsetBase<2, WordType>::to_ulong()
const
1545 #if EASTL_EXCEPTIONS_ENABLED
1547 throw std::overflow_error(
"BitsetBase::to_ulong");
1549 return (
unsigned long)mWord[0];
1553 template <
typename WordType>
1554 inline uint32_t BitsetBase<2, WordType>::to_uint32()
const
1556 #if EASTL_EXCEPTIONS_ENABLED
1559 #if(EA_PLATFORM_WORD_SIZE == 4)
1561 throw std::overflow_error(
"BitsetBase::to_uint32");
1563 if(mWord[1] || (mWord[0] >> 32))
1564 throw std::overflow_error(
"BitsetBase::to_uint32");
1568 return (uint32_t)mWord[0];
1572 template <
typename WordType>
1573 inline uint64_t BitsetBase<2, WordType>::to_uint64()
const
1575 #if(EA_PLATFORM_WORD_SIZE == 4)
1578 return ((uint64_t)mWord[1] << 32) | mWord[0];
1580 #if EASTL_EXCEPTIONS_ENABLED
1582 throw std::overflow_error(
"BitsetBase::to_uint64");
1585 return (uint64_t)mWord[0];
1590 template <
typename WordType>
1591 inline typename BitsetBase<2, WordType>::word_type&
1592 BitsetBase<2, WordType>::DoGetWord(size_type i)
1594 return mWord[i >> kBitsPerWordShift];
1598 template <
typename WordType>
1599 inline typename BitsetBase<2, WordType>::word_type
1600 BitsetBase<2, WordType>::DoGetWord(size_type i)
const
1602 return mWord[i >> kBitsPerWordShift];
1606 template <
typename WordType>
1607 inline typename BitsetBase<2, WordType>::size_type
1608 BitsetBase<2, WordType>::DoFindFirst()
const
1610 size_type fbiw = GetFirstBit(mWord[0]);
1612 if(fbiw != kBitsPerWord)
1615 fbiw = GetFirstBit(mWord[1]);
1617 if(fbiw != kBitsPerWord)
1618 return kBitsPerWord + fbiw;
1620 return 2 * kBitsPerWord;
1624 template <
typename WordType>
1625 inline typename BitsetBase<2, WordType>::size_type
1626 BitsetBase<2, WordType>::DoFindNext(size_type last_find)
const
1629 if(++last_find < (size_type)kBitsPerWord)
1632 word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) << last_find);
1635 size_type fbiw = GetFirstBit(this_word);
1637 if(fbiw != kBitsPerWord)
1640 fbiw = GetFirstBit(mWord[1]);
1642 if(fbiw != kBitsPerWord)
1643 return kBitsPerWord + fbiw;
1645 else if(last_find < (size_type)(2 * kBitsPerWord))
1648 last_find -= kBitsPerWord;
1651 word_type this_word = mWord[1] & ((~static_cast<word_type>(0)) << last_find);
1653 const size_type fbiw = GetFirstBit(this_word);
1655 if(fbiw != kBitsPerWord)
1656 return kBitsPerWord + fbiw;
1659 return 2 * kBitsPerWord;
1663 template <
typename WordType>
1664 inline typename BitsetBase<2, WordType>::size_type
1665 BitsetBase<2, WordType>::DoFindLast()
const
1667 size_type lbiw = GetLastBit(mWord[1]);
1669 if(lbiw != kBitsPerWord)
1670 return kBitsPerWord + lbiw;
1672 lbiw = GetLastBit(mWord[0]);
1674 if(lbiw != kBitsPerWord)
1677 return 2 * kBitsPerWord;
1681 template <
typename WordType>
1682 inline typename BitsetBase<2, WordType>::size_type
1683 BitsetBase<2, WordType>::DoFindPrev(size_type last_find)
const
1686 if(last_find > (size_type)kBitsPerWord)
1689 last_find -= kBitsPerWord;
1692 word_type this_word = mWord[1] & ((~static_cast<word_type>(0)) >> (kBitsPerWord - last_find));
1695 size_type lbiw = GetLastBit(this_word);
1697 if(lbiw != kBitsPerWord)
1698 return kBitsPerWord + lbiw;
1700 lbiw = GetLastBit(mWord[0]);
1702 if(lbiw != kBitsPerWord)
1705 else if(last_find != 0)
1708 word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) >> (kBitsPerWord - last_find));
1710 const size_type lbiw = GetLastBit(this_word);
1712 if(lbiw != kBitsPerWord)
1716 return 2 * kBitsPerWord;
1725 template <
size_t N,
typename WordType>
1726 inline bitset<N, WordType>::reference::reference(
const bitset& x, size_type i)
1727 : mpBitWord(&const_cast<bitset&>(x).DoGetWord(i)),
1728 mnBitIndex(i & kBitsPerWordMask)
1734 template <
size_t N,
typename WordType>
1735 inline typename bitset<N, WordType>::reference&
1736 bitset<N, WordType>::reference::operator=(
bool value)
1739 *mpBitWord |= (
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask));
1741 *mpBitWord &= ~(
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask));
1746 template <
size_t N,
typename WordType>
1747 inline typename bitset<N, WordType>::reference&
1748 bitset<N, WordType>::reference::operator=(
const reference& x)
1750 if(*x.mpBitWord & (
static_cast<word_type
>(1) << (x.mnBitIndex & kBitsPerWordMask)))
1751 *mpBitWord |= (
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask));
1753 *mpBitWord &= ~(
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask));
1758 template <
size_t N,
typename WordType>
1759 inline bool bitset<N, WordType>::reference::operator~()
const
1761 return (*mpBitWord & (
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask))) == 0;
1773 template <
size_t N,
typename WordType>
1774 inline typename bitset<N, WordType>::reference&
1775 bitset<N, WordType>::reference::flip()
1777 *mpBitWord ^=
static_cast<word_type
>(1) << (mnBitIndex & kBitsPerWordMask);
1788 template <
size_t N,
typename WordType>
1789 inline bitset<N, WordType>::bitset()
1795 EA_DISABLE_VC_WARNING(6313)
1796 template <
size_t N, typename WordType>
1797 inline bitset<N, WordType>::bitset(uint32_t value)
1800 if((N & kBitsPerWordMask) || (N == 0))
1801 mWord[kWordCount - 1] &= ~(
static_cast<word_type
>(~static_cast<word_type>(0)) << (N & kBitsPerWordMask));
1803 EA_RESTORE_VC_WARNING()
1816 template <
size_t N, typename WordType>
1817 inline typename bitset<N, WordType>::this_type&
1818 bitset<N, WordType>::operator&=(const this_type& x)
1820 base_type::operator&=(x);
1825 template <
size_t N,
typename WordType>
1826 inline typename bitset<N, WordType>::this_type&
1827 bitset<N, WordType>::operator|=(
const this_type& x)
1829 base_type::operator|=(x);
1834 template <
size_t N,
typename WordType>
1835 inline typename bitset<N, WordType>::this_type&
1836 bitset<N, WordType>::operator^=(
const this_type& x)
1838 base_type::operator^=(x);
1843 template <
size_t N,
typename WordType>
1844 inline typename bitset<N, WordType>::this_type&
1845 bitset<N, WordType>::operator<<=(size_type n)
1847 if(EASTL_LIKELY((intptr_t)n < (intptr_t)N))
1849 EA_DISABLE_VC_WARNING(6313)
1850 base_type::operator<<=(n);
1851 if((N & kBitsPerWordMask) || (N == 0))
1852 mWord[kWordCount - 1] &= ~(static_cast<word_type>(~static_cast<word_type>(0)) << (N & kBitsPerWordMask));
1853 EA_RESTORE_VC_WARNING()
1861 template <
size_t N, typename WordType>
1862 inline typename bitset<N, WordType>::this_type&
1863 bitset<N, WordType>::operator>>=(size_type n)
1865 if(EASTL_LIKELY(n < N))
1866 base_type::operator>>=(n);
1873 template <
size_t N,
typename WordType>
1874 inline typename bitset<N, WordType>::this_type&
1875 bitset<N, WordType>::set()
1878 if((N & kBitsPerWordMask) || (N == 0))
1879 mWord[kWordCount - 1] &= ~(
static_cast<word_type
>(~static_cast<word_type>(0)) << (N & kBitsPerWordMask));
1884 template <
size_t N,
typename WordType>
1885 inline typename bitset<N, WordType>::this_type&
1886 bitset<N, WordType>::set(size_type i,
bool value)
1889 base_type::set(i, value);
1892 #if EASTL_ASSERT_ENABLED
1893 if(EASTL_UNLIKELY(!(i < N)))
1894 EASTL_FAIL_MSG(
"bitset::set -- out of range");
1897 #if EASTL_EXCEPTIONS_ENABLED
1898 throw std::out_of_range(
"bitset::set");
1906 template <
size_t N,
typename WordType>
1907 inline typename bitset<N, WordType>::this_type&
1908 bitset<N, WordType>::reset()
1915 template <
size_t N,
typename WordType>
1916 inline typename bitset<N, WordType>::this_type&
1917 bitset<N, WordType>::reset(size_type i)
1919 if(EASTL_LIKELY(i < N))
1920 DoGetWord(i) &= ~(
static_cast<word_type
>(1) << (i & kBitsPerWordMask));
1923 #if EASTL_ASSERT_ENABLED
1924 if(EASTL_UNLIKELY(!(i < N)))
1925 EASTL_FAIL_MSG(
"bitset::reset -- out of range");
1928 #if EASTL_EXCEPTIONS_ENABLED
1929 throw std::out_of_range(
"bitset::reset");
1937 template <
size_t N,
typename WordType>
1938 inline typename bitset<N, WordType>::this_type&
1939 bitset<N, WordType>::flip()
1941 EA_DISABLE_VC_WARNING(6313)
1943 if((N & kBitsPerWordMask) || (N == 0))
1944 mWord[kWordCount - 1] &= ~(static_cast<word_type>(~static_cast<word_type>(0)) << (N & kBitsPerWordMask));
1946 EA_RESTORE_VC_WARNING()
1950 template <
size_t N, typename WordType>
1951 inline typename bitset<N, WordType>::this_type&
1952 bitset<N, WordType>::flip(size_type i)
1954 if(EASTL_LIKELY(i < N))
1955 DoGetWord(i) ^= (
static_cast<word_type
>(1) << (i & kBitsPerWordMask));
1958 #if EASTL_ASSERT_ENABLED
1959 if(EASTL_UNLIKELY(!(i < N)))
1960 EASTL_FAIL_MSG(
"bitset::flip -- out of range");
1963 #if EASTL_EXCEPTIONS_ENABLED
1964 throw std::out_of_range(
"bitset::flip");
1971 template <
size_t N,
typename WordType>
1972 inline typename bitset<N, WordType>::this_type
1973 bitset<N, WordType>::operator~()
const
1975 return this_type(*this).flip();
1979 template <
size_t N,
typename WordType>
1980 inline typename bitset<N, WordType>::reference
1981 bitset<N, WordType>::operator[](size_type i)
1983 #if EASTL_ASSERT_ENABLED
1984 if(EASTL_UNLIKELY(!(i < N)))
1985 EASTL_FAIL_MSG(
"bitset::operator[] -- out of range");
1988 return reference(*
this, i);
1992 template <
size_t N,
typename WordType>
1993 inline bool bitset<N, WordType>::operator[](size_type i)
const
1995 #if EASTL_ASSERT_ENABLED
1996 if(EASTL_UNLIKELY(!(i < N)))
1997 EASTL_FAIL_MSG(
"bitset::operator[] -- out of range");
2000 return (DoGetWord(i) & (
static_cast<word_type
>(1) << (i & kBitsPerWordMask))) != 0;
2004 template <
size_t N,
typename WordType>
2005 inline const typename bitset<N, WordType>::word_type* bitset<N, WordType>::data()
const
2007 return base_type::mWord;
2011 template <
size_t N,
typename WordType>
2012 inline typename bitset<N, WordType>::word_type* bitset<N, WordType>::data()
2014 return base_type::mWord;
2018 template <
size_t N,
typename WordType>
2019 inline void bitset<N, WordType>::from_uint32(uint32_t value)
2021 base_type::from_uint32(value);
2023 if((N & kBitsPerWordMask) || (N == 0))
2024 mWord[kWordCount - 1] &= ~(
static_cast<word_type
>(~static_cast<word_type>(0)) << (N & kBitsPerWordMask));
2028 template <
size_t N,
typename WordType>
2029 inline void bitset<N, WordType>::from_uint64(uint64_t value)
2031 base_type::from_uint64(value);
2033 if((N & kBitsPerWordMask) || (N == 0))
2034 mWord[kWordCount - 1] &= ~(
static_cast<word_type
>(~static_cast<word_type>(0)) << (N & kBitsPerWordMask));
2067 template <
size_t N,
typename WordType>
2068 inline typename bitset<N, WordType>::size_type
2069 bitset<N, WordType>::size()
const
2071 return (size_type)N;
2075 template <
size_t N,
typename WordType>
2076 inline bool bitset<N, WordType>::operator==(
const this_type& x)
const
2078 return base_type::operator==(x);
2082 template <
size_t N,
typename WordType>
2083 inline bool bitset<N, WordType>::operator!=(
const this_type& x)
const
2085 return !base_type::operator==(x);
2089 template <
size_t N,
typename WordType>
2090 inline bool bitset<N, WordType>::test(size_type i)
const
2092 if(EASTL_UNLIKELY(i < N))
2093 return (DoGetWord(i) & (
static_cast<word_type
>(1) << (i & kBitsPerWordMask))) != 0;
2095 #if EASTL_ASSERT_ENABLED
2096 EASTL_FAIL_MSG(
"bitset::test -- out of range");
2099 #if EASTL_EXCEPTIONS_ENABLED
2100 throw std::out_of_range(
"bitset::test");
2114 template <
size_t N,
typename WordType>
2115 inline bool bitset<N, WordType>::all()
const
2117 return count() == size();
2121 template <
size_t N,
typename WordType>
2122 inline bool bitset<N, WordType>::none()
const
2124 return !base_type::any();
2128 template <
size_t N,
typename WordType>
2129 inline typename bitset<N, WordType>::this_type
2130 bitset<N, WordType>::operator<<(size_type n)
const
2132 return this_type(*this).operator<<=(n);
2136 template <
size_t N,
typename WordType>
2137 inline typename bitset<N, WordType>::this_type
2138 bitset<N, WordType>::operator>>(size_type n)
const
2140 return this_type(*this).operator>>=(n);
2144 template <
size_t N,
typename WordType>
2145 inline typename bitset<N, WordType>::size_type
2146 bitset<N, WordType>::find_first()
const
2148 const size_type i = base_type::DoFindFirst();
2158 template <
size_t N,
typename WordType>
2159 inline typename bitset<N, WordType>::size_type
2160 bitset<N, WordType>::find_next(size_type last_find)
const
2162 const size_type i = base_type::DoFindNext(last_find);
2172 template <
size_t N,
typename WordType>
2173 inline typename bitset<N, WordType>::size_type
2174 bitset<N, WordType>::find_last()
const
2176 const size_type i = base_type::DoFindLast();
2186 template <
size_t N,
typename WordType>
2187 inline typename bitset<N, WordType>::size_type
2188 bitset<N, WordType>::find_prev(size_type last_find)
const
2190 const size_type i = base_type::DoFindPrev(last_find);
2205 template <
size_t N,
typename WordType>
2206 inline bitset<N, WordType> operator&(
const bitset<N, WordType>& a,
const bitset<N, WordType>& b)
2209 return bitset<N, WordType>(a).operator&=(b);
2213 template <
size_t N,
typename WordType>
2214 inline bitset<N, WordType> operator|(
const bitset<N, WordType>& a,
const bitset<N, WordType>& b)
2216 return bitset<N, WordType>(a).operator|=(b);
2220 template <
size_t N,
typename WordType>
2221 inline bitset<N, WordType> operator^(
const bitset<N, WordType>& a,
const bitset<N, WordType>& b)
2223 return bitset<N, WordType>(a).operator^=(b);
2230 EA_RESTORE_VC_WARNING();
EA Standard Template Library.
Definition: algorithm.h:288
uint32_t BitsetCountBits(uint64_t x)
Definition: bitset.h:442