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
This commit is contained in:
Phil Edwards 2002-05-24 18:16:00 +00:00
parent f64ce6c6e8
commit bb12c8093d
3 changed files with 142 additions and 2 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}