Implement DR 396 [Ready].

2008-09-23  Paolo Carlini  <paolo.carlini@oracle.com>

	Implement DR 396 [Ready].
	* include/std/bitset (bitset<>::bitset(const std::basic_string<>&,
	size_t, size_t, _CharT, _CharT), bitset<>::bitset(const char*,
	char, char), bitset<>::to_string(_CharT, _CharT),
	bitset<>::_M_copy_from_string(const std::basic_string<>&, size_t,
	size_t, _CharT, _CharT), bitset<>::_M_copy_to_string
	(std::basic_string<>&, _CharT, _CharT), bitset<>::_M_copy_from_ptr(
	const _CharT*, size_t, size_t, size_t, _CharT, _CharT)): Add.
	(operator>>(std::basic_istream<>&, bitset<_Nb>&), operator<<(
	std::basic_ostream<>&, const bitset<_Nb>&)): Adjust.
	* include/debug/bitset (bitset<>::bitset(const std::basic_string<>&,
	size_t, size_t, _CharT, _CharT), bitset<>::bitset(const char*,
	char, char), bitset<>::to_string(_CharT, _CharT)): Add.
	* doc/xml/manual/intro.xml: Add an entry for DR 396.
	* testsuite/23_containers/bitset/cons/dr396.cc: Add.
	* testsuite/23_containers/bitset/to_string/dr396.cc: Likewise.

From-SVN: r140607
This commit is contained in:
Paolo Carlini 2008-09-23 18:14:24 +00:00 committed by Paolo Carlini
parent 37e27d01ca
commit 47cd155763
6 changed files with 324 additions and 50 deletions

View File

@ -1,3 +1,22 @@
2008-09-23 Paolo Carlini <paolo.carlini@oracle.com>
Implement DR 396 [Ready].
* include/std/bitset (bitset<>::bitset(const std::basic_string<>&,
size_t, size_t, _CharT, _CharT), bitset<>::bitset(const char*,
char, char), bitset<>::to_string(_CharT, _CharT),
bitset<>::_M_copy_from_string(const std::basic_string<>&, size_t,
size_t, _CharT, _CharT), bitset<>::_M_copy_to_string
(std::basic_string<>&, _CharT, _CharT), bitset<>::_M_copy_from_ptr(
const _CharT*, size_t, size_t, size_t, _CharT, _CharT)): Add.
(operator>>(std::basic_istream<>&, bitset<_Nb>&), operator<<(
std::basic_ostream<>&, const bitset<_Nb>&)): Adjust.
* include/debug/bitset (bitset<>::bitset(const std::basic_string<>&,
size_t, size_t, _CharT, _CharT), bitset<>::bitset(const char*,
char, char), bitset<>::to_string(_CharT, _CharT)): Add.
* doc/xml/manual/intro.xml: Add an entry for DR 396.
* testsuite/23_containers/bitset/cons/dr396.cc: Add.
* testsuite/23_containers/bitset/to_string/dr396.cc: Likewise.
2008-09-23 Chris Fairles <cfairles@gcc.gnu.org>
* include/std/chrono: If _GLIBCXX_USE_MONOTONIC_CLOCK is defined, don't

View File

@ -522,6 +522,12 @@
<listitem><para>Change it to return a <code>const T&amp;</code>.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="../ext/lwg-active.html#396">396</ulink>:
<emphasis>what are characters zero and one</emphasis>
</term>
<listitem><para>Implement the proposed resolution.
</para></listitem></varlistentry>
<varlistentry><term><ulink url="../ext/lwg-defects.html#402">402</ulink>:
<emphasis>Wrong new expression in [some_]allocator::construct</emphasis>
</term>

View File

