1367 lines
44 KiB
C++
1367 lines
44 KiB
C++
/***************************************************************************
|
|
*
|
|
* 23.bitset.cpp - test exercising [lib.bitset]
|
|
*
|
|
* $Id: 23.bitset.cpp 648752 2008-04-16 17:01:56Z faridz $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
* Copyright 2001-2006 Rogue Wave Software.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#include <bitset>
|
|
#include <istream>
|
|
#include <ostream>
|
|
|
|
#include <cstdio> // for sprintf()
|
|
#include <climits>
|
|
|
|
#include <rw_char.h> // for UserChar
|
|
#include <rw_rand.h> // for rw_rand()
|
|
#include <driver.h> // for rw_test(), ...
|
|
|
|
|
|
#define NLOOPS 128
|
|
|
|
/**************************************************************************/
|
|
|
|
// sets the `n' least significant bits
|
|
std::size_t
|
|
bitmax (std::size_t n)
|
|
{
|
|
std::size_t result = 0;
|
|
while (n--)
|
|
result = result << 1 | 1U;
|
|
return result;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
// fake bitset class, bit pattern represented as a character string
|
|
template <std::size_t N>
|
|
struct test_set
|
|
{
|
|
char bits_ [N + 1];
|
|
|
|
test_set () {
|
|
reset ();
|
|
bits_ [N] = '\0'; // null-terminate
|
|
}
|
|
|
|
_EXPLICIT test_set (unsigned long val) {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
set (i, !!(val & (1UL << i)));
|
|
bits_ [N] = '\0'; // NUL-terminate
|
|
}
|
|
|
|
_EXPLICIT test_set (const std::bitset<N> &rhs) {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
set (i, rhs.test (i));
|
|
bits_ [N] = '\0'; // NUL-terminate
|
|
}
|
|
|
|
// accessor function provided to work around
|
|
// a MIPSpro 7.3.1.1 bug (PR #25682)
|
|
const char* bits () const {
|
|
return bits_;
|
|
}
|
|
|
|
test_set& random () {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = char ('0' + rw_rand (2U));
|
|
return *this;
|
|
}
|
|
|
|
std::bitset<N> to_bitset () const {
|
|
std::bitset<N> tmp;
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
tmp.set (i, test (i));
|
|
return tmp;
|
|
}
|
|
|
|
test_set& operator&= (const test_set &rhs) {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = '0' + ('1' == bits_ [i] && '1' == rhs.bits_ [i]);
|
|
return *this;
|
|
}
|
|
|
|
test_set& operator|= (const test_set &rhs) {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = '0' + ('1' == bits_ [i] || '1' == rhs.bits_ [i]);
|
|
return *this;
|
|
}
|
|
|
|
test_set& operator^= (const test_set &rhs) {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = '0' + !!(bits_ [i] - rhs.bits_ [i]);
|
|
return *this;
|
|
}
|
|
|
|
test_set& operator<<= (std::size_t n) {
|
|
for (std::size_t i = 0; i < N - n && i + n + 1 < N + 1; ++i)
|
|
bits_ [i] = bits_ [i + n];
|
|
for (std::size_t j = N - n; j != N; ++j)
|
|
bits_ [j] = '0';
|
|
return *this;
|
|
}
|
|
|
|
test_set& operator>>= (std::size_t n) {
|
|
for (std::size_t i = N - 1; i != n - 1; --i)
|
|
bits_ [i] = bits_ [i - n];
|
|
for (std::size_t j = n; j != 0; )
|
|
bits_ [--j] = '0';
|
|
return *this;
|
|
}
|
|
|
|
test_set& set () {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = '1';
|
|
return *this;
|
|
}
|
|
|
|
test_set& set (std::size_t pos, bool val) {
|
|
bits_ [N - pos - 1] = '0' + val;
|
|
return *this;
|
|
}
|
|
|
|
test_set& reset () {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = '0';
|
|
return *this;
|
|
}
|
|
|
|
test_set& reset (std::size_t pos) {
|
|
return bits_ [N - pos - 1] = '0', *this;
|
|
}
|
|
|
|
test_set operator~ () const {
|
|
return test_set (*this).flip ();
|
|
}
|
|
|
|
test_set& flip () {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
bits_ [i] = '0' + ('0' == bits_ [i]);
|
|
return *this;
|
|
}
|
|
|
|
test_set& flip (std::size_t pos) {
|
|
bits_ [N - pos - 1] = '0' + ('0' == bits_ [N - pos - 1]);
|
|
return *this;
|
|
}
|
|
|
|
std::size_t count () const {
|
|
std::size_t n = 0;
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
n += bits_ [i] != '0';
|
|
return n;
|
|
}
|
|
|
|
bool operator== (const test_set &rhs) const {
|
|
for (std::size_t i = 0; i != N; ++i)
|
|
if (bits_ [i] != rhs.bits_ [i])
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool test (std::size_t pos) const {
|
|
return '0' != bits_ [N - pos - 1];
|
|
}
|
|
};
|
|
|
|
/**************************************************************************/
|
|
|
|
#ifndef _RWSTD_NO_EXPLICIT
|
|
|
|
// helper to verify that bitset ctor is explicit
|
|
// not defined since it must not be referenced if test is successful
|
|
// static commented out to prevent gcc warning: function declared
|
|
// 'static' but never defined
|
|
/* static */ void
|
|
is_explicit (const std::bitset<0>&);
|
|
|
|
struct has_implicit_ctor
|
|
{
|
|
// NOT explicit
|
|
has_implicit_ctor (const std::string&) { }
|
|
};
|
|
|
|
// calls to the overloaded is_explicit() resolve to the function below
|
|
static void
|
|
is_explicit (const has_implicit_ctor&) { }
|
|
|
|
#endif // _RWSTD_NO_EXPLICIT
|
|
|
|
|
|
static void
|
|
test_synopsis (std::bitset<0>*)
|
|
{
|
|
// prevent warnings about unreachable code
|
|
volatile bool dummy = false;
|
|
|
|
if (!dummy)
|
|
return;
|
|
|
|
typedef std::bitset<0> Bitset;
|
|
typedef Bitset::reference Reference;
|
|
|
|
Bitset::reference *pr = (Bitset::reference*)0;
|
|
_RWSTD_UNUSED (pr);
|
|
|
|
// verify that a member function is accessible and has the appropriate
|
|
// signature, including return type and exception specification
|
|
#define MEMFUN(result, name, arg_list) do { \
|
|
result (Bitset::reference::*pf) arg_list = &Bitset::reference::name; \
|
|
_RWSTD_UNUSED (pf); \
|
|
} while (0)
|
|
|
|
// exercise bitset::reference members
|
|
MEMFUN (Reference&, operator=, (bool));
|
|
MEMFUN (Reference&, operator=, (const Reference&));
|
|
MEMFUN (bool, operator~, () const);
|
|
MEMFUN (bool, operator bool, () const);
|
|
MEMFUN (Reference&, flip, ());
|
|
|
|
// 23.3.5.1 - verify bitset ctors
|
|
#if !defined (_RWSTD_NO_EXPLICIT) \
|
|
&& (!defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530) \
|
|
&& (!defined (__GNUG__) || __GNUG__ >= 3)
|
|
// working around a SunPro 5.2 bug (see PR #25959)
|
|
|
|
// verify that bitset ctor is declared explicit
|
|
is_explicit (std::string ());
|
|
|
|
#endif // _RWSTD_NO_EXPLICIT && SunPro > 5.3
|
|
|
|
// verify default arguments
|
|
(void)Bitset (std::string ());
|
|
(void)Bitset (std::string (), std::string::size_type ());
|
|
|
|
// verify that a member function is accessible and has the appropriate
|
|
// signature, including return type and exception specification
|
|
#undef MEMFUN
|
|
#define MEMFUN(result, name, arg_list) do { \
|
|
result (Bitset::*pf) arg_list = &Bitset::name; \
|
|
_RWSTD_UNUSED (pf); \
|
|
} while (0)
|
|
|
|
MEMFUN (Bitset&, operator&=, (const Bitset&));
|
|
MEMFUN (Bitset&, operator|=, (const Bitset&));
|
|
MEMFUN (Bitset&, operator^=, (const Bitset&));
|
|
MEMFUN (Bitset&, operator<<=, (std::size_t));
|
|
MEMFUN (Bitset&, operator>>=, (std::size_t));
|
|
|
|
MEMFUN (Bitset&, set, ());
|
|
MEMFUN (Bitset&, set, (std::size_t, bool)); // lwg issue 186
|
|
Bitset ().set (0); // verify default argument
|
|
|
|
MEMFUN (Bitset&, reset, ());
|
|
MEMFUN (Bitset&, reset, (std::size_t));
|
|
|
|
MEMFUN (Bitset, operator~, () const);
|
|
MEMFUN (Bitset&, flip, ());
|
|
MEMFUN (Bitset&, flip, (std::size_t));
|
|
|
|
MEMFUN (Bitset::reference, operator[], (std::size_t));
|
|
MEMFUN (bool, operator[], (std::size_t) const);
|
|
|
|
MEMFUN (unsigned long, to_ulong, () const);
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
# if !defined (__HP_aCC) || __HP_aCC >= 60000
|
|
|
|
// working around HP aCC bugs PR #23312 and bug #503
|
|
|
|
# define PARAMLIST_3(T) T, std::char_traits<T>, std::allocator<T>
|
|
# define PARAMLIST_2(T) T, std::char_traits<T>
|
|
|
|
// exercise the overloaded member template function and ordinary
|
|
// member function to_string()
|
|
MEMFUN (std::basic_string<PARAMLIST_3 (char) >,
|
|
to_string<PARAMLIST_3 (char) >, (char, char) const);
|
|
MEMFUN (std::basic_string<PARAMLIST_3 (char) >,
|
|
to_string, (char, char) const);
|
|
|
|
# ifndef _RWSTD_NO_WCHAR_T
|
|
|
|
MEMFUN (std::basic_string<PARAMLIST_3 (wchar_t) >,
|
|
to_string<PARAMLIST_3 (wchar_t) >, (wchar_t, wchar_t) const);
|
|
|
|
# endif // _RWSTD_NO_WCHAR_T
|
|
|
|
MEMFUN (std::basic_string<PARAMLIST_3 (int) >,
|
|
to_string<PARAMLIST_3 (int) >, (int, int) const);
|
|
|
|
# undef PARAMLIST_3
|
|
# undef PARAMLIST_2
|
|
|
|
# endif // !__HP_aCC || __HP_aCC >= 60000
|
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
MEMFUN (std::size_t, size, () const);
|
|
MEMFUN (std::size_t, count, () const);
|
|
|
|
MEMFUN (bool, operator==, (const Bitset&) const);
|
|
MEMFUN (bool, operator!=, (const Bitset&) const);
|
|
|
|
MEMFUN (bool, test, (std::size_t) const);
|
|
MEMFUN (bool, any, () const);
|
|
MEMFUN (bool, none, () const);
|
|
|
|
MEMFUN (Bitset, operator>>, (std::size_t) const);
|
|
MEMFUN (Bitset, operator<<, (std::size_t) const);
|
|
|
|
#define FUN(result, name, arg_list) do { \
|
|
result (*pf) arg_list = &name; \
|
|
_RWSTD_UNUSED (pf); \
|
|
} while (0)
|
|
|
|
#if !defined (__IBMCPP__) || __IBMCPP__ > 502
|
|
FUN (Bitset, std::operator&, (const Bitset&, const Bitset&));
|
|
FUN (Bitset, std::operator|, (const Bitset&, const Bitset&));
|
|
FUN (Bitset, std::operator^, (const Bitset&, const Bitset&));
|
|
|
|
#else
|
|
// working around xlC 5.0.2.0 bug: PR #26561
|
|
|
|
FUN (Bitset, std::operator&,(const Bitset&,const Bitset&) _PTR_THROWS(()));
|
|
FUN (Bitset, std::operator|,(const Bitset&,const Bitset&) _PTR_THROWS(()));
|
|
FUN (Bitset, std::operator^,(const Bitset&,const Bitset&) _PTR_THROWS(()));
|
|
#endif
|
|
|
|
|
|
#define PARAMLIST(T) T, std::char_traits<T>
|
|
|
|
FUN (std::basic_istream< PARAMLIST (char) >&, std::operator>>,
|
|
(std::basic_istream< PARAMLIST (char) >&, Bitset&));
|
|
FUN (std::basic_ostream< PARAMLIST (char) >&, std::operator<<,
|
|
(std::basic_ostream< PARAMLIST (char) >&, const Bitset&));
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
# ifndef _RWSTD_NO_WCHAR_T
|
|
|
|
FUN (std::basic_istream< PARAMLIST (wchar_t) >&, std::operator>>,
|
|
(std::basic_istream< PARAMLIST (wchar_t) >&, Bitset&));
|
|
FUN (std::basic_ostream< PARAMLIST (wchar_t) >&, std::operator<<,
|
|
(std::basic_ostream< PARAMLIST (wchar_t) >&, const Bitset&));
|
|
|
|
# endif // _RWSTD_NO_WCHAR_T
|
|
|
|
# if !defined (_MSC_VER) || _MSC_VER > 1300
|
|
|
|
// MSVC is too dumb to handle bitset inserters and extractors
|
|
// parametrized on multiple template paramenters
|
|
FUN (std::basic_istream< PARAMLIST (int) >&, std::operator>>,
|
|
(std::basic_istream< PARAMLIST (int) >&, Bitset&));
|
|
FUN (std::basic_ostream< PARAMLIST (int) >&, std::operator<<,
|
|
(std::basic_ostream< PARAMLIST (int) >&, const Bitset&));
|
|
|
|
# endif // !defined (_MSC_VER) || _MSC_VER > 1300
|
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
#undef PARAMLIST
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void test_ctors (const std::bitset<N>*)
|
|
{
|
|
typedef unsigned long ULong;
|
|
const ULong bmask = ULong (::bitmax (N));
|
|
|
|
{ // bitset::bitset()
|
|
rw_info (0, 0, __LINE__, "std::bitset<%d>::bitset()", N);
|
|
|
|
const std::bitset<N> b;
|
|
rw_assert (0 == b.to_ulong (), 0, __LINE__,
|
|
"bitset<%d>::bitset ().to_ulong() == 0, got %#lx",
|
|
b.to_ulong ());
|
|
}
|
|
|
|
{ // bitset::bitset (unsigned long)
|
|
rw_info (0, 0, __LINE__, "std::bitset<%d>::bitset (unsigned long)", N);
|
|
|
|
const std::bitset<N> b (ULONG_MAX & bmask);
|
|
rw_assert ((ULONG_MAX & bmask) == b.to_ulong (), 0, __LINE__,
|
|
"bitset<%d>::bitset (%#lx).to_ulong() == 0, got %#lx",
|
|
N, ULONG_MAX & bmask, b.to_ulong ());
|
|
}
|
|
|
|
{ // bitset (const string& str, size_t pos = 0, size_t n = (size_t)-1);
|
|
rw_info (0, 0, __LINE__, "std::bitset<%d>::bitset (string)", N);
|
|
|
|
test_set<N> ts;
|
|
ts.set ();
|
|
|
|
_TRY {
|
|
const std::bitset<N> b = std::bitset<N>(std::string (ts.bits ()));
|
|
|
|
if (N <= sizeof (unsigned long) * CHAR_BIT)
|
|
rw_assert (b == bmask, 0, __LINE__,
|
|
"bitset<%d>::bitset(string(\"%s\").to_ulong()"
|
|
" == %#x, got %#x", N, ts.bits (), bmask,
|
|
b.to_ulong ());
|
|
else
|
|
rw_assert (test_set<N>(b) == ts, 0, __LINE__,
|
|
"bitset<%d>::bitset(string(\"111...111\")"
|
|
" == 111...111, got %s",
|
|
N, test_set<N>(b).bits ());
|
|
|
|
}
|
|
_CATCH (...) {
|
|
rw_assert (false, 0, __LINE__, (""));
|
|
}
|
|
}
|
|
|
|
{ // bitset (const bitset<N>& rhs)
|
|
rw_info (0, 0, __LINE__, "std::bitset<%d>::bitset (const bitset&)", N);
|
|
|
|
const std::bitset<N> b1 (12345);
|
|
const std::bitset<N> b2 (b1);
|
|
|
|
rw_assert (b1.to_ulong () == b2.to_ulong (), 0, __LINE__,
|
|
"bitset<%d>::bitset (bitset<%d>(%#lx)).to_ulong() == %#lx,"
|
|
" got %#lx", N, b1.to_ulong (), b2.to_ulong ());
|
|
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%d>::operator=(const bitset&)", N);
|
|
|
|
std::bitset<N> b3;
|
|
b3 = b1;
|
|
|
|
rw_assert (b1.to_ulong () == b3.to_ulong (), 0, __LINE__,
|
|
"bitset<%d>::bitset (bitset<%d>(%#lx)).to_ulong() == %#lx,"
|
|
" got %#lx", N, b1.to_ulong (), b3.to_ulong ());
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void stress_ctors (const std::bitset<N>*)
|
|
{
|
|
rw_info (0, 0, __LINE__, "std::bitset<%d>::bitset (string)", N);
|
|
|
|
const std::size_t max_mask = bitmax (N);
|
|
|
|
for (std::size_t i = 0; i != 1000U; i++) {
|
|
|
|
typedef unsigned long ULong;
|
|
|
|
// exercise 23.3.5.1, p2
|
|
const ULong n = ULong (rw_rand (0) & max_mask);
|
|
const std::bitset<N> b1 (n);
|
|
|
|
rw_assert (n == b1.to_ulong (), 0, __LINE__,
|
|
"bitset<%d>::bitset(%#lx).to_ulong() == %#lx, got %#lx",
|
|
N, n, n, b1.to_ulong ());
|
|
|
|
test_set<N> ts;
|
|
ts.random ();
|
|
|
|
// exercise 23.3.5.1, p3
|
|
std::bitset<N> b2 = std::bitset<N>(std::string (ts.bits ()));
|
|
rw_assert (test_set<N>(b2) == ts, 0, __LINE__,
|
|
"bitset<%d>::bitset (\"%s\") got %s",
|
|
N, ts.bits (), b2.to_string ().c_str ());
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void test_operators (const std::bitset<N>*)
|
|
{
|
|
#define TEST_OP(op) do { \
|
|
rw_info (!i, 0, __LINE__, "std::bitset<%d>::operator" #op \
|
|
"= (const bitset&)", N); \
|
|
\
|
|
test_set<N> lhs = test_set<N>().random (); \
|
|
const test_set<N> rhs = test_set<N>().random (); \
|
|
std::bitset<N> b_lhs = std::bitset<N>(std::string (lhs.bits ()));\
|
|
const std::bitset<N> b_rhs = std::bitset<N>(std::string (rhs.bits ()));\
|
|
const test_set<N> res = lhs op ## = rhs; \
|
|
const std::bitset<N> b_res = b_lhs op ## = b_rhs; \
|
|
\
|
|
rw_assert (res == test_set<N>(b_res), 0, __LINE__, \
|
|
"bitset<%lu>::operator" #op "= (const bitset<%lu>&):" \
|
|
" %s " #op " %s == %s, got %s", \
|
|
N, N, lhs.bits (), rhs.bits (), res.bits (), \
|
|
test_set<N>(b_res).bits ()); \
|
|
\
|
|
rw_info (!i, 0, __LINE__, "std::bitset<%d>::operator" #op \
|
|
" (const bitset&)", N); \
|
|
lhs.random (); \
|
|
b_lhs = std::bitset<N>(std::string (lhs.bits ())); \
|
|
\
|
|
const test_set<N> res2 = lhs op ## = rhs; \
|
|
const std::bitset<N> b_res2 = b_lhs op b_rhs; \
|
|
\
|
|
rw_assert (res2 == test_set<N>(b_res2), 0, __LINE__, \
|
|
"bitset<%lu>::operator" #op " (const bitset<%lu>&):" \
|
|
" %s " #op " %s == %s, got %s", \
|
|
N, N, lhs.bits (), rhs.bits (), res2.bits (), \
|
|
test_set<N>(b_res2).bits ()); \
|
|
} while (0)
|
|
|
|
// prevent division by zero errors, also exercise shifting by
|
|
// N bits (operation must zero out the first operand)
|
|
// especially important is shifting bitset<N> by N bits where
|
|
// N >= sizeof (unsigned long) * CHAR_BIT, since this operation
|
|
// is undefined for unsigned longs but defined for bitset
|
|
|
|
const std::size_t M = N + 1;
|
|
|
|
for (int i = 0; i != NLOOPS; ++i) {
|
|
|
|
// 23.3.5.2, p1 and 23.3.5.3, p1
|
|
TEST_OP (&);
|
|
// 23.3.5.2, p3 and 23.3.5.3, p2
|
|
TEST_OP (|);
|
|
// 23.3.5.2, p5 and 23.3.5.3, p3
|
|
TEST_OP (^);
|
|
|
|
rw_info (!i, 0, __LINE__, "std::bitset<%d>::operator<<=(size_t)", N);
|
|
|
|
const test_set<N> ts1 = test_set<N>().random ();
|
|
const test_set<N> ts2 = test_set<N>(ts1) <<= i % M;
|
|
|
|
std::bitset<N> b1 = std::bitset<N> (std::string (ts1.bits ()));
|
|
|
|
// 23.3.5.2, p7
|
|
b1 <<= i % M;
|
|
|
|
rw_assert (test_set<N>(b1) == ts2, 0, __LINE__,
|
|
"bitset<%d>::operator<<=(%lu): %s << %lu == %s, got %s",
|
|
N, i % M, ts1.bits (), i % M, ts2.bits (),
|
|
test_set<N>(b1).bits ());
|
|
|
|
rw_info (!i, 0, __LINE__, "std::bitset<%d>::operator>>=(size_t)", N);
|
|
|
|
const test_set<N> ts3 = test_set<N>(ts1) >>= i % M;
|
|
std::bitset<N> b2 = std::bitset<N>(std::string (ts1.bits ()));
|
|
|
|
// 23.3.5.2, p9
|
|
b2 >>= i % M;
|
|
|
|
rw_assert (test_set<N>(b2) == ts3, 0, __LINE__,
|
|
"bitset<%d>::operator>>=(%lu): %s >> %lu == %s, got %s",
|
|
N, i % M, ts1.bits (), i % M, ts3.bits (),
|
|
test_set<N>(b2).bits ());
|
|
|
|
rw_info (!i, 0, __LINE__,
|
|
"std::bitset<%d>::operator<<=(size_t) (unused bits)", N);
|
|
|
|
if (N) {
|
|
b1.set (N - 1);
|
|
std::size_t first = b1.count ();
|
|
std::size_t second = (b1 <<= 1).count ();
|
|
rw_assert (!(first == second), 0, __LINE__,
|
|
"bitset<%lu>::operator<<=(1): "
|
|
"after <<= 1: expected %lu, got %lu",
|
|
N, first - 1, second);
|
|
}
|
|
|
|
rw_info (!i, 0, __LINE__,
|
|
"std::bitset<%d>::operator>>=(size_t) (unused bits)", N);
|
|
|
|
if (N) {
|
|
b2.set ();
|
|
std::size_t first = b2.count ();
|
|
std::size_t second = (b2 >>= 1).count ();
|
|
rw_assert (first - 1 == second, 0, __LINE__,
|
|
"bitset<%lu>::operator>>=(1): "
|
|
"after >>= 1: expected %lu, got %lu",
|
|
N, first - 1, second);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void test_other (const std::bitset<N>*)
|
|
{
|
|
for (std::size_t i = 0; i != NLOOPS; ++i) {
|
|
|
|
// 23.3.5.2, p23
|
|
test_set<N> ts1;
|
|
ts1.random ();
|
|
|
|
test_set<N> ts2 = ~ts1;
|
|
|
|
std::bitset<N> b1 = std::bitset<N>(std::string (ts1.bits ()));
|
|
std::bitset<N> b2 = ~b1;
|
|
|
|
rw_assert (ts2 == test_set<N>(b2), 0, __LINE__,
|
|
"bitset<%d>::operator~(): ~%s == %s, got %s",
|
|
N, ts1.bits (), ts2.bits (), test_set<N>(b2).bits ());
|
|
|
|
// 23.3.5.2, p25
|
|
b2.flip ();
|
|
rw_assert (ts1 == test_set<N>(b2), 0, __LINE__,
|
|
"bitset<%d>::flip (): ~%s == %s, got %s",
|
|
N, ts1.bits (), ts2.bits (), test_set<N>(b2).bits ());
|
|
|
|
// 23.3.5.2, p27
|
|
for (std::size_t _j = 0; _j != N; ++_j)
|
|
b2.flip (_j);
|
|
|
|
rw_assert (ts2 == test_set<N>(b2), 0, __LINE__,
|
|
"bitset<%d>::flip () == %s, got %s",
|
|
N, ts2.bits (), test_set<N>(b2).bits ());
|
|
|
|
// 23.3.5.3, p35
|
|
rw_assert (ts2.count () == b2.count (), 0, __LINE__,
|
|
"bitset<%d>::count () == %d, got %d [%s]",
|
|
N, ts2.count (), b2.count (), test_set<N>(b2).bits());
|
|
|
|
// 23.3.5.3, p37
|
|
rw_assert (b2 == b2 && (N && !(b1 == b2) || !N && b1 == b2),
|
|
0, __LINE__,
|
|
"bitset<%d>::operator==(const bitset<%ul>&) [%s]",
|
|
N, N, N ? test_set<N>(b2).bits () : "<empty>");
|
|
|
|
// 23.3.5.3, p38
|
|
rw_assert ((N && b1 != b2 || !N && !(b1 != b2)) && !(b2 != b2),
|
|
0, __LINE__,
|
|
"bitset<%d>::operator!=(const bitset<%ul>&) [%s]",
|
|
N, N, N ? test_set<N>(b2).bits () : "<empty>");
|
|
|
|
// 23.3.5.3, p42
|
|
rw_assert (b2.count() && b2.any() || !b2.count() && !b2.any(),
|
|
0, __LINE__,
|
|
"bitset<%d>::any () [%s]",
|
|
N, test_set<N>(b2).bits ());
|
|
|
|
// 23.3.5.3, p43
|
|
rw_assert (b2.count() && !b2.none() || !b2.count() && b2.none(),
|
|
0, __LINE__,
|
|
"bitset<%d>::none () [%s]",
|
|
N, test_set<N>(b2).bits ());
|
|
|
|
for (std::size_t k = 0; k != N; ++k) {
|
|
test_set<N> ts3 = test_set<N>(ts1) <<= k;
|
|
std::bitset<N> b3 = b1 << k;
|
|
|
|
rw_assert (test_set<N>(b3) == ts3, 0, __LINE__,
|
|
"bitset<%lu>::operator<<(%lu)", N, k);
|
|
|
|
ts3 = test_set<N>(ts1) >>= k;
|
|
b3 = b1 >> k;
|
|
|
|
rw_assert (test_set<N>(b3) == ts3, 0, __LINE__,
|
|
"bitset<%lu>::operator>>(%lu)", N, k);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void stress_count (const std::bitset<N>*)
|
|
{
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::count()", N);
|
|
|
|
for (std::size_t i = 0; i != N; i++) {
|
|
std::bitset<N> b;
|
|
|
|
for (std::size_t j = 0; j != i; j++)
|
|
b.set (j);
|
|
|
|
rw_assert (b.count () == i, 0, __LINE__,
|
|
"%lu. std::bitset<%lu>::count()", i, N);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void test_elem_access (const std::bitset<N>*)
|
|
{
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::test(size_t)", N);
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::operator[](size_t)", N);
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::operator[](size_t) const", N);
|
|
|
|
for (std::size_t i = 0; i != NLOOPS; ++i) {
|
|
|
|
const test_set<N> ts = test_set<N>().random ();
|
|
std::bitset<N> b = std::bitset<N>(std::string (ts.bits ()));
|
|
|
|
for (std::size_t _j = 0; _j != N; ++_j) {
|
|
// 23.3.5.2, p39
|
|
rw_assert (b.test (_j) == ts.test (_j), 0, __LINE__,
|
|
"bitset<%lu>::test (%lu): %s",
|
|
N, _j, test_set<N>(b).bits ());
|
|
|
|
// 23.3.5.2, p??: see lwg issue 11
|
|
rw_assert (b [_j] == ts.test (_j), 0, __LINE__,
|
|
"bitset<%lu>::operator[](%lu): %s",
|
|
N, _j, test_set<N>(b).bits ());
|
|
|
|
// 23.3.5.2, p??: see lwg issue 11
|
|
rw_assert (((const std::bitset<N>&)b) [_j] == ts.test (_j),
|
|
0, __LINE__,
|
|
"bitset<%lu>::operator[](%lu) const: %s",
|
|
N, _j, test_set<N>(b).bits ());
|
|
|
|
// exercise std::bitset<N>::reference
|
|
_TYPENAME std::bitset<N>::reference r = b [_j];
|
|
|
|
// std::bitset<N>::reference::flip()
|
|
r.flip ();
|
|
rw_assert (r == !ts.test (_j), 0, __LINE__,
|
|
"bitset<%lu>::reference::flip()", N);
|
|
|
|
// std::bitset<N>::reference::operator~()
|
|
bool toggled = ~r;
|
|
rw_assert (toggled == ts.test (_j), 0, __LINE__,
|
|
"bitset<%lu>::reference::operator~()", N);
|
|
|
|
// std::bitset<N>::reference::operator=(bool)
|
|
r = toggled;
|
|
rw_assert (r == ts.test (_j) && b.test (_j) == ts.test (_j),
|
|
0, __LINE__,
|
|
"bitset<%lu>::reference::operator=(bool)", N);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
|
|
_RWSTD_NAMESPACE (std) {
|
|
|
|
_RWSTD_SPECIALIZED_CLASS
|
|
struct char_traits<UserChar>: UserTraits<UserChar> { };
|
|
|
|
} // namespace std
|
|
|
|
|
|
const char* type_name (char) { return "char"; }
|
|
|
|
#ifndef _RWSTD_NO_WCHAR_T
|
|
const char* type_name (wchar_t) { return "wchar_t"; }
|
|
#endif // _RWSTD_NO_WCHAR_T
|
|
|
|
const char* type_name (const UserChar&)
|
|
{
|
|
return "UserChar";
|
|
}
|
|
|
|
template <class charT>
|
|
const char* traits_name (const std::char_traits<charT>*)
|
|
{
|
|
static char name [64];
|
|
std::sprintf (name, "std::char_traits<%s>", type_name (charT ()));
|
|
return name;
|
|
}
|
|
|
|
const char* traits_name (const UserTraits<UserChar>*)
|
|
{
|
|
return "UserTraits";
|
|
}
|
|
|
|
template <class charT>
|
|
struct MyAlloc: std::allocator<charT> { };
|
|
|
|
template <class charT>
|
|
const char* alloc_name (const std::allocator<charT>&)
|
|
{
|
|
static char name [64];
|
|
std::sprintf (name, "std::allocator<%s>", type_name (charT ()));
|
|
return name;
|
|
}
|
|
|
|
template <class charT>
|
|
const char* alloc_name (const MyAlloc<charT>&)
|
|
{
|
|
static char name [64];
|
|
std::sprintf (name, "MyAlloc<%s>", type_name (charT ()));
|
|
return name;
|
|
}
|
|
|
|
template <class charT>
|
|
charT& assign (charT &lhs, char rhs)
|
|
{
|
|
return lhs = rhs;
|
|
}
|
|
|
|
UserChar& assign (UserChar &lhs, char rhs)
|
|
{
|
|
lhs.c = _RWSTD_STATIC_CAST (unsigned char, rhs);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
// compare two strings, return the offset of the first mismatch
|
|
// or -1 when the strings are equal
|
|
template <class charT>
|
|
int compare (const charT str[], const char s[], const char bits [2])
|
|
{
|
|
const char* const beg = s;
|
|
|
|
for ( ; *s; ++s, ++str) {
|
|
|
|
if (*str != bits ['1' == *s])
|
|
return int (s - beg);
|
|
}
|
|
|
|
return *str ? s - beg : -1;
|
|
}
|
|
|
|
// compare two strings, return the offset of the first mismatch
|
|
// or -1 when the strings are equal
|
|
int compare (const UserChar str[], const char s[], const char bits [2])
|
|
{
|
|
const char* const beg = s;
|
|
|
|
for (; *s; ++s, ++str) {
|
|
|
|
if (char (str->c) != bits ['1' == *s])
|
|
return int (s - beg);
|
|
}
|
|
|
|
return str->c ? s - beg : -1;
|
|
}
|
|
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
// call the bitset<N>::to_string() member function template,
|
|
// explicitly specifying all three template arguments,
|
|
// and 2, 1, or 0 of the two default function arguments
|
|
template <std::size_t N, class charT, class Traits, class Alloc>
|
|
std::basic_string<charT, Traits, Alloc>
|
|
bitset_to_string_3 (const std::bitset<N> &bs, int nfargs,
|
|
charT zero, charT one,
|
|
std::basic_string<charT, Traits, Alloc>*)
|
|
{
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.template to_string<charT, Traits, Alloc>(zero);
|
|
case 0:
|
|
return bs.template to_string<charT, Traits, Alloc>();
|
|
}
|
|
|
|
return bs.template to_string<charT, Traits, Alloc>(zero, one);
|
|
}
|
|
|
|
template <std::size_t N, class Traits, class Alloc>
|
|
std::basic_string<UserChar, Traits, Alloc>
|
|
bitset_to_string_3 (const std::bitset<N> &bs, int nfargs,
|
|
UserChar zero, UserChar one,
|
|
std::basic_string<UserChar, Traits, Alloc>*)
|
|
{
|
|
// UserChar digits zero and one
|
|
static const UserChar dig[] = { { 0, '0' }, { 0, '1' } };
|
|
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.template to_string<UserChar, Traits, Alloc>(zero, dig [1]);
|
|
case 0:
|
|
return bs.template to_string<UserChar, Traits, Alloc>(dig [0], dig [1]);
|
|
}
|
|
|
|
return bs.template to_string<UserChar, Traits, Alloc>(zero, one);
|
|
}
|
|
|
|
// call the bitset<N>::to_string() member function template,
|
|
// explicitly specifying two of the three template arguments,
|
|
// and 2, 1, or 0 of the two default function arguments
|
|
template <std::size_t N, class charT, class Traits>
|
|
std::basic_string<charT, Traits, std::allocator<charT> >
|
|
bitset_to_string_2 (const std::bitset<N> &bs, int nfargs,
|
|
charT zero, charT one,
|
|
std::basic_string<charT, Traits,
|
|
std::allocator<charT> >*)
|
|
{
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.template to_string<charT, Traits>(zero);
|
|
case 0:
|
|
return bs.template to_string<charT, Traits>();
|
|
}
|
|
|
|
return bs.template to_string<charT, Traits>(zero, one);
|
|
}
|
|
|
|
template <std::size_t N, class Traits>
|
|
std::basic_string<UserChar, Traits, std::allocator<UserChar> >
|
|
bitset_to_string_2 (const std::bitset<N> &bs, int nfargs,
|
|
UserChar zero, UserChar one,
|
|
std::basic_string<UserChar, Traits,
|
|
std::allocator<UserChar> >*)
|
|
{
|
|
static const UserChar dig[] = { { 0, '0' }, { 0, '1' } };
|
|
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.template to_string<UserChar, Traits>(zero, dig [1]);
|
|
case 0:
|
|
return bs.template to_string<UserChar, Traits>(dig [0], dig [1]);
|
|
}
|
|
|
|
return bs.template to_string<UserChar, Traits>(zero, one);
|
|
}
|
|
|
|
// call the bitset<N>::to_string() member function template,
|
|
// explicitly specifying one of the three template arguments,
|
|
// and 2, 1, or 0 of the two default function arguments
|
|
template <std::size_t N, class charT>
|
|
std::basic_string<charT, std::char_traits<charT>, std::allocator<charT> >
|
|
bitset_to_string_1 (const std::bitset<N> &bs, int nfargs,
|
|
charT zero, charT one,
|
|
std::basic_string<charT,
|
|
std::char_traits<charT>,
|
|
std::allocator<charT> >*)
|
|
{
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.template to_string<charT>(zero);
|
|
case 0:
|
|
return bs.template to_string<charT>();
|
|
}
|
|
|
|
return bs.template to_string<charT>(zero, one);
|
|
}
|
|
|
|
template <std::size_t N>
|
|
std::basic_string<UserChar, std::char_traits<UserChar>,
|
|
std::allocator<UserChar> >
|
|
bitset_to_string_1 (const std::bitset<N> &bs, int nfargs,
|
|
UserChar zero, UserChar one,
|
|
std::basic_string<UserChar,
|
|
std::char_traits<UserChar>,
|
|
std::allocator<UserChar> >*)
|
|
{
|
|
// UserChar digits zero and one
|
|
static const UserChar dig[] = { { 0, '0' }, { 0, '1' } };
|
|
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.template to_string<UserChar>(zero, dig [1]);
|
|
case 0:
|
|
return bs.template to_string<UserChar>(dig [0], dig [1]);
|
|
}
|
|
|
|
return bs.template to_string<UserChar>(zero, one);
|
|
}
|
|
|
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
|
|
// call the bitset<N>::to_string() ordinary member function,
|
|
// explicitly specifying none of the three template arguments,
|
|
// and 2, 1, or 0 of the two default function arguments
|
|
template <std::size_t N>
|
|
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
|
|
bitset_to_string_0 (const std::bitset<N> &bs, int nfargs,
|
|
char zero, char one,
|
|
std::basic_string<char, std::char_traits<char>,
|
|
std::allocator<char> >*)
|
|
{
|
|
// invoke to_string with the number of function arguments specified
|
|
switch (nfargs) {
|
|
case 1:
|
|
return bs.to_string (zero);
|
|
case 0:
|
|
return bs.to_string ();
|
|
}
|
|
|
|
return bs.to_string (zero, one);
|
|
}
|
|
|
|
|
|
inline char to_char (char ch) { return ch; }
|
|
inline char to_char (UserChar ch) { return ch.c; }
|
|
|
|
#ifndef _RWSTD_NO_WCHAR_T
|
|
inline char to_char (wchar_t ch) { return char (ch); }
|
|
#endif // _RWSTD_NO_WCHAR_T
|
|
|
|
|
|
// convert a basic_string object to a tempstr object for diagnostics
|
|
template <class charT, class Traits, class Alloc>
|
|
std::string narrow_string (const std::basic_string<charT, Traits, Alloc> &str)
|
|
{
|
|
std::string res;
|
|
|
|
for (std::size_t i = 0; i != str.size (); ++i)
|
|
res += to_char (str [i]);
|
|
|
|
return res;
|
|
}
|
|
|
|
#define TO_STR(s) narrow_string (s).c_str ()
|
|
|
|
|
|
// convert an ordinary string to a tempstr object for diagnostics
|
|
// using the binary digits specified by `bits'
|
|
std::string to_string (const char *str, const char bits [2])
|
|
{
|
|
std::string res;
|
|
|
|
std::size_t i;
|
|
|
|
for (i = 0; str [i]; ++i)
|
|
res += bits ['1' == str [i]];
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
template <std::size_t N, class charT, class Traits, class Alloc>
|
|
void test_to_string (std::bitset<N>*, charT*, Traits*, Alloc*,
|
|
bool nontemplate_done)
|
|
{
|
|
static const char* const cname = type_name (charT ());
|
|
static const char* const tname = traits_name ((Traits*)0);
|
|
static const char* const aname = alloc_name (Alloc ());
|
|
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%lu>::to_string<%s, %s, %s >()",
|
|
N, cname, tname, aname);
|
|
|
|
test_set<N> ts;
|
|
|
|
ts.random ();
|
|
|
|
const std::bitset<N> bs = ts.to_bitset ();
|
|
|
|
charT zero;
|
|
charT one;
|
|
|
|
assign (zero, 'o');
|
|
assign (one, 'x');
|
|
|
|
int pos;
|
|
|
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// exercise the overload of the to_string() member function template
|
|
// that takes all three template parameters different from char,
|
|
// char_traits<char>, and allocator<char>
|
|
|
|
typedef std::basic_string<charT, Traits, Alloc> String3;
|
|
|
|
String3 str3;
|
|
|
|
// specify none of the two function arguments (exercise defaults
|
|
// or the respective overloads)
|
|
str3 = bitset_to_string_3 (bs, 0, zero, one, (String3*)0);
|
|
pos = compare (str3.data (), ts.bits (), "01");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string () == \"%s\", got \"%s\": "
|
|
"mismatch at bit %d",
|
|
N, ts.bits (), TO_STR (str3), pos);
|
|
|
|
|
|
// specify one of the two function arguments (exercise the default
|
|
// or the respective overload)
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%lu>::to_string<%s, %s, %s >(\"%s\")",
|
|
N, cname, tname, aname, cname);
|
|
|
|
str3 = bitset_to_string_3 (bs, 1, zero, one, (String3*)0);
|
|
pos = compare (str3.data (), ts.bits (), "o1");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "o1").c_str (),
|
|
TO_STR (str3), pos);
|
|
|
|
|
|
// specify both of the two function arguments
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%lu>::to_string<%s, %s, %s >(%s, %s)",
|
|
N, cname, tname, aname, cname, cname);
|
|
|
|
str3 = bitset_to_string_3 (bs, 2, zero, one, (String3*)0);
|
|
pos = compare (str3.data (), ts.bits (), "ox");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o', 'x') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "ox").c_str (),
|
|
TO_STR (str3), pos);
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// exercise the overload of the to_string() member function template
|
|
// that takes the first two template parameters different from char,
|
|
// and char_traits<char>
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::to_string<%s, %s >()",
|
|
N, cname, tname);
|
|
|
|
typedef std::allocator<charT> CharTAlloc;
|
|
typedef std::basic_string<charT, Traits, CharTAlloc> String2;
|
|
|
|
String2 str2;
|
|
|
|
// specify none of the two function arguments (exercise defaults
|
|
// or the respective overloads)
|
|
str2 = bitset_to_string_2 (bs, 0, zero, one, (String2*)0);
|
|
pos = compare (str2.data (), ts.bits (), "01");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string () == %s, got %s: mismatch at bit %d",
|
|
N, ts.bits (), TO_STR (str2), pos);
|
|
|
|
|
|
// specify one of the two function arguments (exercise the default
|
|
// or the respective overload)
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%lu>::to_string<%s, %s >(%s)",
|
|
N, cname, tname, cname);
|
|
|
|
str2 = bitset_to_string_2 (bs, 1, zero, one, (String2*)0);
|
|
pos = compare (str2.data (), ts.bits (), "o1");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "o1").c_str (),
|
|
TO_STR (str2), pos);
|
|
|
|
|
|
// specify both of the two function arguments
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%lu>::to_string<%s, %s >(%s, %s)",
|
|
N, cname, tname, cname, cname);
|
|
|
|
str2 = bitset_to_string_2 (bs, 2, zero, one, (String2*)0);
|
|
pos = compare (str2.data (), ts.bits (), "ox");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o', 'x') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "ox").c_str (),
|
|
TO_STR (str2), pos);
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// exercise the overload of the to_string() member function template
|
|
// that takes the first template parameter different from char
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::to_string<%s>()",
|
|
N, cname);
|
|
|
|
typedef std::char_traits<charT> CharTraits;
|
|
typedef std::basic_string<charT, CharTraits, CharTAlloc> String1;
|
|
|
|
String1 str1;
|
|
|
|
// specify none of the two function arguments (exercise defaults
|
|
// or the respective overloads)
|
|
str1 = bitset_to_string_1 (bs, 0, zero, one, (String1*)0);
|
|
pos = compare (str1.data (), ts.bits (), "01");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string () == %s, got %s: mismatch at bit %d",
|
|
N, ts.bits (), TO_STR (str1), pos);
|
|
|
|
|
|
// specify one of the two function arguments (exercise the default
|
|
// or the respective overload)
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::to_string<%s>(%s)",
|
|
N, cname, cname);
|
|
|
|
str1 = bitset_to_string_1 (bs, 1, zero, one, (String1*)0);
|
|
pos = compare (str1.data (), ts.bits (), "o1");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "o1").c_str (),
|
|
TO_STR (str1), pos);
|
|
|
|
|
|
// specify both of the two function arguments
|
|
rw_info (0, 0, __LINE__,
|
|
"std::bitset<%lu>::to_string<%s>(%s, %s)",
|
|
N, cname, cname, cname);
|
|
|
|
str1 = bitset_to_string_1 (bs, 2, zero, one, (String1*)0);
|
|
pos = compare (str1.data (), ts.bits (), "ox");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o', 'x') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "ox").c_str (),
|
|
TO_STR (str1), pos);
|
|
|
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// exercise the non-template overload of the to_string() member
|
|
|
|
if (nontemplate_done)
|
|
return;
|
|
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::to_string ()", N);
|
|
|
|
typedef std::string String0;
|
|
|
|
String0 str0;
|
|
|
|
// specify none of the two function arguments (exercise defaults
|
|
// or the respective overloads)
|
|
str0 = bitset_to_string_0 (bs, 0, 'o', 'x', (String0*)0);
|
|
pos = compare (str0.data (), ts.bits (), "01");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string () == %s, got %s: mismatch at bit %d",
|
|
N, ts.bits (), str0.c_str (), pos);
|
|
|
|
|
|
// specify one of the two function arguments (exercise the default
|
|
// or the respective overload)
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::to_string (char)", N);
|
|
|
|
str0 = bitset_to_string_0 (bs, 1, 'o', 'x', (String0*)0);
|
|
pos = compare (str0.data (), ts.bits (), "o1");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "o1").c_str (),
|
|
str0.c_str (), pos);
|
|
|
|
|
|
// specify both of the two function arguments
|
|
rw_info (0, 0, __LINE__, "std::bitset<%lu>::to_string (char, char)", N);
|
|
|
|
str0 = bitset_to_string_0 (bs, 2, 'o', 'x', (String0*)0);
|
|
pos = compare (str0.data (), ts.bits (), "ox");
|
|
|
|
rw_assert (-1 == pos, 0, __LINE__,
|
|
"bitset<%lu>::to_string ('o', 'x') == %s, got %s: "
|
|
"mismatch at bit %d", N,
|
|
to_string (ts.bits (), "ox").c_str (),
|
|
str0.c_str (), pos);
|
|
}
|
|
|
|
|
|
template <std::size_t N>
|
|
void test_to_string (const std::bitset<N>*)
|
|
{
|
|
test_to_string ((std::bitset<N>*)0,
|
|
(char*)0,
|
|
(std::char_traits<char>*)0,
|
|
(std::allocator<char>*)0,
|
|
false);
|
|
|
|
#ifndef _RWSTD_NO_WCHAR_T
|
|
|
|
test_to_string ((std::bitset<N>*)0,
|
|
(wchar_t*)0,
|
|
(std::char_traits<wchar_t>*)0,
|
|
(std::allocator<wchar_t>*)0,
|
|
true);
|
|
|
|
#endif // _RWSTD_NO_WCHAR_T
|
|
|
|
test_to_string ((std::bitset<N>*)0,
|
|
(UserChar*)0,
|
|
(UserTraits<UserChar>*)0,
|
|
(std::allocator<UserChar>*)0,
|
|
true);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
template <std::size_t N>
|
|
void run_test (const std::bitset<N>*)
|
|
{
|
|
test_ctors ((std::bitset<N>*)0);
|
|
stress_ctors ((std::bitset<N>*)0);
|
|
test_elem_access ((std::bitset<N>*)0);
|
|
test_operators ((std::bitset<N>*)0);
|
|
test_other ((std::bitset<N>*)0);
|
|
stress_count ((std::bitset<N>*)0);
|
|
|
|
test_to_string ((std::bitset<N>*)0);
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static int
|
|
run_test (int, char**)
|
|
{
|
|
test_synopsis ((std::bitset<0>*)0);
|
|
|
|
#define DO_TEST(N) run_test ((std::bitset<N>*)0)
|
|
|
|
DO_TEST ( 0); // interesting case
|
|
DO_TEST ( 1); // interesting case
|
|
DO_TEST ( 2);
|
|
DO_TEST ( 31);
|
|
DO_TEST ( 32); // interesting case
|
|
DO_TEST ( 33); // interesting case
|
|
DO_TEST ( 34);
|
|
DO_TEST ( 63);
|
|
DO_TEST ( 64); // interesting case
|
|
DO_TEST ( 65); // interesting case
|
|
DO_TEST ( 66);
|
|
|
|
DO_TEST ( 123);
|
|
|
|
DO_TEST ( 127); // interesting case
|
|
DO_TEST ( 128); // interesting case
|
|
DO_TEST ( 129);
|
|
DO_TEST ( 130);
|
|
DO_TEST ( 255);
|
|
DO_TEST ( 256); // interesting case
|
|
|
|
#if !defined(_MSC_VER) || _MSC_VER != 1300
|
|
// FIXME: MSVC 514 can't compile bitset<257>!
|
|
DO_TEST ( 257); // interesting case
|
|
#endif
|
|
|
|
DO_TEST ( 258); // interesting case
|
|
DO_TEST ( 333);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
int main (int argc, char *argv[])
|
|
{
|
|
// TODO: add command line options to control tested functionality
|
|
return rw_test (argc, argv, __FILE__,
|
|
"lib.bitset",
|
|
0 /* no comment */,
|
|
run_test,
|
|
"",
|
|
(void*)0 /* sentinel */);
|
|
}
|