OSDN Git Service

2011-09-02 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 Sep 2011 10:28:36 +0000 (10:28 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 Sep 2011 10:28:36 +0000 (10:28 +0000)
    Marc Glisse  <marc.glisse@normalesup.org>

PR libstdc++/50268
* include/std/bitset (struct _Sanitize_val): Add.
(bitset<>::bitset(unsigned long long)): Fix.
* testsuite/23_containers/bitset/cons/50268.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178463 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/bitset
libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc [new file with mode: 0644]

index 386a15e..bd9850c 100644 (file)
@@ -1,3 +1,11 @@
+2011-09-02  Paolo Carlini  <paolo.carlini@oracle.com>
+           Marc Glisse  <marc.glisse@normalesup.org>
+
+       PR libstdc++/50268
+       * include/std/bitset (struct _Sanitize_val): Add.
+       (bitset<>::bitset(unsigned long long)): Fix.
+       * testsuite/23_containers/bitset/cons/50268.cc: New.
+
 2011-09-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * include/bits/hashtable.h (_Hashtable<>::_Hashtable(_Hashtable&&)):
index 5829726..648d7ab 100644 (file)
 #include <iosfwd>
 #include <bits/cxxabi_forced.h>
 
-#define _GLIBCXX_BITSET_BITS_PER_WORD  (__CHAR_BIT__ * sizeof(unsigned long))
+#define _GLIBCXX_BITSET_BITS_PER_WORD  (__CHAR_BIT__ * __SIZEOF_LONG__)
 #define _GLIBCXX_BITSET_WORDS(__n) \
   ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \
    ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1))
 
+#define _GLIBCXX_BITSET_BITS_PER_ULL (__CHAR_BIT__ * __SIZEOF_LONG_LONG__)
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
@@ -657,6 +659,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _S_do_sanitize(_WordT) _GLIBCXX_NOEXCEPT { } 
     };
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+  template<size_t _Nb, bool = _Nb < _GLIBCXX_BITSET_BITS_PER_ULL>
+    struct _Sanitize_val
+    {
+      static constexpr unsigned long long
+      _S_do_sanitize_val(unsigned long long __val)
+      { return __val; }
+    };
+
+  template<size_t _Nb>
+    struct _Sanitize_val<_Nb, true>
+    {
+      static constexpr unsigned long long
+      _S_do_sanitize_val(unsigned long long __val)
+      { return __val & ~((~static_cast<unsigned long long>(0)) << _Nb); }
+    };
+#endif
+
   /**
    *  @brief  The %bitset class represents a @e fixed-size sequence of bits.
    *
@@ -822,7 +842,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /// Initial bits bitwise-copied from a single word (others set to zero).
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       constexpr bitset(unsigned long long __val) noexcept
-      : _Base(__val) { }
+      : _Base(_Sanitize_val<_Nb>::_S_do_sanitize_val(__val)) { }
 #else
       bitset(unsigned long __val)
       : _Base(__val)
@@ -1513,6 +1533,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
 
 #undef _GLIBCXX_BITSET_WORDS
 #undef _GLIBCXX_BITSET_BITS_PER_WORD
+#undef _GLIBCXX_BITSET_BITS_PER_ULL
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
 
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc b/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc
new file mode 100644 (file)
index 0000000..6a61d7e
--- /dev/null
@@ -0,0 +1,84 @@
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2011 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 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// 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 COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <bitset>
+#include <testsuite_hooks.h>
+
+// libstdc++/50268
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  std::bitset<1> b1(3ULL);
+  VERIFY( b1.count() == 1ULL );
+
+  std::bitset<3> b2(30ULL);
+  VERIFY( b2.count() == 2ULL );
+
+  std::bitset<6> b3(300ULL);
+  VERIFY( b3.count() == 3ULL );
+
+  std::bitset<9> b4(3000ULL);
+  VERIFY( b4.count() == 5ULL );
+
+  std::bitset<16> b5(300000ULL);
+  VERIFY( b5.count() == 7ULL );
+
+  std::bitset<24> b6(30000000ULL);
+  VERIFY( b6.count() == 9ULL );
+
+  std::bitset<32> b7(30000000000ULL);
+  VERIFY( b7.count() == 13ULL );
+
+  std::bitset<37> b8(3000000000000ULL);
+  VERIFY( b8.count() == 18ULL );
+
+  std::bitset<40> b9(30000000000000ULL);
+  VERIFY( b9.count() == 16ULL );
+
+  std::bitset<45> b10(30000000000000ULL);
+  VERIFY( b10.count() == 20ULL );
+
+  std::bitset<64> b11(30000000000000ULL);
+  VERIFY( b11.count() == 20ULL );
+
+  std::bitset<100> b12(30000000000000ULL);
+  VERIFY( b12.count() == 20ULL );
+
+  std::bitset<200> b13(30000000000000ULL);
+  VERIFY( b13.count() == 20ULL );
+
+  std::bitset<45> b14(18446744073709551615ULL);
+  VERIFY( b14.count() == 45ULL );
+
+  std::bitset<64> b15(18446744073709551615ULL);
+  VERIFY( b15.count() == 64ULL );
+
+  std::bitset<100> b16(18446744073709551615ULL);
+  VERIFY( b16.count() == 64ULL );
+
+  std::bitset<200> b17(18446744073709551615ULL);
+  VERIFY( b17.count() == 64ULL );  
+}
+
+int main()
+{
+  test01();
+  return 0;
+}