aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPhil Edwards <pme@gcc.gnu.org>2002-05-24 18:16:00 +0000
committerPhil Edwards <pme@gcc.gnu.org>2002-05-24 18:16:00 +0000
commitbb12c8093d162a070cb95ab4992b61e6c7bc0d55 (patch)
tree64cbc6d37ff26c3e44f42580a98927151bac8906 /libstdc++-v3
parentf64ce6c6e8c268a3cbac3799d9264e94192a78a5 (diff)
downloadgcc-bb12c8093d162a070cb95ab4992b61e6c7bc0d55.zip
gcc-bb12c8093d162a070cb95ab4992b61e6c7bc0d55.tar.gz
gcc-bb12c8093d162a070cb95ab4992b61e6c7bc0d55.tar.bz2
std_bitset.h (_Base_biteset<0>): New specialization.
2002-05-24 Phil Edwards <pme@gcc.gnu.org> libstdc++/6282 * include/std/std_bitset.h (_Base_biteset<0>): New specialization. (operator>>): If nothing was extracted, don't fail in the zero-length case. * testsuite/23_containers/bitset_ctor.cc (test02): New test. From-SVN: r53844
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/std/std_bitset.h99
-rw-r--r--libstdc++-v3/testsuite/23_containers/bitset_ctor.cc37
3 files changed, 142 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 3bfa38e..67878c1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2002-05-24 Phil Edwards <pme@gcc.gnu.org>
+
+ libstdc++/6282
+ * include/std/std_bitset.h (_Base_biteset<0>): New specialization.
+ (operator>>): If nothing was extracted, don't fail in the
+ zero-length case.
+ * testsuite/23_containers/bitset_ctor.cc (test02): New test.
+
2002-05-24 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/6701
diff --git a/libstdc++-v3/include/std/std_bitset.h b/libstdc++-v3/include/std/std_bitset.h
index 0945c90..fe60b01 100644
--- a/libstdc++-v3/include/std/std_bitset.h
+++ b/libstdc++-v3/include/std/std_bitset.h
@@ -61,7 +61,7 @@
#define _GLIBCPP_BITSET_BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long))
#define _GLIBCPP_BITSET_WORDS(__n) \
- ((__n) < 1 ? 1 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD)
+ ((__n) < 1 ? 0 : ((__n) + _GLIBCPP_BITSET_BITS_PER_WORD - 1)/_GLIBCPP_BITSET_BITS_PER_WORD)
namespace std
{
@@ -463,6 +463,101 @@ namespace std
_M_do_find_next(size_t __prev, size_t __not_found) const;
};
+
+ /**
+ * @if maint
+ * Base class, specialization for no storage (zero-length %bitset).
+ *
+ * See documentation for bitset.
+ * @endif
+ */
+ template<>
+ struct _Base_bitset<0>
+ {
+ typedef unsigned long _WordT;
+
+ _Base_bitset() {}
+ _Base_bitset(unsigned long) {}
+
+ static size_t
+ _S_whichword(size_t __pos )
+ { return __pos / _GLIBCPP_BITSET_BITS_PER_WORD; }
+
+ static size_t
+ _S_whichbyte(size_t __pos )
+ { return (__pos % _GLIBCPP_BITSET_BITS_PER_WORD) / CHAR_BIT; }
+
+ static size_t
+ _S_whichbit(size_t __pos )
+ { return __pos % _GLIBCPP_BITSET_BITS_PER_WORD; }
+
+ static _WordT
+ _S_maskbit(size_t __pos )
+ { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
+
+ // This would normally give access to the data. The bounds-checking
+ // in the bitset class will prevent the user from getting this far,
+ // but (1) it must still return an lvalue to compile, and (2) the
+ // user might call _Unchecked_set directly, in which case this /needs/
+ // to fail. Let's not penalize zero-length users unless they actually
+ // 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
+ { __throw_out_of_range("bitset -- zero-length"); return *new _WordT; }
+
+ _WordT
+ _M_hiword() const { return 0; }
+
+ void
+ _M_do_and(const _Base_bitset<0>&) { }
+
+ void
+ _M_do_or(const _Base_bitset<0>&) { }
+
+ void
+ _M_do_xor(const _Base_bitset<0>&) { }
+
+ void
+ _M_do_left_shift(size_t) { }
+
+ void
+ _M_do_right_shift(size_t) { }
+
+ void
+ _M_do_flip() { }
+
+ void
+ _M_do_set() { }
+
+ void
+ _M_do_reset() { }
+
+ // Are all empty bitsets equal to each other? Are they equal to
+ // themselves? How to compare a thing which has no state? What is
+ // the sound of one zero-length bitset clapping?
+ bool
+ _M_is_equal(const _Base_bitset<0>&) const { return true; }
+
+ bool
+ _M_is_any() const { return false; }
+
+ size_t
+ _M_do_count() const { return 0; }
+
+ unsigned long
+ _M_do_to_ulong() const { return 0; }
+
+ // Normally "not found" is the size, but that could also be
+ // misinterpreted as an index in this corner case. Oh well.
+ size_t
+ _M_do_find_first(size_t) const { return 0; }
+
+ size_t
+ _M_do_find_next(size_t, size_t) const { return 0; }
+ };
+
+
// Helper class to zero out the unused high-order bits in the highest word.
template<size_t _Extrabits>
struct _Sanitize
@@ -1115,7 +1210,7 @@ namespace std
}
}
- if (__tmp.empty())
+ if (__tmp.empty() && !_Nb)
__is.setstate(ios_base::failbit);
else
__x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb);
diff --git a/libstdc++-v3/testsuite/23_containers/bitset_ctor.cc b/libstdc++-v3/testsuite/23_containers/bitset_ctor.cc
index c568e22..8dae3ad 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset_ctor.cc
+++ b/libstdc++-v3/testsuite/23_containers/bitset_ctor.cc
@@ -81,9 +81,46 @@ bool test01(void)
return test;
}
+// boundary condition: a zero-sized set
+// libstdc++/6282
+bool test02(void)
+{
+ using std::char_traits; using std::allocator;
+ bool test = true;
+
+ std::bitset<0> z1;
+ VERIFY( z1.any() == false );
+
+ std::bitset<0> z2(12345);
+ VERIFY( z2.any() == false );
+
+ std::bitset<0> z3(std::string("10101010101"));
+ VERIFY( z3.any() == false );
+
+ try {
+ z1.set(0);
+ VERIFY( false );
+ }
+ catch(std::out_of_range& fail) {
+ VERIFY( true );
+ }
+ catch(...) {
+ VERIFY( false );
+ }
+
+ VERIFY( z1.to_ulong() == 0 );
+ VERIFY( ( z1.to_string<char,char_traits<char>,allocator<char> >().empty() ) );
+
+#ifdef DEBUG_ASSERT
+ assert(test);
+#endif
+ return test;
+}
+
int main()
{
test01();
+ test02();
return 0;
}