Home | History | Annotate | Download | only in include
      1 // -*- C++ -*-
      2 //===---------------------------- bitset ----------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP_BITSET
     12 #define _LIBCPP_BITSET
     13 
     14 /*
     15     bitset synopsis
     16 
     17 namespace std
     18 {
     19 
     20 namespace std {
     21 
     22 template <size_t N>
     23 class bitset
     24 {
     25 public:
     26     // bit reference:
     27     class reference
     28     {
     29         friend class bitset;
     30         reference() noexcept;
     31     public:
     32         ~reference() noexcept;
     33         reference& operator=(bool x) noexcept;           // for b[i] = x;
     34         reference& operator=(const reference&) noexcept; // for b[i] = b[j];
     35         bool operator~() const noexcept;                 // flips the bit
     36         operator bool() const noexcept;                  // for x = b[i];
     37         reference& flip() noexcept;                      // for b[i].flip();
     38     };
     39 
     40     // 23.3.5.1 constructors:
     41     constexpr bitset() noexcept;
     42     constexpr bitset(unsigned long long val) noexcept;
     43     template <class charT>
     44         explicit bitset(const charT* str,
     45                         typename basic_string<charT>::size_type n = basic_string<charT>::npos,
     46                         charT zero = charT('0'), charT one = charT('1'));
     47     template<class charT, class traits, class Allocator>
     48         explicit bitset(const basic_string<charT,traits,Allocator>& str,
     49                         typename basic_string<charT,traits,Allocator>::size_type pos = 0,
     50                         typename basic_string<charT,traits,Allocator>::size_type n =
     51                                  basic_string<charT,traits,Allocator>::npos,
     52                         charT zero = charT('0'), charT one = charT('1'));
     53 
     54     // 23.3.5.2 bitset operations:
     55     bitset& operator&=(const bitset& rhs) noexcept;
     56     bitset& operator|=(const bitset& rhs) noexcept;
     57     bitset& operator^=(const bitset& rhs) noexcept;
     58     bitset& operator<<=(size_t pos) noexcept;
     59     bitset& operator>>=(size_t pos) noexcept;
     60     bitset& set() noexcept;
     61     bitset& set(size_t pos, bool val = true);
     62     bitset& reset() noexcept;
     63     bitset& reset(size_t pos);
     64     bitset operator~() const noexcept;
     65     bitset& flip() noexcept;
     66     bitset& flip(size_t pos);
     67 
     68     // element access:
     69     constexpr bool operator[](size_t pos) const; // for b[i];
     70     reference operator[](size_t pos);            // for b[i];
     71     unsigned long to_ulong() const;
     72     unsigned long long to_ullong() const;
     73     template <class charT, class traits, class Allocator>
     74         basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
     75     template <class charT, class traits>
     76         basic_string<charT, traits, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
     77     template <class charT>
     78         basic_string<charT, char_traits<charT>, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
     79     basic_string<char, char_traits<char>, allocator<char> > to_string(char zero = '0', char one = '1') const;
     80     size_t count() const noexcept;
     81     constexpr size_t size() const noexcept;
     82     bool operator==(const bitset& rhs) const noexcept;
     83     bool operator!=(const bitset& rhs) const noexcept;
     84     bool test(size_t pos) const;
     85     bool all() const noexcept;
     86     bool any() const noexcept;
     87     bool none() const noexcept;
     88     bitset operator<<(size_t pos) const noexcept;
     89     bitset operator>>(size_t pos) const noexcept;
     90 };
     91 
     92 // 23.3.5.3 bitset operators:
     93 template <size_t N>
     94 bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;
     95 
     96 template <size_t N>
     97 bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;
     98 
     99 template <size_t N>
    100 bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;
    101 
    102 template <class charT, class traits, size_t N>
    103 basic_istream<charT, traits>&
    104 operator>>(basic_istream<charT, traits>& is, bitset<N>& x);
    105 
    106 template <class charT, class traits, size_t N>
    107 basic_ostream<charT, traits>&
    108 operator<<(basic_ostream<charT, traits>& os, const bitset<N>& x);
    109 
    110 template <size_t N> struct hash<std::bitset<N>>;
    111 
    112 }  // std
    113 
    114 */
    115 
    116 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    117 #pragma GCC system_header
    118 #endif
    119 
    120 #include <__config>
    121 #include <__bit_reference>
    122 #include <cstddef>
    123 #include <climits>
    124 #include <string>
    125 #include <stdexcept>
    126 #include <iosfwd>
    127 #include <__functional_base>
    128 #if defined(_LIBCPP_NO_EXCEPTIONS)
    129     #include <cassert>
    130 #endif
    131 
    132 #include <__undef_min_max>
    133 
    134 _LIBCPP_BEGIN_NAMESPACE_STD
    135 
    136 template <size_t _N_words, size_t _Size>
    137 class __bitset;
    138 
    139 template <size_t _N_words, size_t _Size>
    140 struct __has_storage_type<__bitset<_N_words, _Size> >
    141 {
    142     static const bool value = true;
    143 };
    144 
    145 template <size_t _N_words, size_t _Size>
    146 class __bitset
    147 {
    148 public:
    149     typedef ptrdiff_t              difference_type;
    150     typedef size_t                 size_type;
    151     typedef size_type              __storage_type;
    152 protected:
    153     typedef __bitset __self;
    154     typedef       __storage_type*  __storage_pointer;
    155     typedef const __storage_type*  __const_storage_pointer;
    156     static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
    157 
    158     friend class __bit_reference<__bitset>;
    159     friend class __bit_const_reference<__bitset>;
    160     friend class __bit_iterator<__bitset, false>;
    161     friend class __bit_iterator<__bitset, true>;
    162     friend struct __bit_array<__bitset>;
    163 
    164     __storage_type __first_[_N_words];
    165 
    166     typedef __bit_reference<__bitset>                  reference;
    167     typedef __bit_const_reference<__bitset>            const_reference;
    168     typedef __bit_iterator<__bitset, false>            iterator;
    169     typedef __bit_iterator<__bitset, true>             const_iterator;
    170 
    171     _LIBCPP_INLINE_VISIBILITY
    172     _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
    173     _LIBCPP_INLINE_VISIBILITY
    174     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
    175 
    176     _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
    177         {return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
    178     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT
    179         {return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
    180     _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT
    181         {return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
    182     _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
    183         {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
    184 
    185     _LIBCPP_INLINE_VISIBILITY
    186     void operator&=(const __bitset& __v) _NOEXCEPT;
    187     _LIBCPP_INLINE_VISIBILITY
    188     void operator|=(const __bitset& __v) _NOEXCEPT;
    189     _LIBCPP_INLINE_VISIBILITY
    190     void operator^=(const __bitset& __v) _NOEXCEPT;
    191 
    192     void flip() _NOEXCEPT;
    193     _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const
    194         {return to_ulong(integral_constant<bool, _Size < sizeof(unsigned long) * CHAR_BIT>());}
    195     _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const
    196         {return to_ullong(integral_constant<bool, _Size < sizeof(unsigned long long) * CHAR_BIT>());}
    197 
    198     bool all() const _NOEXCEPT;
    199     bool any() const _NOEXCEPT;
    200     _LIBCPP_INLINE_VISIBILITY
    201     size_t __hash_code() const _NOEXCEPT;
    202 private:
    203 #ifdef _LIBCPP_HAS_NO_CONSTEXPR
    204     void __init(unsigned long long __v, false_type) _NOEXCEPT;
    205     _LIBCPP_INLINE_VISIBILITY
    206     void __init(unsigned long long __v, true_type) _NOEXCEPT;
    207 #endif  // _LIBCPP_HAS_NO_CONSTEXPR
    208     unsigned long to_ulong(false_type) const;
    209     _LIBCPP_INLINE_VISIBILITY
    210     unsigned long to_ulong(true_type) const;
    211     unsigned long long to_ullong(false_type) const;
    212     _LIBCPP_INLINE_VISIBILITY
    213     unsigned long long to_ullong(true_type) const;
    214     _LIBCPP_INLINE_VISIBILITY
    215     unsigned long long to_ullong(true_type, false_type) const;
    216     unsigned long long to_ullong(true_type, true_type) const;
    217 };
    218 
    219 template <size_t _N_words, size_t _Size>
    220 inline
    221 _LIBCPP_CONSTEXPR
    222 __bitset<_N_words, _Size>::__bitset() _NOEXCEPT
    223 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
    224     : __first_{0}
    225 #endif
    226 {
    227 #ifdef _LIBCPP_HAS_NO_CONSTEXPR
    228     _VSTD::fill_n(__first_, _N_words, __storage_type(0));
    229 #endif
    230 }
    231 
    232 #ifdef _LIBCPP_HAS_NO_CONSTEXPR
    233 
    234 template <size_t _N_words, size_t _Size>
    235 void
    236 __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT
    237 {
    238     __storage_type __t[sizeof(unsigned long long) / sizeof(__storage_type)];
    239     for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word)
    240         __t[__i] = static_cast<__storage_type>(__v);
    241     _VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_);
    242     _VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]),
    243                __storage_type(0));
    244 }
    245 
    246 template <size_t _N_words, size_t _Size>
    247 inline _LIBCPP_INLINE_VISIBILITY
    248 void
    249 __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT
    250 {
    251     __first_[0] = __v;
    252     _VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0));
    253 }
    254 
    255 #endif  // _LIBCPP_HAS_NO_CONSTEXPR
    256 
    257 template <size_t _N_words, size_t _Size>
    258 inline
    259 _LIBCPP_CONSTEXPR
    260 __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
    261 #ifndef _LIBCPP_HAS_NO_CONSTEXPR
    262 #if __SIZEOF_SIZE_T__ == 8
    263     : __first_{__v}
    264 #elif __SIZEOF_SIZE_T__ == 4
    265     : __first_{__v, __v >> __bits_per_word}
    266 #else
    267 #error This constructor has not been ported to this platform
    268 #endif
    269 #endif
    270 {
    271 #ifdef _LIBCPP_HAS_NO_CONSTEXPR
    272     __init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());
    273 #endif
    274 }
    275 
    276 template <size_t _N_words, size_t _Size>
    277 inline
    278 void
    279 __bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
    280 {
    281     for (size_type __i = 0; __i < _N_words; ++__i)
    282         __first_[__i] &= __v.__first_[__i];
    283 }
    284 
    285 template <size_t _N_words, size_t _Size>
    286 inline
    287 void
    288 __bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
    289 {
    290     for (size_type __i = 0; __i < _N_words; ++__i)
    291         __first_[__i] |= __v.__first_[__i];
    292 }
    293 
    294 template <size_t _N_words, size_t _Size>
    295 inline
    296 void
    297 __bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
    298 {
    299     for (size_type __i = 0; __i < _N_words; ++__i)
    300         __first_[__i] ^= __v.__first_[__i];
    301 }
    302 
    303 template <size_t _N_words, size_t _Size>
    304 void
    305 __bitset<_N_words, _Size>::flip() _NOEXCEPT
    306 {
    307     // do middle whole words
    308     size_type __n = _Size;
    309     __storage_pointer __p = __first_;
    310     for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
    311         *__p = ~*__p;
    312     // do last partial word
    313     if (__n > 0)
    314     {
    315         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
    316         __storage_type __b = *__p & __m;
    317         *__p &= ~__m;
    318         *__p |= ~__b & __m;
    319     }
    320 }
    321 
    322 template <size_t _N_words, size_t _Size>
    323 unsigned long
    324 __bitset<_N_words, _Size>::to_ulong(false_type) const
    325 {
    326     const_iterator __e = __make_iter(_Size);
    327     const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true);
    328     if (__i != __e)
    329 #ifndef _LIBCPP_NO_EXCEPTIONS
    330         throw overflow_error("bitset to_ulong overflow error");
    331 #else
    332         assert(!"bitset to_ulong overflow error");
    333 #endif
    334     return __first_[0];
    335 }
    336 
    337 template <size_t _N_words, size_t _Size>
    338 inline
    339 unsigned long
    340 __bitset<_N_words, _Size>::to_ulong(true_type) const
    341 {
    342     return __first_[0];
    343 }
    344 
    345 template <size_t _N_words, size_t _Size>
    346 unsigned long long
    347 __bitset<_N_words, _Size>::to_ullong(false_type) const
    348 {
    349     const_iterator __e = __make_iter(_Size);
    350     const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true);
    351     if (__i != __e)
    352 #ifndef _LIBCPP_NO_EXCEPTIONS
    353         throw overflow_error("bitset to_ullong overflow error");
    354 #else
    355         assert(!"bitset to_ullong overflow error");
    356 #endif
    357     return to_ullong(true_type());
    358 }
    359 
    360 template <size_t _N_words, size_t _Size>
    361 inline
    362 unsigned long long
    363 __bitset<_N_words, _Size>::to_ullong(true_type) const
    364 {
    365     return to_ullong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long long)>());
    366 }
    367 
    368 template <size_t _N_words, size_t _Size>
    369 inline
    370 unsigned long long
    371 __bitset<_N_words, _Size>::to_ullong(true_type, false_type) const
    372 {
    373     return __first_[0];
    374 }
    375 
    376 template <size_t _N_words, size_t _Size>
    377 unsigned long long
    378 __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const
    379 {
    380     unsigned long long __r = __first_[0];
    381     for (std::size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i)
    382         __r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT);
    383     return __r;
    384 }
    385 
    386 template <size_t _N_words, size_t _Size>
    387 bool
    388 __bitset<_N_words, _Size>::all() const _NOEXCEPT
    389 {
    390     // do middle whole words
    391     size_type __n = _Size;
    392     __const_storage_pointer __p = __first_;
    393     for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
    394         if (~*__p)
    395             return false;
    396     // do last partial word
    397     if (__n > 0)
    398     {
    399         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
    400         if (~*__p & __m)
    401             return false;
    402     }
    403     return true;
    404 }
    405 
    406 template <size_t _N_words, size_t _Size>
    407 bool
    408 __bitset<_N_words, _Size>::any() const _NOEXCEPT
    409 {
    410     // do middle whole words
    411     size_type __n = _Size;
    412     __const_storage_pointer __p = __first_;
    413     for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
    414         if (*__p)
    415             return true;
    416     // do last partial word
    417     if (__n > 0)
    418     {
    419         __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
    420         if (*__p & __m)
    421             return true;
    422     }
    423     return false;
    424 }
    425 
    426 template <size_t _N_words, size_t _Size>
    427 inline
    428 size_t
    429 __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT
    430 {
    431     size_t __h = 0;
    432     for (size_type __i = 0; __i < _N_words; ++__i)
    433         __h ^= __first_[__i];
    434     return __h;
    435 }
    436 
    437 template <size_t _Size>
    438 class __bitset<1, _Size>
    439 {
    440 public:
    441     typedef ptrdiff_t              difference_type;
    442     typedef size_t                 size_type;
    443     typedef size_type              __storage_type;
    444 protected:
    445     typedef __bitset __self;
    446     typedef       __storage_type*  __storage_pointer;
    447     typedef const __storage_type*  __const_storage_pointer;
    448     static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
    449 
    450     friend class __bit_reference<__bitset>;
    451     friend class __bit_const_reference<__bitset>;
    452     friend class __bit_iterator<__bitset, false>;
    453     friend class __bit_iterator<__bitset, true>;
    454     friend struct __bit_array<__bitset>;
    455 
    456     __storage_type __first_;
    457 
    458     typedef __bit_reference<__bitset>                  reference;
    459     typedef __bit_const_reference<__bitset>            const_reference;
    460     typedef __bit_iterator<__bitset, false>            iterator;
    461     typedef __bit_iterator<__bitset, true>             const_iterator;
    462 
    463     _LIBCPP_INLINE_VISIBILITY
    464     _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
    465     _LIBCPP_INLINE_VISIBILITY
    466     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
    467 
    468     _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
    469         {return reference(&__first_, __storage_type(1) << __pos);}
    470     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT
    471         {return const_reference(&__first_, __storage_type(1) << __pos);}
    472     _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT
    473         {return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
    474     _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
    475         {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
    476 
    477     _LIBCPP_INLINE_VISIBILITY
    478     void operator&=(const __bitset& __v) _NOEXCEPT;
    479     _LIBCPP_INLINE_VISIBILITY
    480     void operator|=(const __bitset& __v) _NOEXCEPT;
    481     _LIBCPP_INLINE_VISIBILITY
    482     void operator^=(const __bitset& __v) _NOEXCEPT;
    483 
    484     _LIBCPP_INLINE_VISIBILITY
    485     void flip() _NOEXCEPT;
    486 
    487     _LIBCPP_INLINE_VISIBILITY
    488     unsigned long to_ulong() const;
    489     _LIBCPP_INLINE_VISIBILITY
    490     unsigned long long to_ullong() const;
    491 
    492     _LIBCPP_INLINE_VISIBILITY
    493     bool all() const _NOEXCEPT;
    494     _LIBCPP_INLINE_VISIBILITY
    495     bool any() const _NOEXCEPT;
    496 
    497     _LIBCPP_INLINE_VISIBILITY
    498     size_t __hash_code() const _NOEXCEPT;
    499 };
    500 
    501 template <size_t _Size>
    502 inline
    503 _LIBCPP_CONSTEXPR
    504 __bitset<1, _Size>::__bitset() _NOEXCEPT
    505     : __first_(0)
    506 {
    507 }
    508 
    509 template <size_t _Size>
    510 inline
    511 _LIBCPP_CONSTEXPR
    512 __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
    513     : __first_(static_cast<__storage_type>(__v))
    514 {
    515 }
    516 
    517 template <size_t _Size>
    518 inline
    519 void
    520 __bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
    521 {
    522     __first_ &= __v.__first_;
    523 }
    524 
    525 template <size_t _Size>
    526 inline
    527 void
    528 __bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
    529 {
    530     __first_ |= __v.__first_;
    531 }
    532 
    533 template <size_t _Size>
    534 inline
    535 void
    536 __bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
    537 {
    538     __first_ ^= __v.__first_;
    539 }
    540 
    541 template <size_t _Size>
    542 inline
    543 void
    544 __bitset<1, _Size>::flip() _NOEXCEPT
    545 {
    546     __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
    547     __first_ = ~__first_;
    548     __first_ &= __m;
    549 }
    550 
    551 template <size_t _Size>
    552 inline
    553 unsigned long
    554 __bitset<1, _Size>::to_ulong() const
    555 {
    556     return __first_;
    557 }
    558 
    559 template <size_t _Size>
    560 inline
    561 unsigned long long
    562 __bitset<1, _Size>::to_ullong() const
    563 {
    564     return __first_;
    565 }
    566 
    567 template <size_t _Size>
    568 inline
    569 bool
    570 __bitset<1, _Size>::all() const _NOEXCEPT
    571 {
    572     __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
    573     return !(~__first_ & __m);
    574 }
    575 
    576 template <size_t _Size>
    577 inline
    578 bool
    579 __bitset<1, _Size>::any() const _NOEXCEPT
    580 {
    581     __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
    582     return __first_ & __m;
    583 }
    584 
    585 template <size_t _Size>
    586 inline
    587 size_t
    588 __bitset<1, _Size>::__hash_code() const _NOEXCEPT
    589 {
    590     return __first_;
    591 }
    592 
    593 template <>
    594 class __bitset<0, 0>
    595 {
    596 public:
    597     typedef ptrdiff_t              difference_type;
    598     typedef size_t                 size_type;
    599     typedef size_type              __storage_type;
    600 protected:
    601     typedef __bitset __self;
    602     typedef       __storage_type*  __storage_pointer;
    603     typedef const __storage_type*  __const_storage_pointer;
    604     static const unsigned __bits_per_word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
    605 
    606     friend class __bit_reference<__bitset>;
    607     friend class __bit_const_reference<__bitset>;
    608     friend class __bit_iterator<__bitset, false>;
    609     friend class __bit_iterator<__bitset, true>;
    610     friend struct __bit_array<__bitset>;
    611 
    612     typedef __bit_reference<__bitset>                  reference;
    613     typedef __bit_const_reference<__bitset>            const_reference;
    614     typedef __bit_iterator<__bitset, false>            iterator;
    615     typedef __bit_iterator<__bitset, true>             const_iterator;
    616 
    617     _LIBCPP_INLINE_VISIBILITY
    618     _LIBCPP_CONSTEXPR __bitset() _NOEXCEPT;
    619     _LIBCPP_INLINE_VISIBILITY
    620     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT;
    621 
    622     _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT
    623         {return reference(0, 1);}
    624     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT
    625         {return const_reference(0, 1);}
    626     _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t) _NOEXCEPT
    627         {return iterator(0, 0);}
    628     _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t) const _NOEXCEPT
    629         {return const_iterator(0, 0);}
    630 
    631     _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset&) _NOEXCEPT {}
    632     _LIBCPP_INLINE_VISIBILITY void operator|=(const __bitset&) _NOEXCEPT {}
    633     _LIBCPP_INLINE_VISIBILITY void operator^=(const __bitset&) _NOEXCEPT {}
    634 
    635     _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {}
    636 
    637     _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const {return 0;}
    638     _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const {return 0;}
    639 
    640     _LIBCPP_INLINE_VISIBILITY bool all() const _NOEXCEPT {return true;}
    641     _LIBCPP_INLINE_VISIBILITY bool any() const _NOEXCEPT {return false;}
    642 
    643     _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT {return 0;}
    644 };
    645 
    646 inline
    647 _LIBCPP_CONSTEXPR
    648 __bitset<0, 0>::__bitset() _NOEXCEPT
    649 {
    650 }
    651 
    652 inline
    653 _LIBCPP_CONSTEXPR
    654 __bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT
    655 {
    656 }
    657 
    658 template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset;
    659 template <size_t _Size> struct hash<bitset<_Size> >;
    660 
    661 template <size_t _Size>
    662 class _LIBCPP_TYPE_VIS_ONLY bitset
    663     : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1, _Size>
    664 {
    665 public:
    666     static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) * CHAR_BIT) + 1;
    667     typedef __bitset<__n_words, _Size> base;
    668 
    669 public:
    670     typedef typename base::reference       reference;
    671     typedef typename base::const_reference const_reference;
    672 
    673     // 23.3.5.1 constructors:
    674     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
    675     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    676         bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
    677     template<class _CharT>
    678         explicit bitset(const _CharT* __str,
    679                         typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
    680                         _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
    681     template<class _CharT, class _Traits, class _Allocator>
    682         explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
    683                         typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,
    684                         typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =
    685                                 (basic_string<_CharT,_Traits,_Allocator>::npos),
    686                         _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
    687 
    688     // 23.3.5.2 bitset operations:
    689     _LIBCPP_INLINE_VISIBILITY
    690     bitset& operator&=(const bitset& __rhs) _NOEXCEPT;
    691     _LIBCPP_INLINE_VISIBILITY
    692     bitset& operator|=(const bitset& __rhs) _NOEXCEPT;
    693     _LIBCPP_INLINE_VISIBILITY
    694     bitset& operator^=(const bitset& __rhs) _NOEXCEPT;
    695     bitset& operator<<=(size_t __pos) _NOEXCEPT;
    696     bitset& operator>>=(size_t __pos) _NOEXCEPT;
    697     _LIBCPP_INLINE_VISIBILITY
    698     bitset& set() _NOEXCEPT;
    699     bitset& set(size_t __pos, bool __val = true);
    700     _LIBCPP_INLINE_VISIBILITY
    701     bitset& reset() _NOEXCEPT;
    702     bitset& reset(size_t __pos);
    703     _LIBCPP_INLINE_VISIBILITY
    704     bitset  operator~() const _NOEXCEPT;
    705     _LIBCPP_INLINE_VISIBILITY
    706     bitset& flip() _NOEXCEPT;
    707     bitset& flip(size_t __pos);
    708 
    709     // element access:
    710     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    711                               const_reference operator[](size_t __p) const {return base::__make_ref(__p);}
    712     _LIBCPP_INLINE_VISIBILITY       reference operator[](size_t __p)       {return base::__make_ref(__p);}
    713     _LIBCPP_INLINE_VISIBILITY
    714     unsigned long to_ulong() const;
    715     _LIBCPP_INLINE_VISIBILITY
    716     unsigned long long to_ullong() const;
    717     template <class _CharT, class _Traits, class _Allocator>
    718         basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'),
    719                                                             _CharT __one = _CharT('1')) const;
    720     template <class _CharT, class _Traits>
    721         _LIBCPP_INLINE_VISIBILITY
    722         basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
    723                                                                     _CharT __one = _CharT('1')) const;
    724     template <class _CharT>
    725         _LIBCPP_INLINE_VISIBILITY
    726         basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
    727                                                                                 _CharT __one = _CharT('1')) const;
    728     _LIBCPP_INLINE_VISIBILITY
    729     basic_string<char, char_traits<char>, allocator<char> > to_string(char __zero = '0',
    730                                                                       char __one = '1') const;
    731     _LIBCPP_INLINE_VISIBILITY
    732     size_t count() const _NOEXCEPT;
    733     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}
    734     _LIBCPP_INLINE_VISIBILITY
    735     bool operator==(const bitset& __rhs) const _NOEXCEPT;
    736     _LIBCPP_INLINE_VISIBILITY
    737     bool operator!=(const bitset& __rhs) const _NOEXCEPT;
    738     bool test(size_t __pos) const;
    739     _LIBCPP_INLINE_VISIBILITY
    740     bool all() const _NOEXCEPT;
    741     _LIBCPP_INLINE_VISIBILITY
    742     bool any() const _NOEXCEPT;
    743     _LIBCPP_INLINE_VISIBILITY bool none() const _NOEXCEPT {return !any();}
    744     _LIBCPP_INLINE_VISIBILITY
    745     bitset operator<<(size_t __pos) const _NOEXCEPT;
    746     _LIBCPP_INLINE_VISIBILITY
    747     bitset operator>>(size_t __pos) const _NOEXCEPT;
    748 
    749 private:
    750 
    751     _LIBCPP_INLINE_VISIBILITY
    752     size_t __hash_code() const _NOEXCEPT {return base::__hash_code();}
    753 
    754     friend struct hash<bitset>;
    755 };
    756 
    757 template <size_t _Size>
    758 template<class _CharT>
    759 bitset<_Size>::bitset(const _CharT* __str,
    760                       typename basic_string<_CharT>::size_type __n,
    761                       _CharT __zero, _CharT __one)
    762 {
    763     size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str));
    764     for (size_t __i = 0; __i < __rlen; ++__i)
    765         if (__str[__i] != __zero && __str[__i] != __one)
    766 #ifndef _LIBCPP_NO_EXCEPTIONS
    767             throw invalid_argument("bitset string ctor has invalid argument");
    768 #else
    769             assert(!"bitset string ctor has invalid argument");
    770 #endif
    771     size_t _Mp = _VSTD::min(__rlen, _Size);
    772     size_t __i = 0;
    773     for (; __i < _Mp; ++__i)
    774     {
    775         _CharT __c = __str[_Mp - 1 - __i];
    776         if (__c == __zero)
    777             (*this)[__i] = false;
    778         else
    779             (*this)[__i] = true;
    780     }
    781     _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
    782 }
    783 
    784 template <size_t _Size>
    785 template<class _CharT, class _Traits, class _Allocator>
    786 bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
    787        typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,
    788        typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,
    789        _CharT __zero, _CharT __one)
    790 {
    791     if (__pos > __str.size())
    792 #ifndef _LIBCPP_NO_EXCEPTIONS
    793         throw out_of_range("bitset string pos out of range");
    794 #else
    795         assert(!"bitset string pos out of range");
    796 #endif
    797     size_t __rlen = _VSTD::min(__n, __str.size() - __pos);
    798     for (size_t __i = __pos; __i < __pos + __rlen; ++__i)
    799         if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
    800 #ifndef _LIBCPP_NO_EXCEPTIONS
    801             throw invalid_argument("bitset string ctor has invalid argument");
    802 #else
    803             assert(!"bitset string ctor has invalid argument");
    804 #endif
    805     size_t _Mp = _VSTD::min(__rlen, _Size);
    806     size_t __i = 0;
    807     for (; __i < _Mp; ++__i)
    808     {
    809         _CharT __c = __str[__pos + _Mp - 1 - __i];
    810         if (_Traits::eq(__c, __zero))
    811             (*this)[__i] = false;
    812         else
    813             (*this)[__i] = true;
    814     }
    815     _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
    816 }
    817 
    818 template <size_t _Size>
    819 inline
    820 bitset<_Size>&
    821 bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT
    822 {
    823     base::operator&=(__rhs);
    824     return *this;
    825 }
    826 
    827 template <size_t _Size>
    828 inline
    829 bitset<_Size>&
    830 bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT
    831 {
    832     base::operator|=(__rhs);
    833     return *this;
    834 }
    835 
    836 template <size_t _Size>
    837 inline
    838 bitset<_Size>&
    839 bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT
    840 {
    841     base::operator^=(__rhs);
    842     return *this;
    843 }
    844 
    845 template <size_t _Size>
    846 bitset<_Size>&
    847 bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT
    848 {
    849     __pos = _VSTD::min(__pos, _Size);
    850     _VSTD::copy_backward(base::__make_iter(0), base::__make_iter(_Size - __pos), base::__make_iter(_Size));
    851     _VSTD::fill_n(base::__make_iter(0), __pos, false);
    852     return *this;
    853 }
    854 
    855 template <size_t _Size>
    856 bitset<_Size>&
    857 bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT
    858 {
    859     __pos = _VSTD::min(__pos, _Size);
    860     _VSTD::copy(base::__make_iter(__pos), base::__make_iter(_Size), base::__make_iter(0));
    861     _VSTD::fill_n(base::__make_iter(_Size - __pos), __pos, false);
    862     return *this;
    863 }
    864 
    865 template <size_t _Size>
    866 inline
    867 bitset<_Size>&
    868 bitset<_Size>::set() _NOEXCEPT
    869 {
    870     _VSTD::fill_n(base::__make_iter(0), _Size, true);
    871     return *this;
    872 }
    873 
    874 template <size_t _Size>
    875 bitset<_Size>&
    876 bitset<_Size>::set(size_t __pos, bool __val)
    877 {
    878     if (__pos >= _Size)
    879 #ifndef _LIBCPP_NO_EXCEPTIONS
    880         throw out_of_range("bitset set argument out of range");
    881 #else
    882         assert(!"bitset set argument out of range");
    883 #endif
    884     (*this)[__pos] = __val;
    885     return *this;
    886 }
    887 
    888 template <size_t _Size>
    889 inline
    890 bitset<_Size>&
    891 bitset<_Size>::reset() _NOEXCEPT
    892 {
    893     _VSTD::fill_n(base::__make_iter(0), _Size, false);
    894     return *this;
    895 }
    896 
    897 template <size_t _Size>
    898 bitset<_Size>&
    899 bitset<_Size>::reset(size_t __pos)
    900 {
    901     if (__pos >= _Size)
    902 #ifndef _LIBCPP_NO_EXCEPTIONS
    903         throw out_of_range("bitset reset argument out of range");
    904 #else
    905         assert(!"bitset reset argument out of range");
    906 #endif
    907     (*this)[__pos] = false;
    908     return *this;
    909 }
    910 
    911 template <size_t _Size>
    912 inline
    913 bitset<_Size>
    914 bitset<_Size>::operator~() const _NOEXCEPT
    915 {
    916     bitset __x(*this);
    917     __x.flip();
    918     return __x;
    919 }
    920 
    921 template <size_t _Size>
    922 inline
    923 bitset<_Size>&
    924 bitset<_Size>::flip() _NOEXCEPT
    925 {
    926     base::flip();
    927     return *this;
    928 }
    929 
    930 template <size_t _Size>
    931 bitset<_Size>&
    932 bitset<_Size>::flip(size_t __pos)
    933 {
    934     if (__pos >= _Size)
    935 #ifndef _LIBCPP_NO_EXCEPTIONS
    936         throw out_of_range("bitset flip argument out of range");
    937 #else
    938         assert(!"bitset flip argument out of range");
    939 #endif
    940     reference r = base::__make_ref(__pos);
    941     r = ~r;
    942     return *this;
    943 }
    944 
    945 template <size_t _Size>
    946 inline
    947 unsigned long
    948 bitset<_Size>::to_ulong() const
    949 {
    950     return base::to_ulong();
    951 }
    952 
    953 template <size_t _Size>
    954 inline
    955 unsigned long long
    956 bitset<_Size>::to_ullong() const
    957 {
    958     return base::to_ullong();
    959 }
    960 
    961 template <size_t _Size>
    962 template <class _CharT, class _Traits, class _Allocator>
    963 basic_string<_CharT, _Traits, _Allocator>
    964 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
    965 {
    966     basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero);
    967     for (size_t __i = 0; __i < _Size; ++__i)
    968     {
    969         if ((*this)[__i])
    970             __r[_Size - 1 - __i] = __one;
    971     }
    972     return __r;
    973 }
    974 
    975 template <size_t _Size>
    976 template <class _CharT, class _Traits>
    977 inline
    978 basic_string<_CharT, _Traits, allocator<_CharT> >
    979 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
    980 {
    981     return to_string<_CharT, _Traits, allocator<_CharT> >(__zero, __one);
    982 }
    983 
    984 template <size_t _Size>
    985 template <class _CharT>
    986 inline
    987 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
    988 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
    989 {
    990     return to_string<_CharT, char_traits<_CharT>, allocator<_CharT> >(__zero, __one);
    991 }
    992 
    993 template <size_t _Size>
    994 inline
    995 basic_string<char, char_traits<char>, allocator<char> >
    996 bitset<_Size>::to_string(char __zero, char __one) const
    997 {
    998     return to_string<char, char_traits<char>, allocator<char> >(__zero, __one);
    999 }
   1000 
   1001 template <size_t _Size>
   1002 inline
   1003 size_t
   1004 bitset<_Size>::count() const _NOEXCEPT
   1005 {
   1006     return static_cast<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true));
   1007 }
   1008 
   1009 template <size_t _Size>
   1010 inline
   1011 bool
   1012 bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
   1013 {
   1014     return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0));
   1015 }
   1016 
   1017 template <size_t _Size>
   1018 inline
   1019 bool
   1020 bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
   1021 {
   1022     return !(*this == __rhs);
   1023 }
   1024 
   1025 template <size_t _Size>
   1026 bool
   1027 bitset<_Size>::test(size_t __pos) const
   1028 {
   1029     if (__pos >= _Size)
   1030 #ifndef _LIBCPP_NO_EXCEPTIONS
   1031         throw out_of_range("bitset test argument out of range");
   1032 #else
   1033         assert(!"bitset test argument out of range");
   1034 #endif
   1035     return (*this)[__pos];
   1036 }
   1037 
   1038 template <size_t _Size>
   1039 inline
   1040 bool
   1041 bitset<_Size>::all() const _NOEXCEPT
   1042 {
   1043     return base::all();
   1044 }
   1045 
   1046 template <size_t _Size>
   1047 inline
   1048 bool
   1049 bitset<_Size>::any() const _NOEXCEPT
   1050 {
   1051     return base::any();
   1052 }
   1053 
   1054 template <size_t _Size>
   1055 inline
   1056 bitset<_Size>
   1057 bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT
   1058 {
   1059     bitset __r = *this;
   1060     __r <<= __pos;
   1061     return __r;
   1062 }
   1063 
   1064 template <size_t _Size>
   1065 inline
   1066 bitset<_Size>
   1067 bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT
   1068 {
   1069     bitset __r = *this;
   1070     __r >>= __pos;
   1071     return __r;
   1072 }
   1073 
   1074 template <size_t _Size>
   1075 inline _LIBCPP_INLINE_VISIBILITY
   1076 bitset<_Size>
   1077 operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
   1078 {
   1079     bitset<_Size> __r = __x;
   1080     __r &= __y;
   1081     return __r;
   1082 }
   1083 
   1084 template <size_t _Size>
   1085 inline _LIBCPP_INLINE_VISIBILITY
   1086 bitset<_Size>
   1087 operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
   1088 {
   1089     bitset<_Size> __r = __x;
   1090     __r |= __y;
   1091     return __r;
   1092 }
   1093 
   1094 template <size_t _Size>
   1095 inline _LIBCPP_INLINE_VISIBILITY
   1096 bitset<_Size>
   1097 operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
   1098 {
   1099     bitset<_Size> __r = __x;
   1100     __r ^= __y;
   1101     return __r;
   1102 }
   1103 
   1104 template <size_t _Size>
   1105 struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >
   1106     : public unary_function<bitset<_Size>, size_t>
   1107 {
   1108     _LIBCPP_INLINE_VISIBILITY
   1109     size_t operator()(const bitset<_Size>& __bs) const _NOEXCEPT
   1110         {return __bs.__hash_code();}
   1111 };
   1112 
   1113 template <class _CharT, class _Traits, size_t _Size>
   1114 basic_istream<_CharT, _Traits>&
   1115 operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x);
   1116 
   1117 template <class _CharT, class _Traits, size_t _Size>
   1118 basic_ostream<_CharT, _Traits>&
   1119 operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x);
   1120 
   1121 _LIBCPP_END_NAMESPACE_STD
   1122 
   1123 #endif  // _LIBCPP_BITSET
   1124