OSDN Git Service

2010-12-08 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / bitset
index 131a7e3..86f361c 100644 (file)
@@ -1,12 +1,12 @@
 // <bitset> -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 // terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
+// Free Software Foundation; either version 3, or (at your option)
 // any later version.
 
 // This library is distributed in the hope that it will be useful,
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02110-1301, USA.
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
 
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
 
 /*
  * Copyright (c) 1998
@@ -50,7 +45,6 @@
 
 #pragma GCC system_header
 
-#include <cstddef>     // For size_t
 #include <string>
 #include <bits/functexcept.h>   // For invalid_argument, out_of_range,
                                 // overflow_error
@@ -59,8 +53,8 @@
 
 #define _GLIBCXX_BITSET_BITS_PER_WORD  (__CHAR_BIT__ * sizeof(unsigned long))
 #define _GLIBCXX_BITSET_WORDS(__n) \
((__n) < 1 ? 0 : ((__n) + _GLIBCXX_BITSET_BITS_PER_WORD - 1) \
-                  / _GLIBCXX_BITSET_BITS_PER_WORD)
 ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \
+   ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1))
 
 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
 
@@ -78,28 +72,35 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       /// 0 is the least significant word.
       _WordT           _M_w[_Nw];
 
-      _Base_bitset()
-      { _M_do_reset(); }
+      _GLIBCXX_CONSTEXPR _Base_bitset()
+      : _M_w() { }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      constexpr _Base_bitset(unsigned long long __val)
+      : _M_w({ _WordT(__val)
+#if __SIZEOF_LONG_LONG__ > __SIZEOF_LONG__
+              , _WordT(__val >> _GLIBCXX_BITSET_BITS_PER_WORD)
+#endif
+       }) { }
+#else
       _Base_bitset(unsigned long __val)
-      {
-       _M_do_reset();
-       _M_w[0] = __val;
-      }
+      : _M_w()
+      { _M_w[0] = __val; }
+#endif
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichword(size_t __pos )
       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichbyte(size_t __pos )
       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichbit(size_t __pos )
       { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
 
-      static _WordT
+      static _GLIBCXX_CONSTEXPR _WordT
       _S_maskbit(size_t __pos )
       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
 
@@ -111,11 +112,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       _M_getword(size_t __pos) const
       { return _M_w[_S_whichword(__pos)]; }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      const _WordT*
+      _M_getdata() const
+      { return _M_w; }
+#endif
+
       _WordT&
       _M_hiword()
       { return _M_w[_Nw - 1]; }
 
-      _WordT
+      _GLIBCXX_CONSTEXPR _WordT
       _M_hiword() const
       { return _M_w[_Nw - 1]; }
 
@@ -204,6 +211,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       unsigned long
       _M_do_to_ulong() const;
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      unsigned long long
+      _M_do_to_ullong() const;
+#endif
+
       // find first "on" bit
       size_t
       _M_do_find_first(size_t __not_found) const;
@@ -277,6 +289,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       return _M_w[0];
     }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  template<size_t _Nw>
+    unsigned long long
+    _Base_bitset<_Nw>::_M_do_to_ullong() const
+    {
+      const bool __dw = sizeof(unsigned long long) > sizeof(unsigned long);
+      for (size_t __i = 1 + __dw; __i < _Nw; ++__i)
+       if (_M_w[__i])
+         __throw_overflow_error(__N("_Base_bitset::_M_do_to_ullong"));
+
+      if (__dw)
+       return _M_w[0] + (static_cast<unsigned long long>(_M_w[1])
+                         << _GLIBCXX_BITSET_BITS_PER_WORD);
+      return _M_w[0];
+    }
+#endif
+
   template<size_t _Nw>
     size_t
     _Base_bitset<_Nw>::_M_do_find_first(size_t __not_found) const
@@ -338,27 +367,31 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       typedef unsigned long _WordT;
       _WordT _M_w;
 
-      _Base_bitset(void)
+      _GLIBCXX_CONSTEXPR _Base_bitset()
       : _M_w(0)
       { }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      constexpr _Base_bitset(unsigned long long __val)
+#else
       _Base_bitset(unsigned long __val)
+#endif
       : _M_w(__val)
       { }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichword(size_t __pos )
       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichbyte(size_t __pos )
       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichbit(size_t __pos )
       {  return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
 
-      static _WordT
+      static _GLIBCXX_CONSTEXPR _WordT
       _S_maskbit(size_t __pos )
       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
 
@@ -370,11 +403,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       _M_getword(size_t) const
       { return _M_w; }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      const _WordT*
+      _M_getdata() const
+      { return &_M_w; }
+#endif
+
       _WordT&
       _M_hiword()
       { return _M_w; }
 
-      _WordT
+      _GLIBCXX_CONSTEXPR _WordT
       _M_hiword() const
       { return _M_w; }
 
@@ -430,6 +469,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       _M_do_to_ulong() const
       { return _M_w; }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      unsigned long long
+      _M_do_to_ullong() const
+      { return _M_w; }
+#endif
+
       size_t
       _M_do_find_first(size_t __not_found) const
       {
@@ -465,25 +510,29 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
     {
       typedef unsigned long _WordT;
 
-      _Base_bitset()
+      _GLIBCXX_CONSTEXPR _Base_bitset()
       { }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      constexpr _Base_bitset(unsigned long long)
+#else
       _Base_bitset(unsigned long)
+#endif
       { }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichword(size_t __pos )
       { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichbyte(size_t __pos )
       { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; }
 
-      static size_t
+      static _GLIBCXX_CONSTEXPR size_t
       _S_whichbit(size_t __pos )
       {  return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; }
 
-      static _WordT
+      static _GLIBCXX_CONSTEXPR _WordT
       _S_maskbit(size_t __pos )
       { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
 
@@ -495,13 +544,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       // make an unchecked call; all the memory ugliness is therefore
       // localized to this single should-never-get-this-far function.
       _WordT&
-      _M_getword(size_t) const
+      _M_getword(size_t)
       { 
        __throw_out_of_range(__N("_Base_bitset::_M_getword")); 
        return *new _WordT; 
       }
 
       _WordT
+      _M_getword(size_t __pos) const
+      { return 0; }
+
+      _GLIBCXX_CONSTEXPR _WordT
       _M_hiword() const
       { return 0; }
 
@@ -560,6 +613,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       _M_do_to_ulong() const
       { return 0; }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      unsigned long long
+      _M_do_to_ullong() const
+      { return 0; }
+#endif
+
       // Normally "not found" is the size, but that could also be
       // misinterpreted as an index in this corner case.  Oh well.
       size_t
@@ -576,13 +635,21 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
   template<size_t _Extrabits>
     struct _Sanitize
     {
-      static void _S_do_sanitize(unsigned long& __val)
-      { __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
+      typedef unsigned long _WordT;
+
+      static void 
+      _S_do_sanitize(_WordT& __val)
+      { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); }
     };
 
   template<>
     struct _Sanitize<0>
-    { static void _S_do_sanitize(unsigned long) {} };
+    { 
+      typedef unsigned long _WordT;
+
+      static void 
+      _S_do_sanitize(_WordT) { } 
+    };
 
   /**
    *  @brief  The %bitset class represents a @e fixed-size sequence of bits.
@@ -601,16 +668,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
    *  the high-order bits in the highest word.)  It is a class invariant
    *  that those unused bits are always zero.
    *
-   *  If you think of %bitset as "a simple array of bits," be aware that
-   *  your mental picture is reversed:  a %bitset behaves the same way as
-   *  bits in integers do, with the bit at index 0 in the "least significant
-   *  / right-hand" position, and the bit at index Nb-1 in the "most
-   *  significant / left-hand" position.  Thus, unlike other containers, a
-   *  %bitset's index "counts from right to left," to put it very loosely.
+   *  If you think of %bitset as <em>a simple array of bits</em>, be
+   *  aware that your mental picture is reversed: a %bitset behaves
+   *  the same way as bits in integers do, with the bit at index 0 in
+   *  the <em>least significant / right-hand</em> position, and the bit at
+   *  index Nb-1 in the <em>most significant / left-hand</em> position.
+   *  Thus, unlike other containers, a %bitset's index <em>counts from
+   *  right to left</em>, to put it very loosely.
    *
    *  This behavior is preserved when translating to and from strings.  For
    *  example, the first line of the following program probably prints
-   *  "b('a') is 0001100001" on a modern ASCII system.
+   *  <em>b(&apos;a&apos;) is 0001100001</em> on a modern ASCII system.
    *
    *  @code
    *     #include <bitset>
@@ -656,11 +724,15 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       typedef unsigned long _WordT;
 
       void
-       _M_do_sanitize()
-       {
-         _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD>::
-           _S_do_sanitize(this->_M_hiword());
-       }
+      _M_do_sanitize()
+      { 
+       typedef _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD> __sanitize_type;
+       __sanitize_type::_S_do_sanitize(this->_M_hiword());
+      }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      template<typename> friend class hash;
+#endif
 
     public:
       /**
@@ -672,15 +744,15 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
        *  to and from bool are automatic and should be transparent.  Overloaded
        *  operators help to preserve the illusion.
        *
-       *  (On a typical system, this "bit %reference" is 64 times the size of
-       *  an actual bit.  Ha.)
+       *  (On a typical system, this <em>bit %reference</em> is 64
+       *  times the size of an actual bit.  Ha.)
        */
       class reference
       {
        friend class bitset;
 
-       _WordT *_M_wp;
-       size_t _M_bpos;
+       _WordT_M_wp;
+       size_t  _M_bpos;
        
        // left undefined
        reference();
@@ -738,22 +810,27 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
 
       // 23.3.5.1 constructors:
       /// All bits set to zero.
-      bitset()
+      _GLIBCXX_CONSTEXPR bitset()
       { }
 
       /// Initial bits bitwise-copied from a single word (others set to zero).
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      constexpr bitset(unsigned long long __val)
+      : _Base(__val) { }
+#else
       bitset(unsigned long __val)
       : _Base(__val)
       { _M_do_sanitize(); }
+#endif
 
       /**
        *  @brief  Use a subset of a string.
-       *  @param  s  A string of '0' and '1' characters.
+       *  @param  s  A string of @a 0 and @a 1 characters.
        *  @param  position  Index of the first character in @a s to use;
        *                    defaults to zero.
        *  @throw  std::out_of_range  If @a pos is bigger the size of @a s.
        *  @throw  std::invalid_argument  If a character appears in the string
-       *                                 which is neither '0' nor '1'.
+       *                                 which is neither @a 0 nor @a 1.
        */
       template<class _CharT, class _Traits, class _Alloc>
        explicit
@@ -771,12 +848,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
 
       /**
        *  @brief  Use a subset of a string.
-       *  @param  s  A string of '0' and '1' characters.
+       *  @param  s  A string of @a 0 and @a 1 characters.
        *  @param  position  Index of the first character in @a s to use.
        *  @param  n    The number of characters to copy.
        *  @throw  std::out_of_range  If @a pos is bigger the size of @a s.
        *  @throw  std::invalid_argument  If a character appears in the string
-       *                                 which is neither '0' nor '1'.
+       *                                 which is neither @a 0 nor @a 1.
        */
       template<class _CharT, class _Traits, class _Alloc>
        bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
@@ -803,6 +880,35 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
          _M_copy_from_string(__s, __position, __n, __zero, __one);
        }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      /**
+       *  @brief  Construct from a character %array.
+       *  @param  str  An %array of characters @a zero and @a one.
+       *  @param  n    The number of characters to use.
+       *  @param  zero The character corresponding to the value 0.
+       *  @param  one  The character corresponding to the value 1.
+       *  @throw  std::invalid_argument  If a character appears in the string
+       *                                 which is neither @a zero nor @a one.
+       */
+      template<typename _CharT>
+        explicit
+        bitset(const _CharT* __str,
+              typename std::basic_string<_CharT>::size_type __n
+              = std::basic_string<_CharT>::npos,
+              _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'))
+        : _Base()
+        {
+         if (!__str)
+           __throw_logic_error(__N("bitset::bitset(const _CharT*, ...)"));
+
+         if (__n == std::basic_string<_CharT>::npos)
+           __n = std::char_traits<_CharT>::length(__str);
+         _M_copy_from_ptr<_CharT, std::char_traits<_CharT>>(__str, __n, 0,
+                                                            __n, __zero,
+                                                            __one);
+       }
+#endif
+
       // 23.3.5.2 bitset operations:
       //@{
       /**
@@ -994,8 +1100,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       /**
        *  @brief  Array-indexing support.
        *  @param  position  Index into the %bitset.
-       *  @return  A bool for a 'const %bitset'.  For non-const bitsets, an
-       *           instance of the reference proxy class.
+       *  @return A bool for a <em>const %bitset</em>.  For non-const
+       *           bitsets, an instance of the reference proxy class.
        *  @note  These operators do no range checking and throw no exceptions,
        *         as required by DR 11 to the standard.
        *
@@ -1007,7 +1113,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
        */
       reference
       operator[](size_t __position)
-      { return reference(*this,__position); }
+      { return reference(*this, __position); }
 
       bool
       operator[](size_t __position) const
@@ -1024,6 +1130,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       to_ulong() const
       { return this->_M_do_to_ulong(); }
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      unsigned long long
+      to_ullong() const
+      { return this->_M_do_to_ullong(); }
+#endif
+
       /**
        *  @brief Returns a character interpretation of the %bitset.
        *  @return  The string equivalent of the bits.
@@ -1136,7 +1248,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
       { return this->_M_do_count(); }
 
       /// Returns the total number of bits.
-      size_t
+      _GLIBCXX_CONSTEXPR size_t
       size() const
       { return _Nb; }
 
@@ -1302,7 +1414,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
    *  @brief Global I/O operators for bitsets.
    *
    *  Direct I/O between streams and bitsets is supported.  Output is
-   *  straightforward.  Input will skip whitespace, only accept '0' and '1'
+   *  straightforward.  Input will skip whitespace, only accept @a 0 and @a 1
    *  characters, and will only extract as many digits as the %bitset will
    *  hold.
   */
@@ -1394,8 +1506,45 @@ _GLIBCXX_END_NESTED_NAMESPACE
 #undef _GLIBCXX_BITSET_WORDS
 #undef _GLIBCXX_BITSET_BITS_PER_WORD
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+
+#include <bits/functional_hash.h>
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
+  // DR 1182.
+  /// std::hash specialization for bitset.
+  template<size_t _Nb>
+    struct hash<_GLIBCXX_STD_D::bitset<_Nb>>
+    : public __hash_base<size_t, _GLIBCXX_STD_D::bitset<_Nb>>
+    {
+      size_t
+      operator()(const _GLIBCXX_STD_D::bitset<_Nb>& __b) const
+      {
+       const size_t __clength = (_Nb + __CHAR_BIT__ - 1) / __CHAR_BIT__;
+       return std::_Hash_impl::hash(__b._M_getdata(), __clength);
+      }
+    };
+
+  template<>
+    struct hash<_GLIBCXX_STD_D::bitset<0>>
+    : public __hash_base<size_t, _GLIBCXX_STD_D::bitset<0>>
+    {
+      size_t
+      operator()(const _GLIBCXX_STD_D::bitset<0>&) const
+      { return 0; }
+    };
+
+_GLIBCXX_END_NAMESPACE
+
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
 #ifdef _GLIBCXX_DEBUG
 # include <debug/bitset>
 #endif
 
+#ifdef _GLIBCXX_PROFILE
+# include <profile/bitset>
+#endif
+
 #endif /* _GLIBCXX_BITSET */