The attached file contains the updated according to your notes version
of the test for 21.string.capacity.
Martin Sebor wrote:
<>>Yes. That's the expected result. In general, the extended
formatting>directives (such as %{#*S}) format their arguments so that
they are human readable even when the arguments contain non-printable
characters.
Here I meant the following. Suppose my
basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >
contains the string "abc". And when I printed it
out in the --trace mode using the %{#*S} directive I have got "a\0b", but
"abc" (or "a\0b\0c\0" if each byte is printed) was expected.
Is this correct?
Thanks,
Anton Pevtsov
<>
-----Original Message-----
From: Martin Sebor [mailto:[EMAIL PROTECTED]
Sent: Tuesday, March 07, 2006 02:14
To: [email protected]
Subject: Re: test for 21.strings.capacity
Anton Pevtsov wrote:
The attached file contains the updated version of the test for
21.string.capacity. I modified the code and pass the tested string
length to the widen function and basic_string ctor to avoid the bug
with strings containing embedded NULs.
Okay. There still are a small number of improvements that I think would
make the test better. For one, it would be helpful to line up the
arguments to the TEST macro to make them easier to read. Also, it would
make the test for each member function more readable if you added arrows
pointing to each argument and documenting what each stands for (as is
already done in test_reserve).
I'm also not sure I understand the purpose of widening "a" when the str
argument is 0 in test_string_capacity. It seems that widen should be
called with the 0 pointer in this case (widen handles NULL pointers just
fine).
Finally, there is no difference between invoking the test function like
this
TEST ("Test\0string", 11);
or like this:
TEST ("Test\000string", 11);
Either way the effect is identical since \0 and \000 both represent the
NUL character. Instead I would exercise sequences of consecutive NULs
such as "\0", "\0\0", and "\0\0\0" and similar sequences but with
non-NULs thrown in, e.g., "\0a\0", "\0ab\0", etc.
But I suspect a bug in the rw_assert formatting output for {#*S}. The
wchar string "abc" is displayed as "a\0b" (maybe the function dumps
each byte, not symbol here).
Yes. That's the expected result. In general, the extended formatting
directives (such as %{#*S}) format their arguments so that they are
human readable even when the arguments contain non-printable characters.
Here's an example:
$ cat t.cpp && ./t
#include <string>
#include <rw_printf.h>
int main ()
{
const std::string s ("abc\0def", 7);
const std::wstring ws (L"abc\0def", 7);
rw_printf ("%{#1S}\n", &s);
rw_printf ("%{#*S}\n", sizeof (wchar_t), &ws);
}
"abc\0def"
L"abc\0def"
Btw., maybe it would be useful to move the widen function to rw_char
header (or some another place in the test driver).
Definitely. I suspect three overloads of rw_widen() will actually be
useful (and already are being used in various forms throughout the test
suite):
char* rw_widen (char*, const char*, size_t);
wchar_t* rw_widen (wchar_t*, const char*, size_t);
UserChar* rw_widen (UserChar*, const char*, size_t);
where the first is equivalent to memcpy().
Martin
/***************************************************************************
*
* 21.string.capacity.cpp - test exercising [lib.string.capacity]
*
* $Id:
*
***************************************************************************
*
* Copyright 2006 The Apache Software Foundation or its licensors,
* as applicable.
*
* Copyright 2006 Rogue Wave Software.
*
* Licensed 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.
*
**************************************************************************/
#include <string>
#include <cstddef>
#include <stdexcept>
#include <cmdopt.h>
#include <driver.h>
/**************************************************************************/
int traits_eof = -1;
template <class charT>
struct CharTraits: std::char_traits<charT>
{
typedef std::char_traits<charT> Base;
typedef typename Base::int_type int_type;
// override eof() to detect bad assumptions
static int_type eof () { return traits_eof; }
static int_type not_eof (int_type c) {
return c == eof () ? int_type (!c) : c;
}
};
/**************************************************************************/
struct MemFun
{
enum charT { Char, WChar };
enum Traits { DefaultTraits, UserTraits };
enum FunTag {
// which member function to exercise
size, resize, length, reserve, capacity, max_size, clear, empty
};
MemFun (charT cid, const char *cname,
Traits tid, const char *tname)
: cid_ (cid), tid_ (tid), mfun_ (),
cname_ (cname), tname_ (tname), aname_ ("allocator"),
fname_ (0),
max_size_ (0) { /* empty */ }
charT cid_; // character type id (char or wchar_t)
Traits tid_; // traits type id (default or user-defined)
FunTag mfun_; // member function id
const char *cname_; // character type name
const char *tname_; // traits name
const char *aname_; // allocator name
const char *fname_; // function name
unsigned int max_size_;
};
/**************************************************************************/
static const int long_string_len = 4096;
static char long_string [long_string_len];
/**************************************************************************/
template <class charT>
void widen (charT *buf, const char *str, const std::size_t str_len)
{
typedef unsigned char UChar;
buf[0] = charT (UChar ('\0'));
RW_ASSERT (str_len < sizeof long_string);
if (str) {
for (std::size_t i = 0; i < str_len; i++)
buf[i] = charT (UChar (str[i]));
}
}
/**************************************************************************/
template <class charT, class String>
void test_resize (charT, const MemFun *pfid,
int line, // line number
String *pstr, // pointer string object
const char *str, // source string argument
std::size_t str_len, // the string length
std::size_t nparam, // method parameter
char cparam, // method parameter char
bool should_throw) // if true the method should throw
{
typedef unsigned char UChar;
charT chart_param = charT (UChar (cparam));
charT chart_eof = charT (UChar ('\0'));
bool resize2args = charT (UChar (-1)) != chart_param;
#ifndef _RWSTD_NO_EXCEPTIONS
bool ex_thrown = false;
try {
#endif // _RWSTD_NO_EXCEPTIONS
if (resize2args)
pstr->resize (nparam, chart_param);
else
pstr->resize (nparam);
#ifndef _RWSTD_NO_EXCEPTIONS
}
catch (std::length_error e) {
_RWSTD_UNUSED(e);
ex_thrown = true;
}
rw_assert (should_throw == ex_thrown, 0, line,
"line %d. basic_string<%s, %s<%2$s>, %s<%2$s>>(%{#*S})"
".resize(%zu%{?}, %#c%{;}) "
"should throw == %b, was thrown == %b",
__LINE__, pfid->cname_, pfid->tname_, pfid->aname_,
int (sizeof (charT)), pstr, nparam,
resize2args, chart_param, should_throw, ex_thrown);
if (ex_thrown)
return;
#else // _RWSTD_NO_EXCEPTIONS
_RWSTD_UNUSED (should_throw);
#endif
// check the results
static charT wstr_tmp [long_string_len];
widen (wstr_tmp, str, str_len);
std::size_t ubound = nparam < str_len ? nparam : str_len;
bool success = true;
std::size_t i = 0;
for (; i < ubound; i++) {
success = wstr_tmp[i] == pstr->c_str()[i];
if (!success)
break;
}
if (0 < ubound) {
// to avoid errors in --trace mode
i = i < ubound ? i : ubound - 1;
rw_assert (success, 0, line,
"line %d. basic_string<%s, %s<%2$s>, %s<%2$s>>(%{#*S})"
".resize(%zu%{?}, %#c%{;}): got %#c at %zu, expected %#c",
__LINE__, pfid->cname_, pfid->tname_, pfid->aname_,
int (sizeof (charT)), pstr, nparam, resize2args, chart_param,
pstr->c_str()[i], i + 1, wstr_tmp[i]);
}
if (resize2args) {
i = ubound;
ubound = str_len < nparam ? nparam : 0;
for (; i < ubound; i++) {
success = chart_param == pstr->c_str()[i];
if (!success)
break;
}
if (0 < ubound) {
// to avoid errors in --trace mode
i = i < ubound ? i : ubound - 1;
rw_assert (success, 0, line,
"line %d. basic_string<%s, %s<%2$s, %s<%2$s>>(%{#*S})."
"resize(%zu, %#c): got %{?}%#c%{;}%{?}'%s'%{;} "
"at %zu, expected %#c",
__LINE__, pfid->cname_, pfid->tname_, pfid->aname_,
int (sizeof (charT)), pstr, nparam, cparam,
chart_eof != pstr->c_str()[i], pstr->c_str()[i],
chart_eof == pstr->c_str()[i], "eof", i + 1,
chart_param);
}
}
else {
const std::string::size_type sz_tmp = pstr->size ();
rw_assert (nparam == sz_tmp, 0, line,
"line %d. basic_string<%s, %s<%2$s>, %s<%2$s>>(%{#*S})"
".resize(%zu): size() == %5$zu, got %zu",
__LINE__, pfid->cname_, pfid->tname_, pfid->aname_,
int (sizeof (charT)), pstr, nparam, sz_tmp);
}
}
/**************************************************************************/
template <class charT, class Traits>
void test_string_capacity (charT, Traits, const MemFun *pfid,
int line, // line number
const char *str, // string argument
std::size_t str_len, // the string length
std::size_t nparam, // method parameter
char cparam, // method parameter char
std::size_t res, // method expected result
bool should_throw) // the method should throw
{
typedef std::allocator<charT> Allocator;
typedef std::basic_string<charT, Traits, Allocator> TestString;
if (!rw_enabled (line)) {
rw_note (0, 0, 0, "test on line %d disabled", line);
return;
}
// widen the source sequence into the (possibly wide) character buffer
static charT wstr [long_string_len];
widen (wstr, str, str_len);
TestString str_ob (wstr, str_len);
TestString str_def;
TestString* const pstr = 0 != str ? &str_ob : &str_def;
if (MemFun::resize == pfid->mfun_)
return test_resize (charT (), pfid, line, pstr, str, str_len,
nparam, cparam, should_throw);
std::string::size_type ret = 0;
std::string::size_type exp_ret = res;
#ifndef _RWSTD_NO_EXCEPTIONS
const char* const expected = should_throw ? "length_error" : 0;
const char* caught = 0;
try {
#endif // _RWSTD_NO_EXCEPTIONS
// invoke the virtual function with the expected argument (if any)
switch (pfid->mfun_) {
case MemFun::size:
ret = pstr->size ();
break;
case MemFun::length:
ret = pstr->length ();
exp_ret = pstr->size ();
break;
case MemFun::resize:
// do nothing, handled above
break;
case MemFun::reserve:
0 == nparam ? pstr->reserve () : pstr->reserve (nparam);
break;
case MemFun::capacity:
ret = pstr->capacity ();
break;
case MemFun::max_size:
ret = pstr->max_size ();
break;
case MemFun::empty:
ret = pstr->empty () ? 1 : 0;
exp_ret = 0 == pstr->size() ? 1 : 0;
break;
case MemFun::clear:
pstr->clear ();
break;
}
#define CALLFMAT \
"line %d. basic_string<%s, %s<%2$s>, %s<%2$s>>(%{?}%{#*S}%{;})" \
".%s(%{?}%zu%{;})"
#define CALLARGS \
__LINE__, pfid->cname_, pfid->tname_, pfid->aname_, \
0 != str, int (sizeof (charT)), pstr, pfid->fname_, \
MemFun::reserve == pfid->mfun_, nparam
#ifndef _RWSTD_NO_EXCEPTIONS
}
catch (std::length_error e) {
_RWSTD_UNUSED (e);
caught = expected;
}
catch (...) {
caught = "unknown exception";
}
rw_assert (caught == expected, 0, line,
CALLFMAT " %{?}expected %s, caught %s"
"%{:}unexpectedly caught %s%{;}",
CALLARGS, 0 != expected, expected, caught, caught);
if (should_throw || caught)
return;
#else // if defined (_RWSTD_NO_EXCEPTIONS)
_RWSTD_UNUSED (should_throw);
#endif // _RWSTD_NO_EXCEPTIONS
// check the results
if (MemFun::size == pfid->mfun_ || MemFun::length == pfid->mfun_ ||
MemFun::empty == pfid->mfun_) {
rw_assert (exp_ret == ret, 0, line,
CALLFMAT " == %zu, expected %zu",
CALLARGS, ret, exp_ret);
return;
}
if (MemFun::capacity == pfid->mfun_) {
std::string::size_type cur_sz = pstr->size();
std::string::size_type max_sz = pstr->max_size();
rw_assert (cur_sz <= ret && ret <= max_sz, 0, line,
CALLFMAT " == %zu, expected %zu < res < %zu%",
CALLARGS, ret, cur_sz, max_sz);
}
if (MemFun::max_size == pfid->mfun_) {
std::string::size_type cur_sz = pstr->size();
rw_assert (cur_sz <= ret, 0, line,
CALLFMAT " == %zu, expected res > %zu",
CALLARGS, ret, cur_sz);
}
if (MemFun::reserve == pfid->mfun_ ) {
ret = pstr->capacity ();
rw_assert (nparam <= ret, 0, line,
CALLFMAT ": capacity() >= %zu, got %zu",
CALLARGS, nparam, ret);
return;
}
if (MemFun::clear == pfid->mfun_ ) {
rw_assert (pstr->empty (), 0, line,
CALLFMAT ": string not empty", CALLARGS);
return;
}
}
/**************************************************************************/
void test_string_capacity (MemFun *pfid,
int line,
const char *str,
std::size_t str_len,
int nparam,
char cparam,
std::size_t res,
bool should_throw)
{
#undef TEST
#define TEST(charT, Traits) \
test_string_capacity (charT (), Traits (), pfid, line, \
str, str_len, nparam, cparam, res, should_throw)
static const char* const fnames[] = {
"size", "resize", "length", "reserve", "capacity", "max_size",
"clear", "empty"
};
if (!rw_enabled (line)) {
rw_note (0, 0, __LINE__, "test on line %d disabled", line);
return;
}
pfid->fname_ = fnames [pfid->mfun_];
pfid->max_size_ = MemFun::Char == pfid->cid_ ?
_RWSTD_SIZE_MAX / sizeof (char) - 1
: _RWSTD_SIZE_MAX / sizeof (wchar_t) - 1;
if (MemFun:: DefaultTraits == pfid->tid_) {
if (MemFun::Char == pfid->cid_)
TEST (char, std::char_traits<char>);
#ifndef _RWSTD_NO_WCHAR_T
else
TEST (wchar_t, std::char_traits<wchar_t>);
#endif // _RWSTD_NO_WCHAR_T
}
else {
if (MemFun::Char == pfid->cid_)
TEST (char, CharTraits<char>);
#ifndef _RWSTD_NO_WCHAR_T
else
TEST (wchar_t, CharTraits<wchar_t>);
#endif // _RWSTD_NO_WCHAR_T
}
}
/**************************************************************************/
void test_size (MemFun *pfid)
{
rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::size ()",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str, size) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
0, 0, size, false)
// +--------------------------------------- controlled sequence
// | +---------------------- expected result
// | |
// | |
// V V
TEST (0, 0);
TEST ("", 0);
TEST ("\0", 1);
TEST ("a", 1);
TEST (" ", 1);
TEST ("ab", 2);
TEST ("bc", 2);
TEST ("test string", 11);
TEST ("Test String", 11);
TEST ("t\000 s", 4);
TEST ("Test\0string", 11);
TEST ("\0a\0b", 4);
TEST ("a\0\0b", 4);
TEST ("a\0\0\0b", 5);
TEST ("a\0\0b\0", 5);
TEST ("a\0b\0\0c", 6);
TEST ("a\0b\0c\0\0", 7);
TEST (long_string, long_string_len - 1);
}
/**************************************************************************/
void test_resize (MemFun *pfid)
{
rw_info (0, 0, 0,
"std::basic_string<%s, %s<%1$s>, %s<%1$s>>::resize "
"(size_type, char_type)",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str, len, nparam, cparam, ex_throw) \
test_string_capacity (pfid, __LINE__, str, len, nparam, \
cparam, 0, ex_throw)
// +--------------------------------------- controlled sequence
// | +----------------------- controlled sequence length
// | | +-- resize() integer argument
// | | | +-- resize() char argument
// | | | | +--exception expected?
// | | | | |
// V V V V V
TEST ("\0", 0, 0, 'a', false);
TEST ("\0", 0, 10, 'a', false);
TEST ("a", 1, 1, 'a', false);
TEST ("a", 1, 0, 'a', false);
TEST ("a", 1, 10, 'a', false);
TEST ("ab", 2, 2, 'a', false);
TEST ("ab", 2, 1, 'a', false);
TEST ("ab", 2, 10, 'a', false);
TEST ("t\000 s", 4, 6, 'a', false);
TEST ("Test\0string", 11, 100, 'a', false);
TEST ("a\0\0\0b", 5, 10, 'a', false);
TEST ("a\0\0\0b", 5, 10, '\0', false);
TEST ("a\0b\0c\0\0", 7, 10, 'a', false);
TEST ("a\0b\0c\0\0", 7, 10, '\0', false);
TEST ("bc", 2, long_string_len - 1, 'a', false);
TEST (long_string, long_string_len - 1, 10, 'a', false);
TEST (long_string, long_string_len - 1, long_string_len - 1, 'a', false);
#ifndef _RWSTD_NO_EXCEPTIONS
if (_RWSTD_SIZE_MAX > pfid->max_size_) {
TEST ("\0", 1, pfid->max_size_ + 1, 'a', true);
TEST ("a" , 1, pfid->max_size_ + 1, 'a', true);
TEST (long_string, long_string_len - 1,
pfid->max_size_ + 1, 'a', true);
}
#endif //_RWSTD_NO_EXCEPTIONS
rw_info (0, 0, 0,
"std::basic_string<%s, %s<%1$s>, %s<%1$s>>::resize (size_type)",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str, nparam, ex_throw) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
nparam, -1, 0, ex_throw)
// +---------------------------------------- controlled sequence
// | +-------------------------- resize() integer argument
// | | +-- exception expected?
// | | |
// V V V
TEST ("\0", 0, false);
TEST ("\0", 10, false);
TEST ("a", 1, false);
TEST ("a", 0, false);
TEST ("a", 10, false);
TEST ("ab", 2, false);
TEST ("ab", 1, false);
TEST ("ab", 10, false);
TEST ("bc", long_string_len - 1, false);
TEST (long_string, 10, false);
TEST (long_string, long_string_len - 1, false);
#ifndef _RWSTD_NO_EXCEPTIONS
if (_RWSTD_SIZE_MAX > pfid->max_size_) {
TEST ("\0", pfid->max_size_ + 1, true);
TEST ("a", pfid->max_size_ + 1, true);
TEST (long_string, pfid->max_size_ + 1, true);
}
#endif // _RWSTD_NO_EXCEPTIONS
}
/**************************************************************************/
void test_length (MemFun *pfid)
{
rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::length ()",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str, size) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
0, 0, size, false)
// +--------------------------------------- controlled sequence
// | +---------------------- expected result
// | |
// | |
// V V
TEST (0, 0);
TEST ("", 0);
TEST ("\0", 1);
TEST ("a", 1);
TEST (" ", 1);
TEST ("ab", 2);
TEST ("bc", 2);
TEST ("Test String", 11);
TEST ("t\000 s", 4);
TEST ("Test\0string", 11);
TEST ("\0a\0b", 4);
TEST ("a\0\0b", 4);
TEST ("a\0\0\0b", 5);
TEST ("a\0\0b\0", 5);
TEST ("a\0b\0\0c", 6);
TEST ("a\0b\0c\0\0", 7);
TEST (long_string, long_string_len - 1);
#undef TEST
}
/**************************************************************************/
void test_reserve (MemFun *pfid)
{
rw_info (0, 0, 0,
"std::basic_string<%s, %s<%1$s>, %s<%1$s>>::reserve (size_type)",
pfid->cname_, pfid->tname_, pfid->aname_);
#define TEST(str, nparam, ex_throw) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
nparam, 0, 0, ex_throw)
// +--------------------------------------- controlled sequence
// | +---------------------- reserve() argument
// | | +-- exception expected?
// | | |
// V V V
TEST (0, 0, false);
TEST (0, 10, false);
TEST (0, long_string_len - 1, false);
TEST ("\0", 0, false);
TEST ("\0", 10, false);
TEST ("\0", long_string_len - 1, false);
TEST ("abcd", 0, false);
TEST ("abcd", 2, false);
TEST ("abcd", 4, false);
TEST ("abcd", 10, false);
TEST ("abcd", long_string_len - 1, false);
TEST ("t\000 s", 1, false);
TEST ("Test\0string", 4, false);
TEST ("a\0\0b", 2, false);
TEST ("a\0\0b", 10, false);
TEST ("a\0b\0c\0\0", 4, false);
TEST ("a\0b\0c\0\0", 10, false);
TEST (long_string, 10, false);
TEST (long_string, long_string_len - 1, false);
#ifndef _RWSTD_NO_EXCEPTIONS
if (_RWSTD_SIZE_MAX > pfid->max_size_) {
TEST ("\0", pfid->max_size_ + 1, true);
TEST ("a", pfid->max_size_ + 1, true);
TEST (long_string, pfid->max_size_ + 1, true);
}
#endif // _RWSTD_NO_EXCEPTIONS
}
/**************************************************************************/
void test_capacity (MemFun *pfid)
{
rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::capacity ()",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str, size) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
0, 0, size, false)
// +--------------------------------------- controlled sequence
// | +---------------------- expected result
// | |
// | |
// V V
TEST (0, 0);
TEST ("\0", 0);
TEST ("a", 128);
TEST ("abcd", 128);
TEST ("t\000 s", 128);
TEST ("Test\0string", 128);
TEST ("\0a\0b", 128);
TEST ("a\0\0\0b", 128);
TEST ("a\0b\0c\0\0", 128);
TEST (long_string, long_string_len - 1);
}
/**************************************************************************/
void test_max_size (MemFun *pfid)
{
rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::max_size ()",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
0, 0, 0, false)
TEST (0);
TEST ("\0");
TEST ("abcd");
TEST (long_string);
}
/**************************************************************************/
void test_clear (MemFun *pfid)
{
rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::clear ()",
pfid->cname_, pfid->tname_, pfid->aname_);
#undef TEST
#define TEST(str) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
0, 0, 0, false)
TEST (0);
TEST ("\0");
TEST ("a");
TEST ("ab");
TEST ("abcde");
TEST ("t\000 s");
TEST ("Test\0string");
TEST ("\0a\0b");
TEST ("a\0\0\0b");
TEST ("a\0b\0c\0\0");
TEST (long_string);
}
/**************************************************************************/
void test_empty (MemFun *pfid)
{
rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::empty ()",
pfid->cname_, pfid->tname_, pfid->aname_);
pfid->mfun_ = MemFun::empty;
#undef TEST
#define TEST(str) \
test_string_capacity (pfid, __LINE__, str, sizeof str - 1, \
0, 0, 0, false)
TEST (0);
TEST ("\0");
TEST ("a");
TEST ("ab");
TEST ("abcde");
TEST ("\000 s");
TEST ("t\000 s");
TEST ("Test\0string");
TEST ("\0a\0b");
TEST ("a\0\0\0b");
TEST ("a\0b\0c\0\0");
TEST (long_string);
#undef TEST
}
/**************************************************************************/
static int rw_opt_no_size; // for --no-size
static int rw_opt_no_resize; // for --no-resize
static int rw_opt_no_length; // for --no-length
static int rw_opt_no_reserve; // for --no-reserve
static int rw_opt_no_capacity; // for --no-capacity
static int rw_opt_no_max_size; // for --no-max_size
static int rw_opt_no_clear; // for --no-clear
static int rw_opt_no_empty; // for --no-empty
static int rw_opt_no_char_traits; // for --no-char_traits
static int rw_opt_no_user_traits; // for --no-user_traits
/**************************************************************************/
static void
run_test (MemFun *pfid)
{
#undef TEST
#define TEST(function) \
if (rw_opt_no_ ## function) \
rw_note (1 < rw_opt_no_ ## function++, 0, 0, \
"%s test disabled", #function); \
else { \
pfid->mfun_ = MemFun::function; \
test_ ## function (pfid); \
} (void)0
if (pfid->tname_ && rw_opt_no_user_traits) {
rw_note (1 < rw_opt_no_user_traits++, 0, 0,
"user defined traits test disabled");
}
else if (!pfid->tname_ && rw_opt_no_char_traits) {
rw_note (1 < rw_opt_no_char_traits++, 0, 0,
"char_traits test disabled");
}
else {
TEST (size);
TEST (resize);
TEST (length);
TEST (reserve);
TEST (capacity);
TEST (max_size);
TEST (clear);
TEST (empty);
}
}
/**************************************************************************/
int run_test (int, char*[])
{
if ('\0' == long_string [0]) {
// initialize long_string
for (std::size_t i = 0; i != sizeof long_string - 1; ++i)
long_string [i] = 'x';
}
if (rw_enabled ("char")) {
MemFun fid (MemFun::Char, "char", MemFun::DefaultTraits, 0);
traits_eof = -1;
fid.tname_ = "char_traits";
run_test (&fid);
fid.tid_ = MemFun::UserTraits;
fid.tname_ = "UserTraits";
traits_eof = '$';
run_test (&fid);
}
else
rw_note (0, 0, 0, "string.capacity char tests disabled");
if (rw_enabled ("wchar_t")) {
MemFun fid (MemFun::WChar, "wchar_t", MemFun::DefaultTraits, 0);
traits_eof = -1;
fid.tname_ = "char_traits";
run_test (&fid);
fid.tid_ = MemFun::UserTraits;
fid.tname_ = "UserTraits";
traits_eof = '$';
run_test (&fid);
}
else
rw_note (0, 0, 0, "string.capacity wchar tests disabled");
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.string.capacity",
0 /* no comment */, run_test,
"|-no-size# "
"|-no-resize# "
"|-no-length# "
"|-no-reserve# "
"|-no-capacity# "
"|-no-max_size# "
"|-no-clear# "
"|-no-empty# "
"|-no-char_traits# "
"|-no-user_traits",
&rw_opt_no_size,
&rw_opt_no_resize,
&rw_opt_no_length,
&rw_opt_no_reserve,
&rw_opt_no_capacity,
&rw_opt_no_max_size,
&rw_opt_no_clear,
&rw_opt_no_empty,
&rw_opt_no_char_traits,
&rw_opt_no_user_traits);
}