@ -1,6 +1,7 @@
// Debugging bitset implementation -*- C++ -*-
// Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
// 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
@ -125,20 +126,31 @@ namespace __debug
bitset(unsigned long __val) : _Base(__val) { }
template<typename _CharT, typename _Traits, typename _Allocator>
template<typename _CharT, typename _Traits, typename _Alloc>
explicit
bitset(const std::basic_string<_CharT,_Traits,_Allocator>& __str,
typename std::basic_string<_CharT,_Traits,_Allocator>::size_type
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__pos = 0,
typename std::basic_string<_CharT,_Traits,_Allocator>::size_type
__n = (std::basic_string<_CharT,_Traits,_Allocator>::npos))
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__n = (std::basic_string<_CharT, _Traits, _Alloc>::npos))
: _Base(__str, __pos, __n) { }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__pos,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__n,
_CharT __zero, _CharT __one = _CharT('1'))
: _Base(__str, __pos, __n, __zero, __one) { }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 778. std::bitset does not have any constructor taking a string literal
explicit
bitset(const char* __s)
: _Base(__s) { }
bitset(const char* __s, char __zero = '0', char __one = '1')
: _Base(__s, __zero, __one) { }
bitset(const _Base& __x) : _Base(__x), _Safe_base() { }
@ -245,10 +257,20 @@ namespace __debug
using _Base::to_ulong;
template <typename _CharT, typename _Traits, typename _Allocator>
std::basic_string<_CharT, _Traits, _Allocator>
template <typename _CharT, typename _Traits, typename _Alloc>
std::basic_string<_CharT, _Traits, _Alloc>
to_string() const
{ return _M_base().template to_string<_CharT, _Traits, _Allocator>(); }
{ return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
std::basic_string<_CharT, _Traits, _Alloc>
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
return _M_base().template
to_string<_CharT, _Traits, _Alloc>(__zero, __one);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 434. bitset::to_string() hard to use.
@ -257,6 +279,14 @@ namespace __debug
to_string() const
{ return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits>
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{ return to_string<_CharT, _Traits,
std::allocator<_CharT> >(__zero, __one); }
template<typename _CharT>
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
@ -266,11 +296,27 @@ namespace __debug
std::allocator<_CharT> >();
}
template<class _CharT>
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
return to_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >(__zero, __one);
}
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string() const
{
return to_string<char,std::char_traits<char>,std::allocator<char> >();
}
to_string() const
{
return to_string<char,std::char_traits<char>,std::allocator<char> >();
}
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string(char __zero, char __one = '1') const
{
return to_string<char, std::char_traits<char>,
std::allocator<char> >(__zero, __one);
}
using _Base::count;
using _Base::size;

View File

@ -764,7 +764,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
__throw_out_of_range(__N("bitset::bitset initial position "
"not valid"));
_M_copy_from_string(__s, __position,
std::basic_string<_CharT, _Traits, _Alloc>::npos);
std::basic_string<_CharT, _Traits, _Alloc>::npos,
_CharT('0'), _CharT('1'));
}
/**
@ -784,15 +785,33 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
if (__position > __s.size())
__throw_out_of_range(__N("bitset::bitset initial position "
"not valid"));
_M_copy_from_string(__s, __position, __n);
_M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1'));
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
size_t __position, size_t __n,
_CharT __zero, _CharT __one = _CharT('1'))
: _Base()
{
if (__position > __s.size())
__throw_out_of_range(__N("bitset::bitset initial position "
"not valid"));
_M_copy_from_string(__s, __position, __n, __zero, __one);
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 778. std::bitset does not have any constructor taking a string literal
explicit
bitset(const char* __s)
bitset(const char* __s, char __zero = '0', char __one = '1')
: _Base()
{ _M_copy_from_ptr(__s, char_traits<char>::length(__s), 0, size_t(-1)); }
{
_M_copy_from_ptr<char, char_traits<char> >(__s,
char_traits<char>::length(__s), 0, size_t(-1),
__zero, __one);
}
// 23.3.5.2 bitset operations:
//@{
@ -1028,7 +1047,18 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
to_string() const
{
std::basic_string<_CharT, _Traits, _Alloc> __result;
_M_copy_to_string(__result);
_M_copy_to_string(__result, _CharT('0'), _CharT('1'));
return __result;
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
std::basic_string<_CharT, _Traits, _Alloc>
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
std::basic_string<_CharT, _Traits, _Alloc> __result;
_M_copy_to_string(__result, __zero, __one);
return __result;
}
@ -1039,6 +1069,14 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
to_string() const
{ return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits>
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{ return to_string<_CharT, _Traits,
std::allocator<_CharT> >(__zero, __one); }
template<class _CharT>
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
@ -1048,6 +1086,15 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
std::allocator<_CharT> >();
}
template<class _CharT>
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
return to_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >(__zero, __one);
}
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string() const
{
@ -1055,20 +1102,43 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
std::allocator<char> >();
}
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string(char __zero, char __one = '1') const
{
return to_string<char, std::char_traits<char>,
std::allocator<char> >(__zero, __one);
}
// Helper functions for string operations.
template<class _CharT>
template<class _CharT, class _Traits>
void
_M_copy_from_ptr(const _CharT*, size_t, size_t, size_t);
_M_copy_from_ptr(const _CharT*, size_t, size_t, size_t,
_CharT, _CharT);
template<class _CharT, class _Traits, class _Alloc>
void
_M_copy_from_string(const std::basic_string<_CharT,
_Traits, _Alloc>& __s, size_t __pos, size_t __n)
{ _M_copy_from_ptr(__s.data(), __s.size(), __pos, __n); }
_Traits, _Alloc>& __s, size_t __pos, size_t __n,
_CharT __zero, _CharT __one)
{ _M_copy_from_ptr<_CharT, _Traits>(__s.data(), __s.size(), __pos, __n,
__zero, __one); }
template<class _CharT, class _Traits, class _Alloc>
void
_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&) const;
_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&,
_CharT, _CharT) const;
// NB: Backward compat.
template<class _CharT, class _Traits, class _Alloc>
void
_M_copy_from_string(const std::basic_string<_CharT,
_Traits, _Alloc>& __s, size_t __pos, size_t __n)
{ _M_copy_from_string(__s, __pos, __n, _CharT('0'), _CharT('1')); }
template<class _CharT, class _Traits, class _Alloc>
void
_M_copy_to_string(std::basic_string<_CharT, _Traits,_Alloc>& __s) const
{ _M_copy_to_string(__s, _CharT('0'), _CharT('1')); }
/// Returns the number of bits which are set.
size_t
@ -1166,26 +1236,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
// Definitions of non-inline member functions.
template<size_t _Nb>
template<class _CharT>
template<class _CharT, class _Traits>
void
bitset<_Nb>::
_M_copy_from_ptr(const _CharT* __s, size_t __len,
size_t __pos, size_t __n)
size_t __pos, size_t __n, _CharT __zero, _CharT __one)
{
reset();
const size_t __nbits = std::min(_Nb, std::min(__n, __len - __pos));
for (size_t __i = __nbits; __i > 0; --__i)
{
switch(__s[__pos + __nbits - __i])
{
case '0':
break;
case '1':
_Unchecked_set(__i - 1);
break;
default:
__throw_invalid_argument(__N("bitset::_M_copy_from_ptr"));
}
const _CharT __c = __s[__pos + __nbits - __i];
if (_Traits::eq(__c, __zero))
;
else if (_Traits::eq(__c, __one))
_Unchecked_set(__i - 1);
else
__throw_invalid_argument(__N("bitset::_M_copy_from_ptr"));
}
}
@ -1193,12 +1260,13 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
template<class _CharT, class _Traits, class _Alloc>
void
bitset<_Nb>::
_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s) const
_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s,
_CharT __zero, _CharT __one) const
{
__s.assign(_Nb, '0');
__s.assign(_Nb, __zero);
for (size_t __i = _Nb; __i > 0; --__i)
if (_Unchecked_test(__i - 1))
__s[_Nb - __i] = '1';
_Traits::assign(__s[_Nb - __i], __one);
}
// 23.3.5.3 bitset operations:
@ -1259,16 +1327,17 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
std::basic_string<_CharT, _Traits> __tmp;
__tmp.reserve(_Nb);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 303. Bitset input operator underspecified
const char_type __zero = __is.widen('0');
const char_type __one = __is.widen('1');
typename __ios_base::iostate __state = __ios_base::goodbit;
typename __istream_type::sentry __sentry(__is);
if (__sentry)
{
try
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 303. Bitset input operator underspecified
const char_type __zero = __is.widen('0');
const char_type __one = __is.widen('1');
for (size_t __i = _Nb; __i > 0; --__i)
{
static typename _Traits::int_type __eof = _Traits::eof();
@ -1282,10 +1351,10 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
else
{
const char_type __c2 = _Traits::to_char_type(__c1);
if (__c2 == __zero)
__tmp.push_back('0');
else if (__c2 == __one)
__tmp.push_back('1');
if (_Traits::eq(__c2, __zero))
__tmp.push_back(__zero);
else if (_Traits::eq(__c2, __one))
__tmp.push_back(__one);
else if (_Traits::
eq_int_type(__is.rdbuf()->sputbackc(__c2),
__eof))
@ -1308,7 +1377,8 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
if (__tmp.empty() && _Nb)
__state |= __ios_base::failbit;
else
__x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb);
__x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb,
__zero, __one);
if (__state)
__is.setstate(__state);
return __is;
@ -1320,7 +1390,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
const bitset<_Nb>& __x)
{
std::basic_string<_CharT, _Traits> __tmp;
__x._M_copy_to_string(__tmp);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__os.getloc());
__x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1'));
return __os << __tmp;
}
//@}

View File

@ -0,0 +1,64 @@
// 2009-09-23 Paolo Carlini <paolo.carlini@oracle.com>
// Copyright (C) 2008 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)
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
#include <bitset>
#include <testsuite_hooks.h>
// DR 396. what are characters zero and one.
void test01()
{
bool test __attribute__((unused)) = true;
std::bitset<4> z1("bbab", 'a', 'b');
std::bitset<4> z1_ref(std::string("bbab"), 0, std::string::npos, 'a', 'b');
VERIFY( z1.to_string('a', 'b') == "bbab" );
VERIFY( z1 == z1_ref );
std::bitset<4> z2("11a1", 'a');
std::bitset<4> z2_ref(std::string("11a1"), 0, std::string::npos, 'a');
VERIFY( z2.to_string('a') == "11a1" );
VERIFY( z2 == z2_ref );
std::bitset<8> z3("babb", 'a', 'b');
std::bitset<8> z3_ref(std::string("babb"), 0, std::string::npos, 'a', 'b');
VERIFY( z3.to_string('a', 'b') == "aaaababb" );
VERIFY( z3 == z3_ref );
std::bitset<8> z4("1a11", 'a');
std::bitset<8> z4_ref(std::string("1a11"), 0, std::string::npos, 'a');
VERIFY( z4.to_string('a') == "aaaa1a11" );
VERIFY( z4 == z4_ref );
std::bitset<2> z5("bbab", 'a', 'b');
std::bitset<2> z5_ref(std::string("bbab"), 0, std::string::npos, 'a', 'b');
VERIFY( z5.to_string('a', 'b') == "bb" );
VERIFY( z5 == z5_ref );
std::bitset<2> z6("11a1", 'a');
std::bitset<2> z6_ref(std::string("11a1"), 0, std::string::npos, 'a');
VERIFY( z6.to_string('a') == "11" );
VERIFY( z6 == z6_ref );
}
int main()
{
test01();
return 0;
}

View File

@ -0,0 +1,65 @@
// 2008-09-23 Paolo Carlini <pcarlini@suse.de>
// Copyright (C) 2008 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)
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// 23.3.5.2 bitset members
#include <bitset>
#include <testsuite_hooks.h>
// DR 396. what are characters zero and one.
void test01()
{
using namespace std;
bool test __attribute__((unused)) = true;
bitset<5> b5;
string s0 = b5.to_string<char, char_traits<char>, allocator<char> >('a', 'b');
VERIFY( s0 == "aaaaa" );
string s1 = b5.to_string<char, char_traits<char>, allocator<char> >('b');
VERIFY( s1 == "bbbbb" );
b5.set(0);
string s2 = b5.to_string<char, char_traits<char> >('c', 'd');
VERIFY( s2 == "ccccd" );
string s3 = b5.to_string<char, char_traits<char> >('d');
VERIFY( s3 == "dddd1" );
b5.set(2);
string s4 = b5.to_string<char>('e', 'f');
VERIFY( s4 == "eefef" );
string s5 = b5.to_string<char>('f');
VERIFY( s5 == "ff1f1" );
b5.set(4);
string s6 = b5.to_string('g', 'h');
VERIFY( s6 == "hghgh" );
string s7 = b5.to_string('h');
VERIFY( s7 == "1h1h1" );
}
int main()
{
test01();
return 0;
}