first commit

This commit is contained in:
Jose Caban
2025-06-07 11:34:38 -04:00
commit 0eb2d7c07d
4708 changed files with 1500614 additions and 0 deletions

View File

@@ -0,0 +1,847 @@
/***************************************************************************
*
* 23.bitset.cons.cpp - test exercising [lib.bitset.cons]
*
* $Id: 23.bitset.cons.cpp 429065 2006-08-05 21:57:17Z sebor $
*
***************************************************************************
*
* 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 2004-2006 Rogue Wave Software.
*
**************************************************************************/
#include <bitset> // for bitset
#include <stdexcept> // for invalid_argument, out_of_range
#include <string> // for basic_string
#include <cstddef> // for size_t
#include <rw_char.h> // for UserChar, UserTraits
#include <driver.h> // for rw_test(), ...
/**************************************************************************/
int opt_char; // for --no-char
int opt_wchar; // for --no-wchar_t
int opt_userchar; // for --no-UserChar
int opt_no_exceptions; // for --no-exceptions
/**************************************************************************/
template <std::size_t N>
int bcmp (const std::bitset<N> &bset,
const char *str)
{
RW_ASSERT (0 != str);
for (std::size_t i = 0; i != N; ++i) {
const char bit = bset [i] ? '1' : '0';
if (bit != str [N - i - 1])
return -1;
}
return 0;
}
/**************************************************************************/
// equivalent to the result of std::bitset<bits>(val).to_string<char>()
const char*
ulong_to_bitstring (unsigned long val, std::size_t bits)
{
const std::size_t ulongbits = sizeof (unsigned long) * 8;
static char bitstr [1024];
for (std::size_t i = 0; i != bits; ++i) {
if (i < ulongbits)
bitstr [bits - i - 1] = val & (1UL << i) ? '1' : '0';
else
bitstr [bits - i - 1] = '0';
}
bitstr [bits] = '\0';
return bitstr;
}
/**************************************************************************/
// exercises the effects of the default bitset ctor
template <std::size_t N>
void test_default_ctor (std::bitset<N>*)
{
rw_info (0, 0, __LINE__, "std::bitset<%u>::bitset()", N);
const std::bitset<N> bset;
char all_zeros [N + 1];
for (std::size_t i = 0; i != N; ++i) all_zeros [i] = '0';
all_zeros [N] = '\0';
rw_assert (!bcmp (bset, all_zeros), 0, __LINE__,
"bitset<%u>::bitset() expected 0, got { %.*b }",
N, int (N), &bset);
}
/**************************************************************************/
// exercises the effects of bitset<N>::bitset(unsigned long)
template <std::size_t N>
void test_long_ctor (std::bitset<N>*)
{
rw_info (0, 0, __LINE__, "std::bitset<%u>::bitset(unsigned long)", N);
#undef DO_TEST
#define DO_TEST(T, val) \
do { \
const T v = val; \
const std::bitset<N> bset (v); \
const char* const bstr = ulong_to_bitstring (val, N); \
rw_assert (!bcmp (bset, (const char*)bstr), 0, __LINE__, \
"bitset<%u>::bitset(%zu) == { %{.*b} }, " \
"got { %{.*b} }", N, val, bstr, int (N), &bset); \
} while (0)
DO_TEST (unsigned long, 0);
DO_TEST (unsigned long, 1);
DO_TEST (unsigned long, 2);
DO_TEST (unsigned long, 3);
DO_TEST (unsigned long, 4);
DO_TEST (unsigned long, 5);
DO_TEST (unsigned long, 6);
DO_TEST (unsigned long, 7);
DO_TEST (unsigned long, 8);
DO_TEST (unsigned long, 9);
DO_TEST (unsigned long, 10);
DO_TEST (unsigned long, 11);
DO_TEST (unsigned long, 12);
DO_TEST (unsigned long, 13);
DO_TEST (unsigned long, 14);
DO_TEST (unsigned long, 15);
DO_TEST (unsigned long, _RWSTD_LONG_MAX / 16);
DO_TEST (unsigned long, _RWSTD_LONG_MAX / 8);
DO_TEST (unsigned long, _RWSTD_LONG_MAX / 4);
DO_TEST (unsigned long, _RWSTD_LONG_MAX / 2);
DO_TEST (unsigned long, _RWSTD_LONG_MAX - 2);
DO_TEST (unsigned long, _RWSTD_LONG_MAX - 1);
DO_TEST (unsigned long, _RWSTD_LONG_MAX);
// exercise calls to the ctor with arguments of other integer types
DO_TEST (char, 16);
DO_TEST (signed char, 17);
DO_TEST (unsigned char, 18);
DO_TEST (short, 19);
DO_TEST (unsigned short, 20);
DO_TEST (int, 21);
DO_TEST (unsigned int, 22);
DO_TEST (long, 23);
}
/**************************************************************************/
// invokes coverting bitset ctor from basic_string<char, ...>
template <std::size_t N, class Traits, class Allocator>
std::bitset<N>
bitset_ctor (std::bitset<N>*,
const std::basic_string<char, Traits, Allocator> *bstr,
const char *str,
std::size_t pos, std::size_t n, const char bin_digits [2])
{
if (bstr) {
if (std::size_t (-1) == pos)
return std::bitset<N>(*bstr);
if (std::size_t (-1) == n)
return std::bitset<N>(*bstr, pos);
if (0 == bin_digits)
return std::bitset<N>(*bstr, pos, n);
if (Traits::eq (bin_digits [0], bin_digits [1]))
return std::bitset<N>(*bstr, pos, n, bin_digits [0]);
return std::bitset<N>(*bstr, pos, n, bin_digits [0], bin_digits [1]);
}
#if !defined (_RWSTD_NO_EXT_BITSET_CTOR_CHAR_ARRAY) \
&& !defined (_RWSTD_NO_EXT_BITSET_CTOR_STRING)
if (std::size_t (-1) == pos)
return std::bitset<N>(str);
if (std::size_t (-1) == n)
return std::bitset<N>(str, pos);
if (0 == bin_digits)
return std::bitset<N>(str, pos, n);
if (Traits::eq (bin_digits [0], bin_digits [1]))
return std::bitset<N>(str, pos, n, bin_digits [0]);
return std::bitset<N>(str, pos, n, bin_digits [0], bin_digits [1]);
#else
RW_ASSERT (!"test logic error");
return std::bitset<N>();
#endif // _RWSTD_NO_EXT_BITSET_CTOR_{CHAR_ARRAY,STRING)
}
#ifndef _RWSTD_NO_WCHAR_T
// invokes coverting bitset ctor from basic_string<wchar_t, ...>
template <std::size_t N, class Traits, class Allocator>
std::bitset<N>
bitset_ctor (std::bitset<N>*,
const std::basic_string<wchar_t, Traits, Allocator> *bstr,
const wchar_t *wstr,
std::size_t pos, std::size_t n, const wchar_t bin_digits [2])
{
if (bstr) {
if (std::size_t (-1) == pos)
return std::bitset<N>(*bstr);
if (std::size_t (-1) == n)
return std::bitset<N>(*bstr, pos);
if (0 == bin_digits)
return std::bitset<N>(*bstr, pos, n);
if (Traits::eq (bin_digits [0], bin_digits [1]))
return std::bitset<N>(*bstr, pos, n, bin_digits [0]);
return std::bitset<N>(*bstr, pos, n, bin_digits [0], bin_digits [1]);
}
#if !defined (_RWSTD_NO_EXT_BITSET_CTOR_CHAR_ARRAY) \
&& !defined (_RWSTD_NO_EXT_BITSET_CTOR_STRING)
if (std::size_t (-1) == pos)
return std::bitset<N>(wstr);
if (std::size_t (-1) == n)
return std::bitset<N>(wstr, pos);
if (0 == bin_digits)
return std::bitset<N>(wstr, pos, n);
if (Traits::eq (bin_digits [0], bin_digits [1]))
return std::bitset<N>(wstr, pos, n, bin_digits [0]);
return std::bitset<N>(wstr, pos, n, bin_digits [0], bin_digits [1]);
#else
RW_ASSERT (!"test logic error");
return std::bitset<N>();
#endif // _RWSTD_NO_EXT_BITSET_CTOR_{CHAR_ARRAY,STRING)
}
#endif // _RWSTD_NO_WCHAR_T
// invokes coverting bitset ctor from basic_string<UserChar, ...>
template <std::size_t N, class Traits, class Allocator>
std::bitset<N>
bitset_ctor (std::bitset<N>*,
const std::basic_string<UserChar, Traits, Allocator> *bstr,
const UserChar* /* intentionally unused */,
std::size_t pos, std::size_t n, const UserChar bin_digits [2])
{
if (std::size_t (-1) == pos)
pos = 0;
if (0 == bin_digits) {
static const UserChar zero_one[] = { { 0.0, '0' }, { 0.0, '1' } };
bin_digits = zero_one;
}
if (bstr)
return std::bitset<N>(*bstr, pos, n, bin_digits [0], bin_digits [1]);
// cannot invoke std::bitset<N>(const UserChar*) without providing
// an explicit specialization of std::char_traits<UserChar> that
// implements eq() and length()
RW_ASSERT (!"test logic error");
return std::bitset<N>();
}
// constructs a bitset object by invoking one of the overloaded ctors
template <std::size_t N, class charT, class Traits, class Allocator>
std::bitset<N>
bitset_ctor (std::bitset<N>*,
std::basic_string<charT, Traits, Allocator> *p,
const char *str, std::size_t pos, std::size_t n)
{
charT wstr [1024];
for (std::size_t i = 0; i != sizeof wstr / sizeof *wstr; ++i) {
if (str [i])
Traits::assign (wstr [i], make_char (str [i], (charT*)0));
else {
Traits::assign (wstr [i], charT ());
break;
}
}
typedef std::bitset<N> Bitset;
typedef std::basic_string<charT, Traits, Allocator> String;
if (p) { // use one of the const basic_string& overloads
const String bstr (wstr);
return bitset_ctor ((Bitset*)0, &bstr, 0, pos, n, (charT*)0);
}
else { // invoke one of the const charT* overloads
return bitset_ctor ((Bitset*)0, (String*)0, wstr, pos, n, (charT*)0);
}
}
template <class charT>
const char* type_prefix (charT) { return ""; }
#ifndef _RWSTD_NO_WCHAR_T
const char* type_prefix (wchar_t) { return "L"; }
#endif // _RWSTD_NO_WCHAR_T
enum { InvalidArgument = 1, OutOfRange };
template <std::size_t N, class charT, class Traits, class Allocator>
void test_string_ctor (std::bitset<N>*,
std::basic_string<charT, Traits, Allocator> *p,
int line,
const char *str, std::size_t pos, std::size_t n,
const char *bitstr)
{
static const char* const tpfx = type_prefix (charT ());
typedef std::bitset<N> Bitset;
typedef std::basic_string<charT, Traits, Allocator> String;
static const char* const exstr[] = {
"failed to throw",
"caught std::invalid_argument",
"caught std::out_of_range",
"caught unknown exception"
};
// compute which exception, if any, the ctor is expected to throw
const int except = bitstr - (char*)0 < 3 ? bitstr - (char*)0 : 0;
if (except && opt_no_exceptions)
return;
int caught = 0;
_TRY {
// invoke one of the overloads of the constructor
const Bitset bset = bitset_ctor ((Bitset*)0, p, str, pos, n);
if (!except)
rw_assert (!bcmp (bset, bitstr), 0, line,
"line %d: bitset<%u>::bitset(%s\"%s\""
"%{?}, %zu%{?}, %zu%{;}%{;}) "
"== { %s }, got { %{.*b} }",
__LINE__, N, tpfx, str,
pos != std::size_t (-1), pos,
n != std::size_t (-1), n,
bitstr, int (N), &bset);
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::out_of_range&) {
caught = OutOfRange;
}
catch (const std::invalid_argument&) {
caught = InvalidArgument;
}
catch (...) {
caught = 3;
}
#endif // _RWSTD_NO_EXCEPTIONS
rw_assert (except == caught, 0, line,
"line %d: bitset<%u>::bitset(%s\"%s\", %u, %u) "
"unexpectedly %s", __LINE__, N, tpfx, str, pos, n,
exstr [caught]);
}
std::string
fillstr (const char *pfx, int bit, std::size_t count, const char *sfx)
{
std::string str (pfx);
str.append (count, char ('0' + bit));
str.append (sfx);
return str;
}
template <class charT, class Traits, class Allocator>
void test_string_ctor (std::basic_string<charT, Traits, Allocator> *p,
const char *cname)
{
#undef DO_TEST
#define DO_TEST(N, str, pos, n, except) \
test_string_ctor ((std::bitset<N>*)0, p, __LINE__, \
str, std::size_t (pos), std::size_t (n), \
(const char*)except)
//////////////////////////////////////////////////////////////////
#define CTOR_INFO(N) \
rw_info (0, 0, __LINE__, "std::bitset<%i>::bitset(const " \
"%{?}std::basic_string<%s>&%{:}%3$s%{;})", \
N, 0 != p, cname)
CTOR_INFO (0);
#define TEST_1(N, str, except) DO_TEST(N, str, -1, -1, except)
// +----------- bitset size
// | +-------- string argument
// | | +-- result or exception
// v v v
TEST_1 (0, "", "");
TEST_1 (0, "0", "");
TEST_1 (0, "1", "");
TEST_1 (0, "2", InvalidArgument);
TEST_1 (0, "00", "");
TEST_1 (0, "01", "");
TEST_1 (0, "02", InvalidArgument);
CTOR_INFO (1);
TEST_1 (1, "", "0");
TEST_1 (1, "0", "0");
TEST_1 (1, "1", "1");
TEST_1 (1, "2", InvalidArgument);
TEST_1 (1, "00", "0");
TEST_1 (1, "01", "0");
TEST_1 (1, "02", InvalidArgument);
CTOR_INFO (2);
TEST_1 (2, "", "00");
TEST_1 (2, "0", "00");
TEST_1 (2, "1", "01");
TEST_1 (2, "2", InvalidArgument);
TEST_1 (2, "00", "00");
TEST_1 (2, "01", "01");
TEST_1 (2, "02", InvalidArgument);
TEST_1 (2, "10", "10");
TEST_1 (2, "11", "11");
TEST_1 (2, "12", InvalidArgument);
TEST_1 (2, "20", InvalidArgument);
TEST_1 (2, "21", InvalidArgument);
TEST_1 (2, "22", InvalidArgument);
TEST_1 (2, "000", "00");
TEST_1 (2, "001", "00");
TEST_1 (2, "002", InvalidArgument);
TEST_1 (2, "010", "01");
TEST_1 (2, "011", "01");
TEST_1 (2, "012", InvalidArgument);
TEST_1 (2, "020", InvalidArgument);
TEST_1 (2, "100", "10");
TEST_1 (2, "101", "10");
TEST_1 (2, "110", "11");
TEST_1 (2, "111", "11");
TEST_1 (2, "112", InvalidArgument);
TEST_1 (2, "200", InvalidArgument);
TEST_1 (2, "201", InvalidArgument);
TEST_1 (2, "202", InvalidArgument);
CTOR_INFO (3);
TEST_1 (3, "", "000");
TEST_1 (3, "0", "000");
TEST_1 (3, "1", "001");
TEST_1 (3, "2", InvalidArgument);
TEST_1 (3, "00", "000");
TEST_1 (3, "01", "001");
TEST_1 (3, "02", InvalidArgument);
TEST_1 (3, "10", "010");
TEST_1 (3, "11", "011");
TEST_1 (3, "12", InvalidArgument);
TEST_1 (3, "000", "000");
TEST_1 (3, "001", "001");
TEST_1 (3, "002", InvalidArgument);
TEST_1 (3, "010", "010");
TEST_1 (3, "011", "011");
TEST_1 (3, "012", InvalidArgument);
TEST_1 (3, "100", "100");
TEST_1 (3, "101", "101");
TEST_1 (3, "102", InvalidArgument);
TEST_1 (3, "100", "100");
TEST_1 (3, "101", "101");
TEST_1 (3, "102", InvalidArgument);
TEST_1 (3, "0001", "000");
TEST_1 (3, "0010", "001");
TEST_1 (3, "0100", "010");
TEST_1 (3, "1000", "100");
TEST_1 (3, "1001", "100");
TEST_1 (3, "0001", "000");
TEST_1 (3, "0010", "001");
TEST_1 (3, "0100", "010");
TEST_1 (3, "1000", "100");
TEST_1 (3, "1001", "100");
TEST_1 (3, "1002", InvalidArgument);
TEST_1 (3, "2000", InvalidArgument);
TEST_1 (3, "10010", "100");
TEST_1 (3, "10011", "100");
TEST_1 (3, "10012", InvalidArgument);
TEST_1 (3, "100102", InvalidArgument);
// macro to insert N zeros or ones in between two string literals
#define FILL(pfx, bit, N, sfx) fillstr (pfx, bit, N, sfx).c_str ()
CTOR_INFO (33);
// +------------- preceded by these characters
// | +--------- binary digit (0 or 1)
// | | +------ repeated this many times
// | | | +-- followed by these characters
// | | | |
// v v v v
TEST_1 (33, "", FILL ("", 0, 33, ""));
TEST_1 (33, "0", FILL ("", 0, 33, ""));
TEST_1 (33, "1", FILL ("", 0, 32, "1"));
TEST_1 (33, "00", FILL ("", 0, 31, "00"));
TEST_1 (33, "01", FILL ("", 0, 31, "01"));
TEST_1 (33, "10", FILL ("", 0, 31, "10"));
TEST_1 (33, "11", FILL ("", 0, 31, "11"));
TEST_1 (33, "100", FILL ("", 0, 30, "100"));
TEST_1 (33, "101", FILL ("", 0, 30, "101"));
TEST_1 (33, FILL ("1", 0, 32, ""), FILL ("10", 0, 30, "0"));
TEST_1 (33, FILL ("1", 0, 31, "1"), FILL ("10", 0, 30, "1"));
TEST_1 (33, FILL ("1", 0, 31, "2"), InvalidArgument);
TEST_1 (33, FILL ("", 1, 33, ""), FILL ("", 1, 33, ""));
TEST_1 (33, FILL ("", 1, 32, "0"), FILL ("", 1, 32, "0"));
TEST_1 (33, FILL ("", 1, 31, "00"), FILL ("", 1, 31, "00"));
TEST_1 (33, FILL ("", 1, 30, "000"), FILL ("", 1, 30, "000"));
TEST_1 (33, FILL ("", 1, 29, "0000"), FILL ("", 1, 29, "0000"));
TEST_1 (33, FILL ("", 1, 28, "00000"), FILL ("", 1, 28, "00000"));
TEST_1 (33, FILL ("", 1, 28, "00001"), FILL ("", 1, 28, "00001"));
TEST_1 (33, FILL ("", 1, 28, "00010"), FILL ("", 1, 28, "00010"));
TEST_1 (33, FILL ("", 1, 28, "00100"), FILL ("", 1, 28, "00100"));
TEST_1 (33, FILL ("", 1, 28, "01000"), FILL ("", 1, 28, "01000"));
TEST_1 (33, FILL ("", 1, 28, "02000"), InvalidArgument);
TEST_1 (33, FILL ("", 1, 33, "0"), FILL ("", 1, 33, ""));
TEST_1 (33, FILL ("", 1, 33, "1"), FILL ("", 1, 33, ""));
TEST_1 (33, FILL ("", 1, 33, "2"), InvalidArgument);
TEST_1 (33, FILL ("2", 1, 33, ""), InvalidArgument);
CTOR_INFO (80);
TEST_1 (80, FILL ("" , 1, 80, ""), FILL ("" , 1, 80, ""));
TEST_1 (80, FILL ("1", 0, 78, "1"), FILL ("1" , 0, 78, "1"));
TEST_1 (80, FILL ("1", 0, 77, "10"), FILL ("1" , 0, 77, "10"));
TEST_1 (80, FILL ("1", 0, 77, "20"), InvalidArgument);
TEST_1 (80, FILL ("2", 0, 77, "00"), InvalidArgument);
TEST_1 (80, FILL ("02", 0, 76, "00"), InvalidArgument);
TEST_1 (80, FILL ("12", 0, 76, "00"), InvalidArgument);
//////////////////////////////////////////////////////////////////
#undef CTOR_INFO
#define CTOR_INFO(N) \
rw_info (0, 0, __LINE__, "std::bitset<%i>::bitset(const " \
"%{?}std::basic_string<%s>&%{:}%3$s%{;}, size_t)", \
N, 0 != p, cname)
#define TEST_2(N, str, pos, except) DO_TEST(N, str, pos, -1, except)
CTOR_INFO (0);
TEST_2 (0, "", 0, "");
TEST_2 (0, "", 1, OutOfRange);
TEST_2 (0, "0", 0, "");
TEST_2 (0, "1", 0, "");
TEST_2 (0, "2", 0, InvalidArgument);
TEST_2 (0, "0", 1, "");
TEST_2 (0, "1", 1, "");
TEST_2 (0, "2", 1, "");
CTOR_INFO (1);
TEST_2 (1, "", 0, "0");
TEST_2 (1, "0", 0, "0");
TEST_2 (1, "1", 0, "1");
TEST_2 (1, "2", 0, InvalidArgument);
TEST_2 (1, "00", 0, "0");
TEST_2 (1, "01", 0, "0");
TEST_2 (1, "02", 0, InvalidArgument);
TEST_2 (1, "10", 0, "1");
TEST_2 (1, "11", 0, "1");
TEST_2 (1, "12", 0, InvalidArgument);
TEST_2 (1, "00", 1, "0");
TEST_2 (1, "01", 1, "1");
TEST_2 (1, "02", 1, InvalidArgument);
TEST_2 (1, "10", 1, "0");
TEST_2 (1, "11", 1, "1");
TEST_2 (1, "12", 1, InvalidArgument);
TEST_2 (1, "20", 1, "0");
TEST_2 (1, "21", 1, "1");
TEST_2 (1, "22", 1, InvalidArgument);
TEST_2 (1, "000", 1, "0");
TEST_2 (1, "001", 1, "0");
TEST_2 (1, "002", 1, InvalidArgument);
TEST_2 (1, "010", 1, "1");
TEST_2 (1, "011", 1, "1");
TEST_2 (1, "012", 1, InvalidArgument);
TEST_2 (1, "020", 1, InvalidArgument);
TEST_2 (1, "021", 1, InvalidArgument);
TEST_2 (1, "022", 1, InvalidArgument);
TEST_2 (1, "120", 1, InvalidArgument);
TEST_2 (1, "121", 1, InvalidArgument);
TEST_2 (1, "122", 1, InvalidArgument);
TEST_2 (1, "200", 1, "0");
TEST_2 (1, "201", 1, "0");
TEST_2 (1, "202", 1, InvalidArgument);
TEST_2 (1, "320", 2, "0");
TEST_2 (1, "321", 2, "1");
TEST_2 (1, "322", 2, InvalidArgument);
TEST_2 (1, "3200", 2, "0");
TEST_2 (1, "3201", 2, "0");
TEST_2 (1, "3202", 2, InvalidArgument);
TEST_2 (1, "3210", 2, "1");
TEST_2 (1, "3211", 2, "1");
TEST_2 (1, "3212", 2, InvalidArgument);
TEST_2 (1, "", 1, OutOfRange);
//////////////////////////////////////////////////////////////////
#undef CTOR_INFO
#define CTOR_INFO(N) \
rw_info (0, 0, __LINE__, "std::bitset<%i>::bitset(const " \
"%{?}std::basic_string<%s>&%{:}%3$s%{;}, size_t, size_t)", \
N, 0 != p, cname)
CTOR_INFO (0);
#define TEST_3(N, str, pos, n, except) DO_TEST(N, str, pos, n, except)
// +-------------------- bitset size
// | +----------------- string argument
// | | +---------- pos
// | | | +------ n
// | | | | +--- result or exception
// | | | | |
// v v v v v
TEST_3 (0, "", 0, 0, "");
TEST_3 (0, "", 1, 0, OutOfRange);
TEST_3 (0, "02", 0, 0, "");
CTOR_INFO (1);
TEST_3 (1, "012", 0, 1, "0");
TEST_3 (1, "012", 1, 1, "1");
TEST_3 (1, "012", 2, 1, InvalidArgument);
TEST_3 (1, "", 0, 0, "0");
TEST_3 (1, "", 1, 0, OutOfRange);
CTOR_INFO (8);
TEST_3 (8, "11111111", 0, 8, FILL ("", 1, 8, ""));
TEST_3 (8, "11111111", 1, 7, FILL ("0", 1, 7, ""));
TEST_3 (8, "11111111", 2, 6, FILL ("00", 1, 6, ""));
TEST_3 (8, "11111111", 3, 5, FILL ("000", 1, 5, ""));
TEST_3 (8, "11111111", 4, 4, FILL ("0000", 1, 4, ""));
TEST_3 (8, "11111111", 5, 3, FILL ("00000", 1, 3, ""));
TEST_3 (8, "11111111", 6, 2, FILL ("000000", 1, 2, ""));
TEST_3 (8, "11111111", 7, 1, FILL ("0000000", 1, 1, ""));
TEST_3 (8, "11111111", 8, 0, FILL ("00000000", 1, 0, ""));
TEST_3 (8, "11111111", 9, 0, OutOfRange);
TEST_3 (8, "11111111", 9, 1, OutOfRange);
TEST_3 (8, "111111112", 7, 1, FILL ("0000000", 1, 1, ""));
TEST_3 (8, "111111112", 7, 2, InvalidArgument);
TEST_3 (8, "211111112", 1, 7, FILL ("0", 1, 7, ""));
TEST_3 (8, "210111112", 1, 7, FILL ("010", 1, 5, ""));
TEST_3 (8, "211111012", 1, 7, FILL ("0", 1, 5, "01"));
CTOR_INFO (40);
TEST_3 (40, FILL ("", 0, 40, ""), 0, 0, FILL ("", 0, 40, ""));
TEST_3 (40, FILL ("", 0, 40, "1"), 0, 40, FILL ("", 0, 40, ""));
TEST_3 (40, FILL ("", 0, 40, "1"), 0, 41, FILL ("", 0, 40, ""));
TEST_3 (40, FILL ("", 0, 39, "1"), 0, 39, FILL ("", 0, 40, ""));
TEST_3 (40, FILL ("", 0, 39, "1"), 0, 40, FILL ("", 0, 39, "1"));
TEST_3 (40, FILL ("1", 0, 40, "1"), 0, 0, FILL ("", 0, 40, ""));
TEST_3 (40, FILL ("1", 0, 38, "1"), 0, 40, FILL ("1", 0, 38, "1"));
TEST_3 (40, FILL ("1", 0, 38, "1"), 0, 40, FILL ("1", 0, 38, "1"));
TEST_3 (40, FILL ("2", 0, 40, "2"), 1, 40, FILL ("", 0, 40, ""));
}
/**************************************************************************/
template <std::size_t N>
void test_ctors (std::bitset<N>* pb)
{
test_default_ctor (pb);
test_long_ctor (pb);
}
/**************************************************************************/
template <class Traits>
void test_ctors (const Traits*, const char *cname)
{
typedef typename Traits::char_type char_type;
typedef std::allocator<char_type> Allocator;
typedef std::basic_string<char_type, Traits, Allocator> String;
// exercise const std::string& overloads
test_string_ctor ((String*)1, cname);
#if !defined (_RWSTD_NO_EXT_BITSET_CTOR_CHAR_ARRAY) \
&& !defined (_RWSTD_NO_EXT_BITSET_CTOR_STRING)
// exercise const char* and const wchar_t* extensions
// but avoid calling the bitset(const UserChar*) overload in order
if (sizeof (char_type) != sizeof (UserChar))
test_string_ctor ((String*)0, cname);
#endif // _RWSTD_NO_EXT_BITSET_CTOR_{CHAR_ARRAY,STRING}
}
/**************************************************************************/
static int
run_test (int, char**)
{
#ifdef _RWSTD_NO_EXCEPTIONS
opt_no_exceptions = 1;
#endif // _RWSTD_NO_EXCEPTIONS
if (opt_no_exceptions)
rw_note (0, 0, 0, "exception tests disabled");
#undef DO_TEST
#define DO_TEST(N) test_ctors ((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 can't compile bitset<257>!
DO_TEST ( 257); // interesting case
#endif
DO_TEST ( 258); // interesting case
DO_TEST ( 333);
if (0 <= opt_char) {
typedef std::char_traits<char> NarrowTraits;
test_ctors ((NarrowTraits*)0, "char");
}
else {
rw_note (0, 0, __LINE__, "tests of char specialization disabled");
}
#ifndef _RWSTD_NO_WCHAR_T
if (0 <= opt_wchar) {
typedef std::char_traits<wchar_t> WideTraits;
test_ctors ((WideTraits*)0, "wchar_t");
}
else {
rw_note (0, 0, __LINE__, "tests of wchar_t specialization disabled");
}
#endif // _RWSTD_NO_WCHAR_T
if (0 <= opt_userchar) {
test_ctors ((UserTraits<UserChar>*)0, "UserChar");
}
else {
rw_note (0, 0, __LINE__, "tests of UserChar specialization disabled");
}
return 0;
}
/**************************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"lib.bitset.cons",
0 /* no comment */,
run_test,
"|-char~ "
"|-wchar_t~ "
"|-UserChar~ "
"|-no-exceptions# ",
&opt_char,
&opt_wchar,
&opt_userchar,
&opt_no_exceptions,
(void*)0 /* sentinel */);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,369 @@
/***************************************************************************
*
* 23.deque.iterators.cpp - test exercising lib.deque.iterators
*
* $Id: 23.deque.iterators.cpp 550991 2007-06-26 23:58:07Z sebor $
*
***************************************************************************
*
* 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 1994-2006 Rogue Wave Software.
*
**************************************************************************/
#include <cstddef> // for size_t
#include <deque> // for deque
#include <driver.h> // for rw_test()
#include <alg_test.h>
#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
// disabled for compilers that can't reliably replace the operators
// replace operators new and delete with versions that invalidate
// storage to detect problems due to deque iterators accessing
// uninitialized pointers
# include <rw_new.h>
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
/**************************************************************************/
std::size_t new_capacity;
typedef std::deque<int> IntDeque;
namespace __rw {
_RWSTD_SPECIALIZED_FUNCTION
inline IntDeque::size_type
__rw_new_capacity<IntDeque>(IntDeque::size_type n, const IntDeque*)
{
if (n) {
// non-zero size argument indicates a request for an increase
// in the capacity of a deque object's dynamically sizable
// vector of nodes
return n * 2;
}
// zero size argument is a request for the initial size of a deque
// object's dynamically sizable vector of nodes or for the size of
// the objects's fixed-size buffer for elements
return new_capacity;
}
}
/**************************************************************************/
template <class T>
void test_iterators (std::size_t N, int dir, T*)
{
typedef std::deque<T> Deque;
typedef typename Deque::difference_type Difference;
typedef typename Deque::size_type Size;
typedef typename Deque::value_type Value;
typedef typename Deque::iterator Iterator;
typedef typename Deque::const_iterator ConstIterator;
Deque d;
// fill `d' with the range of values [1, N)
if (dir < 0) {
for (std::size_t i = 0; i != N; ++i)
d.push_front (Value (N - i));
}
else if (dir > 0) {
for (std::size_t i = 0; i != N; ++i)
d.push_back (Value (i + 1));
}
else {
d = Deque (Size (N), Value ());
for (std::size_t i = 0; i != N; ++i)
d [i] = Value (i + 1);
}
const Iterator begin = d.begin ();
const Iterator end = d.end ();
Iterator i0 = begin;
Iterator i1 = end;
// convert N to Difference to avoid any potential issues
// due to integer promotion in expressions below (e.g.,
// on LP64)
const Difference N_diff = Difference (N);
for (std::size_t i = 0; i != N; ++i, ++i0, --i1) {
// convert i to Difference for the same reason as N above
const Difference i_diff = Difference (i);
// exercise iterator::operator*()
// and iterator::operator[](difference_type)
rw_assert (Value (i + 1) == *i0, 0, __LINE__,
"Expected iterator::operator*() value to be %d; got %d.",
Value (i + 1), *i0);
rw_assert (Value (N - i) == i0 [N_diff - 2 * i_diff - 1], 0, __LINE__,
"Expected value of iterator::operator[](%d) to be %d; "
"got %d.", N_diff - 2 * i_diff - 1, Value (N - i),
i0 [N_diff - 2 * i_diff - 1]);
rw_assert (Value (N - i) == i1 [Difference (-1)], 0, __LINE__,
"Expected value of iterator::operator[](%d) to be %d; "
"got %d.", Difference (-1), Value (N - i),
i1 [Difference (-1)]);
rw_assert (Value (i + 1) == i1 [2 * i_diff - N_diff], 0, __LINE__,
"Expected value of iterator::operator[](%d) to be %d; "
"got %d.", 2 * i_diff - N_diff, Value (i + 1),
i1 [2 * i_diff - N_diff]);
// exercise operator-(deque::iterator, deque::iterator)
Difference d0_begin = i0 - begin;
Difference d1_begin = i1 - begin;
Difference d0_end = end - i0;
Difference d1_end = end - i1;
rw_assert (d0_begin == Difference (i), 0, __LINE__,
"Expected value of operator-(deque::iterator, "
"deque::iterator) to be %d; got %d.",
Difference (i), d0_begin);
rw_assert (d1_begin == N_diff - i_diff, 0, __LINE__,
"Expected value of operator-(deque::iterator, "
"deque::iterator) to be %d; got %d.",
N_diff - i_diff, d1_begin);
rw_assert (d0_end == N_diff - i_diff, 0, __LINE__,
"Expected value of operator-(deque::iterator, "
"deque::iterator) to be %d; got %d.",
N_diff - i_diff, d0_end);
rw_assert (d1_end == i_diff, 0, __LINE__,
"Expected value of operator-(deque::iterator, "
"deque::iterator) to be %d; got %d.",
i_diff, d1_end);
// exercise operator+(deque::iterator, deque::difference_type),
// operator-(deque::iterator, deque::difference_type),
// operator==(deque::iterator, deque::iterator), and
// operator< (deque::iterator, deque::iterator)
const Iterator i_begin = begin + i_diff;
const Iterator i_end = end - (N_diff - i_diff);
rw_assert (i_begin == i0, 0, __LINE__,
"Expected operator==(deque::iterator, "
"deque::iterator) to evaluate true.");
rw_assert (i_end == i0, 0, __LINE__,
"Expected operator==(deque::iterator, "
"deque::iterator) to evaluate true.");
rw_assert (!(i_begin < i0), 0, __LINE__,
"Expected operator<(deque::iterator, "
"deque::iterator) to evaluate true.");
rw_assert (!(i_end < i0), 0, __LINE__,
"Expected operator<(deque::iterator, "
"deque::iterator) to evaluate true.");
d0_begin = i_begin - begin;
d0_end = end - i_end;
rw_assert (d0_begin == i_diff, 0, __LINE__,
"Expected operator==(deque::iterator, "
"deque::iterator) to evaluate true.");
rw_assert (d0_end == N_diff - i_diff, 0, __LINE__,
"Expected operator==(deque::iterator, "
"deque::iterator) to evaluate true.");
// exercise iterator::operator++() and iterator::operator--()
Iterator i2 = i0;
Iterator i3 = i0;
if (i && i < N - 1) {
++i2;
rw_assert (i2 == i0 + 1, 0, __LINE__,
"Expected ++iterator(it) == it + 1.");
rw_assert (i0 < i2, 0, __LINE__,
"Expected it < ++iterator(it).");
rw_assert (!(i2 < i0), 0, __LINE__,
"Expected !(++iterator (it) < it) to yield true.");
rw_assert (i2 - i0 == Difference (+1), 0, __LINE__,
"Expected ++iterator(it) - it == 1.");
rw_assert (i0 - i2 == Difference (-1), 0, __LINE__,
"Expected it - (++iterator(it)) == -1");
i2 -= 1;
rw_assert (i2 - i0 == 0, 0, __LINE__,
"Expected (++iterator(it) - 1) - it == 0.");
rw_assert (i0 - i2 == 0, 0, __LINE__,
"Expected it - (++iterator(it) - 1) == 0.");
i3 -= 1;
rw_assert (i3 == i0 - 1, 0, __LINE__,
"Expected --iterator (it) == it - 1.");
rw_assert (i3 < i0, 0, __LINE__,
"Expected --iterator (it) < it.");
rw_assert (!(i0 < i3), 0, __LINE__,
"Expected !(it < --iterator (it)) to yield true.");
rw_assert (i3 - i0 == Difference (-1), 0, __LINE__,
"Expected (--iterator(it) - it) == -1.");
rw_assert (i0 - i3 == Difference (+1), 0, __LINE__,
"Expected (it - (--iterator(it))) == 1.");
++i3;
rw_assert (i3 - i0 == 0, 0, __LINE__,
"Expected --iterator (it) + 1 - it == 0.");
rw_assert (i0 - i3 == 0, 0, __LINE__,
"Expected it - (--iterator (it) + 1) == 0.");
}
rw_assert (i2 == i0, 0, __LINE__,
"Expected iterators to be equal.");
rw_assert (i3 == i0, 0, __LINE__,
"Expected iterators to be equal.");
rw_assert (i2 == i3, 0, __LINE__,
"Expected iterators to be equal.");
rw_assert (!(i2 < i0), 0, __LINE__,
"Expected iterators to be equal.");
rw_assert (!(i3 < i0), 0, __LINE__,
"Expected iterators to be equal.");
rw_assert (!(i2 < i3), 0, __LINE__,
"Expected iterators to be equal.");
}
}
/**************************************************************************/
#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
// replacement operator new is expensive, avoid long runtimes
unsigned rw_opt_nloops = 6; // for --nloops
#else
unsigned rw_opt_nloops = 10; // for --nloops
#endif
int rw_opt_no_fill; // for --no-fill
int rw_opt_no_push_back; // for --no-push_back
int rw_opt_no_push_front; // for --no-push_front
template <class T>
void test_iterators (std::size_t N, T*)
{
// avoid repeatedly noting that test has been disabled
static int push_back_noted;
static int push_front_noted;
static int fill_noted;
// fill deque by repeatedly calling either push_front() or push_back()
if (rw_opt_no_push_back)
rw_note (push_back_noted++, 0, 0, "push_back test disabled");
else
test_iterators (N, -1, (T*)0);
if (rw_opt_no_fill)
rw_note (fill_noted++, 0, 0, "fill test disabled");
else
test_iterators (N, 0, (T*)0);
if (rw_opt_no_push_front)
rw_note (push_front_noted++, 0, 0, "push_front test disabled");
else
test_iterators (N, 1, (T*)0);
}
/**************************************************************************/
int run_test (int, char**)
{
#ifdef _RWSTD_NO_DEBUG_ITER
// verify the size of deque<int>::iterator (space optimization
// available only when debugging iterators are not enabled)
const std::size_t itsize = sizeof (IntDeque::iterator);
rw_assert (itsize == 2 * sizeof (IntDeque::pointer), 0, __LINE__,
"sizeof(deque<int>::iterator) == %zu, got %zu "
"[space optimization]",
2 * sizeof (IntDeque::pointer), itsize);
#endif // _RWSTD_NO_DEBUG_ITER
// capacity must be at least 2
for (std::size_t i = 2; i < rw_opt_nloops; ++i) {
// set the result of __rw::__rw_new_capacity() to override
// the container's allocation policy and force an early
// reallocation
new_capacity = i;
const IntDeque::size_type cap =
__rw::__rw_new_capacity (IntDeque::size_type (),
(const IntDeque*)0);
rw_info (0, 0, 0,
"__rw::__rw_new_capacity(std::deque<int>::"
"size_type, std::deque<int>*) = %zu", cap);
const std::size_t max_size = i * i * 10;
for (std::size_t j = 0; j != max_size; ++j) {
if (j % (max_size / 10) == 0)
rw_info (0, 0, 0, "std::deque<int>(%u, ...)", j);
test_iterators (j, (int*)0);
}
}
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.deque.iterators",
0 /* no comment */,
run_test,
"|-nloops#2 " // argument must be greater than 1
"|-no-push_back# "
"|-no-push_front# "
"|-no-fill#",
&rw_opt_nloops,
&rw_opt_no_push_back,
&rw_opt_no_push_front,
&rw_opt_no_fill);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
/***************************************************************************
*
* 23.deque.special.cpp - test exercising [lib.deque.special]
*
* $Id: 23.deque.special.cpp 510071 2007-02-21 15:58:53Z 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 1994-2006 Rogue Wave Software.
*
**************************************************************************/
#include <deque> // for deque
#include <cstddef> // for size_t
#include <rw_value.h> // for UserClass
#include <driver.h> // for rw_test(), ...
/**************************************************************************/
struct DequeValueType { };
typedef std::allocator<DequeValueType> DequeAllocator;
typedef std::deque<DequeValueType, DequeAllocator> DequeType;
int deque_swap_called;
_RWSTD_NAMESPACE (std) {
// define an explicit specialization of the deque::swap() member
// to verify tha the non-member swap function calls the member
_RWSTD_SPECIALIZED_FUNCTION
void DequeType::swap (DequeType&)
{
++deque_swap_called;
}
} // namespace std
/**************************************************************************/
void test_std_swap ()
{
rw_info (0, 0, 0,
"Testing std::swap (std::deque&, std::deque&) "
"calls std::deque::swap");
// verify the signature of the function specialization
void (*pswap)(DequeType&, DequeType&) =
&std::swap<DequeValueType, DequeAllocator>;
_RWSTD_UNUSED (pswap);
// verify that std::swap() calls std::deque::swap()
DequeType d;
std::swap (d, d);
rw_assert (1 == deque_swap_called, 0, __LINE__,
"std::swap (std::deque<T, A>&, std::deque<T, A>&) called "
"std::deque<T, A>::swap (std::deque<T, A>&) exactly once; "
"got %d times", deque_swap_called);
}
/**************************************************************************/
typedef std::deque<UserClass, std::allocator<UserClass> > Deque;
Deque::size_type new_capacity;
namespace __rw {
_RWSTD_SPECIALIZED_FUNCTION
inline Deque::size_type
__rw_new_capacity<Deque>(Deque::size_type n, const Deque*)
{
if (n) {
// non-zero size argument indicates a request for an increase
// in the capacity of a deque object's dynamically sizable
// vector of nodes
return n * 2;
}
// zero size argument is a request for the initial size of a deque
// object's dynamically sizable vector of nodes or for the size of
// the objects's fixed-size buffer for elements
return new_capacity;
}
}
/**************************************************************************/
template <class T, class Allocator>
void test_swap (const T *lhs_seq, std::size_t lhs_seq_len,
const T *rhs_seq, std::size_t rhs_seq_len,
std::deque<T, Allocator>*,
const char *tname)
{
typedef std::deque<T, Allocator> Deque;
typedef typename Deque::iterator Iterator;
typedef typename Deque::size_type SizeType;
// create two containers from the provided sequences
Deque lhs (lhs_seq, lhs_seq + lhs_seq_len);
Deque rhs (rhs_seq, rhs_seq + rhs_seq_len);
// save the begin and and iterators and the size
// of each container before swapping the objects
const Iterator lhs_begin_0 = lhs.begin ();
const Iterator lhs_end_0 = lhs.end ();
const SizeType lhs_size_0 = lhs.size ();
const Iterator rhs_begin_0 = rhs.begin ();
const Iterator rhs_end_0 = rhs.end ();
const SizeType rhs_size_0 = rhs.size ();
// swap the two containers
lhs.swap (rhs);
// compute the begin and and iterators and the size
// of each container after swapping the objects
const Iterator lhs_begin_1 = lhs.begin ();
const Iterator lhs_end_1 = lhs.end ();
const SizeType lhs_size_1 = lhs.size ();
const Iterator rhs_begin_1 = rhs.begin ();
const Iterator rhs_end_1 = rhs.end ();
const SizeType rhs_size_1 = rhs.size ();
// verify that the iterators and sizes
// of the two objects were swapped
rw_assert (lhs_begin_0 == rhs_begin_1 && lhs_begin_1 == rhs_begin_0,
0, __LINE__,
"begin() not swapped for \"%{X=*.*}\" and \"%{X=*.*}\"",
int (lhs_seq_len), -1, lhs_seq,
int (rhs_seq_len), -1, rhs_seq);
rw_assert (lhs_end_0 == rhs_end_1 && lhs_end_1 == rhs_end_0,
0, __LINE__,
"end() not swapped for \"%{X=*.*}\" and \"%{X=*.*}\"",
int (lhs_seq_len), -1, lhs_seq,
int (rhs_seq_len), -1, rhs_seq);
rw_assert (lhs_size_0 == rhs_size_1 && lhs_size_1 == rhs_size_0,
0, __LINE__,
"size() not swapped for \"%{X=*.*}\" and \"%{X=*.*}\"",
int (lhs_seq_len), -1, lhs_seq,
int (rhs_seq_len), -1, rhs_seq);
// swap one of the containers with an empty unnamed temporary
// container and verify that the object is empty
{ Deque ().swap (lhs); }
const Iterator lhs_begin_2 = lhs.begin ();
const Iterator lhs_end_2 = lhs.end ();
const SizeType lhs_size_2 = lhs.size ();
rw_assert (lhs_begin_2 == lhs_end_2, 0, __LINE__,
"deque<%s>().begin() not swapped for \"%{X=*.*}\"",
tname, int (rhs_seq_len), -1, rhs_seq);
rw_assert (0 == lhs_size_2, 0, __LINE__,
"deque<%s>().size() not swapped for \"%{X=*.*}\"",
tname, int (rhs_seq_len), -1, rhs_seq);
}
template <class T>
void test_swap (const T*, const char* tname)
{
rw_info (0, 0, 0,
"std::deque<%s>::swap(deque<%1$s>&)", tname);
typedef std::deque<T, std::allocator<T> > MyDeque;
typedef typename MyDeque::iterator Iterator;
// create two empty deque objects
MyDeque empty [2];
// save their begin and end iterators before calling swap
const Iterator before [2][2] = {
{ empty [0].begin (), empty [0].end () },
{ empty [1].begin (), empty [1].end () }
};
// swap the two containers
empty [0].swap (empty [1]);
// get the new begin and end iterators
const Iterator after [2][2] = {
{ empty [0].begin (), empty [0].end () },
{ empty [1].begin (), empty [1].end () }
};
// verify that the iterators have not been invalidated
rw_assert ( before [0][0] == after [1][0]
&& before [1][0] == after [0][0], 0, __LINE__,
"deque<%s>().begin() not swapped", tname);
rw_assert ( before [0][1] == after [1][1]
&& before [1][1] == after [0][1], 0, __LINE__,
"deque<%s>().end() not swapped", tname);
// static to zero-initialize if T is a POD type
static T seq [32];
const std::size_t seq_len = sizeof seq / sizeof *seq;
for (std::size_t i = 0; i != seq_len; ++i) {
for (std::size_t j = 0; j != seq_len; ++j) {
test_swap (seq, i, seq, j, (MyDeque*)0, tname);
}
}
}
/**************************************************************************/
void test_swap ()
{
test_swap ((int*)0, "int");
test_swap ((UserClass*)0, "UserClass");
}
/**************************************************************************/
int run_test (int, char**)
{
// Test std::swap calling std::deque::swap
test_std_swap ();
static const Deque::size_type caps[] = {
2, 3, 4, 5, 16, 32
};
for (std::size_t i = 0; i != sizeof caps / sizeof *caps; ++i) {
new_capacity = caps [i];
rw_info (0, 0, 0,
"__rw::__rw_new_capacity<std::deque<UserClass> >(0) = %u",
_RW::__rw_new_capacity (0, (Deque*)0));
test_swap ();
}
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.deque.special",
0 /* no comment */,
run_test,
0 /* co command line options */);
}

View File

@@ -0,0 +1,556 @@
/***************************************************************************
*
* 23.list.assign.cpp - test exercising [lib.list.assign]
*
* $Id: 23.list.assign.cpp 580483 2007-09-28 20:55:52Z sebor $
*
***************************************************************************
*
* 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.
*
**************************************************************************/
#include <list> // for list
#include <cstddef> // for size_t
#include <23.list.h> // for ListMembers
#include <alg_test.h> // for InputIter
#include <driver.h> // for rw_test()
#include <rw_allocator.h> // for UserAlloc
#include <rw_new.h> // for bad_alloc, replacement operator new
/**************************************************************************/
// for convenience and brevity
#define Assign(sig) ListIds::assign_ ## sig
static const char* const exceptions[] = {
"unknown exception", "bad_alloc", "exception"
};
/**************************************************************************/
// used to exercise:
// assign (InputIterator, InputIterator)
static const ContainerTestCase
range_test_cases [] = {
#undef TEST
#define TEST(lst, arg, off, size, res, bthrow) { \
__LINE__, -1, -1, off, size, -1, \
lst, sizeof lst - 1, \
arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
}
// +------------------------------------------ controlled sequence
// | +------------------------- sequence to be inserted
// | | +------------ assign() pos argument
// | | | +--------- assign() n argument
// | | | | +------ expected result sequence
// | | | | | +--- exception info
// | | | | | | 0 - no exception
// | | | | | | 1 - out_of_range
// | | | | | | 2 - length_error
// | | | | | | -1 - exc. safety
// | | | | | |
// | | | | | +--------------------+
// | | | | +------+ |
// | | | +------+ | |
// | | +---+ | | |
// | | | | | |
// | | | | | |
// V V V V V V
TEST ("ab", "c", 0, 1, "c", 0),
TEST ("", "", 0, 0, "", 0),
TEST ("", "abc", 1, 1, "b", 0),
TEST ("", "<U0>", 0, 1, "<U0>", 0),
TEST ("<U0>", "", 0, 0, "", 0),
TEST ("abc", "", 0, 0, "", 0),
TEST ("<U0>", "a", 0, 1, "a", 0),
TEST ("<U0>", "<U0>@2", 1, 1, "<U0>", 0),
TEST ("<U0>", "<U0>@2", 0, 2, "<U0>@2", 0),
TEST ("<U0>", "<U0>@2", 1, 5, "<U0>", 0),
TEST ("cde", "ab", 0, 2, "ab", 0),
TEST ("cde", "ab", 0, 1, "a", 0),
TEST ("cde", "ab", 1, 5, "b", 0),
TEST ("ab", "c<U0>e", 0, 3, "c<U0>e", 0),
TEST ("ab", "c<U0>e", 1, 2, "<U0>e", 0),
TEST ("ab", "c<U0>e", 0, 2, "c<U0>", 0),
TEST ("<U0>e<U0>", "<U0>ab<U0>@2c", 0, 9, "<U0>ab<U0>@2c", 0),
TEST ("<U0>e<U0>", "<U0>ab<U0>@2c", 0, 3, "<U0>ab", 0),
TEST ("a<U0>b<U0>@2c", "<U0>e<U0>", 0, 3, "<U0>e<U0>", 0),
TEST ("a<U0>b<U0>@2c", "<U0>@2e<U0>", 0, 2, "<U0>@2", 0),
TEST ("<U0>ab<U0>@2c", "<U0>e<U0>", 2, 1, "<U0>", 0),
TEST ("<U0>ab<U0>@2c", "<U0>e<U0>", 2, 9, "<U0>", 0),
TEST ("a<U0>bc<U0>@2", "<U0>e", 0, 2, "<U0>e", 0),
TEST ("x@4096", "", 0, 0, "", 0),
TEST ("", "x@4096", 9, 2, "xx", 0),
TEST ("", "x@4096", 9, 0, "", 0),
TEST ("abc", "x@4096", 2, 1, "x", 0),
TEST ("x@4096", "x@4096", 2, 3, "xxx", 0),
TEST ("", "x@4096", 0, 4096, "x@4096", 0),
TEST ("", "x@4096", 100, 2000, "x@2000", 0),
TEST ("", "x@207", 0, 207, "x@207", 0),
TEST ("x@128", "x@334", 10, 207, "x@207", 0),
TEST ("x@540", "x@207", 50, 128, "x@128", 0),
TEST ("", "x@1412", 128, 873, "x@873", 0),
TEST ("x@128", "x@1412", 0, 1412, "x@1412", 0),
TEST ("x@3695", "x@1412", 207, 540, "x@540", 0),
TEST ("x@872", "x@874", 1, 873, "x@873", 0),
TEST ("x@873", "x@3695", 10, 2284, "x@2284", 0),
TEST ("", "<U0>", 2, 0, "", 1),
TEST ("", "a", 2, 0, "", 1),
TEST ("", "x@4096", 4106, 0, "", 1),
TEST ("last", "test", 0, 4, "test", 0)
};
/**************************************************************************/
// used to exercise:
// assign (size_type, const value_type&)
static const ContainerTestCase
size_cref_test_cases [] = {
#undef TEST
#define TEST(lst, size, val, res, bthrow) { \
__LINE__, -1, size, -1, -1, val, \
lst, sizeof lst - 1, \
0, 0, res, sizeof res - 1, bthrow \
}
// +----------------------------------------- controlled sequence
// | +------------------------ assign() count argument
// | | +-------------------- character to be assigned
// | | | +---------------- expected result sequence
// | | | | +-------- exception info
// | | | | | 0 - no exception
// | | | | | 1 - out_of_range
// | | | | | 2 - length_error
// | | | | | -1 - exc. safety
// | | | | |
// | | | | +--------+
// V V V V V
TEST ("ab", 1, 'c', "c", 0),
TEST ("", 0, ' ', "", 0),
TEST ("", 1, 'b', "b", 0),
TEST ("", 3, 'b', "bbb", 0),
TEST ("<U0>", 0, ' ', "", 0),
TEST ("", 2, '\0', "<U0>@2", 0),
TEST ("<U0>", 1, 'a', "a", 0),
TEST ("<U0>", 1, '\0', "<U0>", 0),
TEST ("<U0>", 2, '\0', "<U0>@2", 0),
TEST ("<U0>", 0, '\0', "", 0),
TEST ("cde", 3, 'a', "aaa", 0),
TEST ("ab", 2, '\0', "<U0>@2", 0),
TEST ("ab", 1, '\0', "<U0>", 0),
TEST ("a<U0>b<U0>@2c", 2, '\0', "<U0>@2", 0),
TEST ("a<U0>b<U0>@2c", 1, '\0', "<U0>", 0),
TEST ("<U0>ab<U0>@2c", 3, '\0', "<U0>@3", 0),
TEST ("a<U0>bc<U0>@2", 2, 'a', "aa", 0),
TEST ("", 4096, 'x', "x@4096", 0),
TEST ("x@4096", 0, 'x', "", 0),
TEST ("x@127", 128, 'x', "x@128", 0),
TEST ("x@200", 207, 'x', "x@207", 0),
TEST ("x@334", 128, 'x', "x@128", 0),
TEST ("", 540, 'x', "x@540", 0),
TEST ("xx", 873, 'x', "x@873", 0),
TEST ("x@873", 1412, 'x', "x@1412", 0),
TEST ("x@3695", 207, 'x', "x@207", 0),
TEST ("x@540", 3695, 'x', "x@3695", 0),
TEST ("last", 4, 't', "tttt", 0)
};
/**************************************************************************/
template <class InputIterator, class Distance>
inline void
_rw_advance (InputIterator& it, Distance dist) {
while (0 < dist) {
--dist;
++it;
}
}
// invokes specializations of the member function template
// on the required iterator categories
template <class List, class Iterator>
struct AssignRange: ContRangeBase<List> {
typedef typename List::iterator ListIter;
typedef typename List::value_type ListVal;
AssignRange () { }
virtual List&
operator() (List &lst,
const ContainerTestCaseData<ListVal>& tdata) const {
const ListVal* const beg = tdata.arg_ + tdata.off2_;
const ListVal* const end = beg + tdata.ext2_;
const Iterator first (beg, beg, end);
const Iterator last (end, beg, end);
lst.assign (first, last);
return lst;
}
};
/**************************************************************************/
// invokes possible overloads of the member function template
// on common RandomAccessIterator types
template <class List, class Iterator>
struct AssignRangeOverload: ContRangeBase<List>
{
typedef typename List::iterator ListIter;
typedef typename List::value_type ListVal;
AssignRangeOverload () { }
virtual List&
operator() (List &lst,
const ContainerTestCaseData<ListVal>& tdata) const {
const bool reverse_iter =
ListIds::ReverseIterator == tdata.func_.iter_id_
|| ListIds::ConstReverseIterator == tdata.func_.iter_id_;
const std::size_t off = tdata.arglen_ - tdata.off2_ - tdata.ext2_;
List str_arg (tdata.arg_, tdata.arg_ + tdata.arglen_);
Iterator first (this->begin (str_arg, (Iterator*)0));
_rw_advance (first, reverse_iter ? off : tdata.off2_);
Iterator last (first);
_rw_advance (last, tdata.ext2_);
lst.assign (first, last);
return lst;
}
};
/**************************************************************************/
// invokes specializations of the member function template
// on the required iterator categories
template <class List, class Iterator>
struct AssignRangePtrOverload: ContRangeBase<List> {
typedef typename List::value_type ListVal;
AssignRangePtrOverload () { }
virtual List&
operator() (List& lst,
const ContainerTestCaseData<ListVal>& tdata) const {
const ListVal* const beg = tdata.arg_ + tdata.off2_;
const ListVal* const end = beg + tdata.ext2_;
const Iterator first = _RWSTD_CONST_CAST (Iterator, beg);
const Iterator last = _RWSTD_CONST_CAST (Iterator, end);
lst.assign (first, last);
return lst;
}
};
/**************************************************************************/
template <class T, class Allocator>
void test_assign (T*, Allocator*,
const ContRangeBase< std::list <T, Allocator> > &rng,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list <T, Allocator> List;
typedef typename List::iterator ListIter;
typedef typename List::const_iterator ListCIter;
typedef ListState<List> ListState;
const ContainerFunc &func = tdata.func_;
const ContainerTestCase &tcase = tdata.tcase_;
// construct the list object to be modified
List lst (tdata.str_, tdata.str_ + tdata.strlen_);
std::size_t size = tcase.size >= 0 ? tcase.size : 0;
rwt_free_store* const pst = rwt_get_free_store (0);
SharedAlloc* const pal = SharedAlloc::instance ();
// iterate for`throw_after' starting at the next call to operator new,
// forcing each call to throw an exception, until the function finally
// succeeds (i.e, no exception is thrown)
std::size_t throw_count;
for (throw_count = 0; ; ++throw_count) {
// (name of) expected and caught exception
const char* expected = 0;
const char* caught = 0;
#ifndef _RWSTD_NO_EXCEPTIONS
if (0 == tcase.bthrow) {
// by default exercise the exception safety of the function
// by iteratively inducing an exception at each call to operator
// new or Allocator::allocate() until the call succeeds
expected = exceptions [1]; // bad_alloc
*pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
pal->throw_at_calls_ [pal->m_allocate] =
pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
}
else {
// exceptions disabled for this test case
}
#else // if defined (_RWSTD_NO_EXCEPTIONS)
if (tcase.bthrow)
return;
#endif // _RWSTD_NO_EXCEPTIONS
// start checking for memory leaks
rw_check_leaks (lst.get_allocator ());
try {
switch (func.which_) {
case Assign (size_cref): {
const T val = T::from_char (char (tcase.val));
lst.assign (size, val);
break;
}
case Assign (range):
rng (lst, tdata);
break;
default:
RW_ASSERT (!"test logic error: unknown assign overload");
}
// for convenience
static const int cwidth = sizeof (T);
const std::size_t got_size = lst.size ();
char* const got = new char [got_size + 1];
std::size_t index = 0;
for (ListCIter it = lst.begin (),
end = lst.end (); it != end; ++it) {
got [index++] = char (it->data_.val_);
}
got [got_size] = '\0';
// verify that list length are equal to the expected
rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
"line %d. %{$FUNCALL}: expected \"%{X=*}\" with length "
"%zu, got %{/*.*Gs} with length %zu", __LINE__,
cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_,
1, int (got_size), got, got_size);
if (tdata.reslen_ == got_size) {
// if the result length matches the expected length
// (and only then), also verify that the modified
// list matches the expected result
const std::size_t match =
rw_match (tcase.res, got, got_size);
rw_assert (match == tdata.reslen_, 0, tcase.line,
"line %d. %{$FUNCALL}: expected \"%{X=*}\", "
"got %{/*.*Gs}, difference at off %zu",
__LINE__, cwidth, int (tdata.reslen_), tdata.res_,
1, int (got_size), got, match);
}
delete [] got;
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::bad_alloc &ex) {
caught = exceptions [1];
rw_assert (0 == tcase.bthrow, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (const std::exception &ex) {
caught = exceptions [2];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (...) {
caught = exceptions [0];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught %s",
__LINE__, 0 != expected, expected, caught);
}
#endif // _RWSTD_NO_EXCEPTIONS
// FIXME: verify the number of blocks the function call
// is expected to allocate and detect any memory leaks
rw_check_leaks (lst.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
if (caught) {
if (0 == tcase.bthrow && caught == exceptions [1]) {
// allow this call to operator new to succeed and try
// to make the next one to fail during the next call
// to the same function again
continue;
}
}
else if (0 < tcase.bthrow) {
rw_assert (caught == expected, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s, caught %s"
"%{:}unexpectedly caught %s%{;}",
__LINE__, 0 != expected, expected, caught, caught);
}
break;
}
// disable bad_alloc exceptions
*pst->throw_at_calls_ [0] = 0;
pal->throw_at_calls_ [pal->m_allocate] = 0;
}
/**************************************************************************/
template <class T, class Allocator>
void test_assign (T*, Allocator*,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list<T, Allocator> List;
if (tdata.func_.which_ == Assign (range)) {
switch (tdata.func_.iter_id_) {
// exercise possible overloads of the member function template
// on common RandomAccessIterator types
#undef TEST
#define TEST(Iterator) do { \
typedef typename List::Iterator Iter; \
static const \
AssignRangePtrOverload<List, Iter> rng; \
test_assign ((T*)0, (Allocator*)0, rng, tdata); \
} while (0)
case ListIds::Pointer: TEST (pointer); break;
case ListIds::ConstPointer: TEST (const_pointer); break;
#undef TEST
#define TEST(Iterator) do { \
typedef typename List::Iterator Iter; \
static const \
AssignRangeOverload<List, Iter> rng; \
test_assign ((T*)0, (Allocator*)0, rng, tdata); \
} while (0)
case ListIds::Iterator: TEST (iterator); break;
case ListIds::ConstIterator: TEST (const_iterator); break;
case ListIds::ReverseIterator: TEST (reverse_iterator); break;
case ListIds::ConstReverseIterator: TEST (const_reverse_iterator);
break;
// exercise specializations of the member function template
// on the required iterator categories
#undef TEST
#define TEST(Iterator) do { \
typedef Iterator<T> Iter; \
static const \
AssignRange<List, Iter> rng; \
test_assign ((T*)0, (Allocator*)0, rng, tdata); \
} while (0)
case ListIds::Input: TEST (InputIter); break;
case ListIds::Forward: TEST (ConstFwdIter); break;
case ListIds::Bidir: TEST (ConstBidirIter); break;
case ListIds::Random: TEST (ConstRandomAccessIter); break;
default:
rw_error (0, 0, __LINE__, "bad iterator id");
}
}
else {
// exercise ordinary overloads of the member function
static const ContRangeBase<List> rng;
test_assign ((T*)0, (Allocator*)0, rng, tdata);
}
}
/**************************************************************************/
DEFINE_CONTAINER_TEST_FUNCTIONS (test_assign);
int main (int argc, char** argv)
{
static const ContainerTest
tests [] = {
#undef TEST
#define TEST(sig) { \
Assign (sig), sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (size_cref),
TEST (range)
};
const std::size_t test_count = sizeof tests / sizeof *tests;
const int status =
rw_run_cont_test (argc, argv, __FILE__,
"lib.list.assign",
ContainerIds::List,
test_assign_func_array, tests, test_count);
return status;
}

View File

@@ -0,0 +1,625 @@
/***************************************************************************
*
* 23.list.capacity.cpp - test exercising [lib.list.capacity]
*
* $Id: 23.list.capacity.cpp 523692 2007-03-29 13:01:55Z 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.
*
**************************************************************************/
#include <list> // for list
#include <cstddef> // for size_t
#include <stdexcept> // for exception
#include <23.list.h> // for ListMembers
#include <driver.h> // for rw_test()
#include <rw_allocator.h> // for UserAlloc
#include <rw_char.h> // for rw_expand()
#include <rw_new.h> // for bad_alloc, replacement operator new
/**************************************************************************/
// for convenience and brevity
#define Size(sig) ListIds::size_ ## sig
#define MaxSize(sig) ListIds::max_size_ ## sig
#define Resize(sig) ListIds::resize_ ## sig
#define Clear(sig) ListIds::clear_ ## sig
#define Empty(sig) ListIds::empty_ ## sig
static const char* const exceptions[] = {
"unknown exception", "bad_alloc", "exception"
};
/**************************************************************************/
// used to exercise
// size ()
static const ContainerTestCase
size_void_test_cases [] = {
#undef TEST
#define TEST(str, res) { \
__LINE__, -1, -1, -1, -1, -1, \
str, sizeof str - 1, 0, 0, \
0, res, -1 \
}
// +--------------------------------------- controlled sequence
// | +------------------ expected result
// | |
// | |
// V V
TEST (0, 0),
TEST ("", 0),
TEST ("<U0>", 1),
TEST ("a", 1),
TEST (" ", 1),
TEST ("ab", 2),
TEST ("bc", 2),
TEST ("test string", 11),
TEST ("Test String", 11),
TEST ("t<U0> s", 4),
TEST ("Test<U0>string", 11),
TEST ("<U0>a<U0>b", 4),
TEST ("a<U0>@2b", 4),
TEST ("a<U0>@3b", 5),
TEST ("a<U0>@2b<U0>", 5),
TEST ("a<U0>b<U0>@2c", 6),
TEST ("a<U0>b<U0>c<U0>@2", 7),
TEST ("x@128", 128),
TEST ("x@207", 207),
TEST ("x@334", 334),
TEST ("x@540", 540),
TEST ("x@873", 873),
TEST ("x@1412", 1412),
TEST ("x@2284", 2284),
TEST ("x@3695", 3695),
TEST ("x@4096", 4096),
TEST ("last", 4)
};
/**************************************************************************/
// used to exercise
// max_size ()
static const ContainerTestCase
max_size_void_test_cases [] = {
#undef TEST
#define TEST(str) { \
__LINE__, -1, -1, -1, -1, -1, \
str, sizeof str - 1, 0, 0, \
0, 0, -1 \
}
// +------------------------------ controlled sequence
// |
// |
// |
// V
TEST (0),
TEST (""),
TEST ("<U0>"),
TEST ("a"),
TEST ("test string"),
TEST ("a<U0>b<U0>c<U0>@2"),
TEST ("x@128"),
TEST ("x@207"),
TEST ("x@2284"),
TEST ("x@3695"),
TEST ("last")
};
/**************************************************************************/
// used to exercise
// resize (size_type, value_type)
static const ContainerTestCase
resize_size_val_test_cases [] = {
#undef TEST
#define TEST(str, size, val, res, bthrow) { \
__LINE__, -1, size, -1, -1, val, \
str, sizeof str - 1, 0, 0, \
res, sizeof res - 1, bthrow \
}
// +------------------------------------------ controlled sequence
// | +------------------- new size
// | | +------------- value_type argument
// | | | +-------- expected result sequence
// | | | | +- exception info
// | | | | | 0 - no exception
// | | | | | 1 - length_error
// | | | | |
// | | | | +-----------+
// V V V V V
TEST ("", 0, 'a', "", 0),
TEST ("", 5, '\0', "<U0>@3<U0>@2", 0),
TEST ("", 334, 'x', "x@334", 0),
TEST ("<U0>", 0, 'a', "", 0),
TEST ("<U0>", 2, 'a', "<U0>a", 0),
TEST ("<U0>", 1, 'a', "<U0>", 0),
TEST ("<U0>", 128, 'a', "<U0>a@127", 0),
TEST ("a", 0, 'a', "", 0),
TEST ("a", 2, '\0', "a<U0>", 0),
TEST ("a", 540, 'a', "a@540", 0),
TEST ("a<U0>@3b", 10, 'a', "a<U0>@3baaaaa", 0),
TEST ("ab<U0>@3", 10, 'a', "ab<U0>@3aaaaa", 0),
TEST ("<U0>@3ab", 10, 'a', "<U0>@3abaaaaa", 0),
TEST ("a<U0>@3b", 7, '\0', "a<U0>@3b<U0>@2", 0),
TEST ("ab<U0>@3", 7, '\0', "ab<U0>@3<U0>@2", 0),
TEST ("<U0>@3ba", 7, '\0', "<U0>@3ba<U0>@2", 0),
TEST ("a<U0>b<U0>c<U0>@2", 6, 'a', "a<U0>b<U0>c<U0>", 0),
TEST ("a<U0>b<U0>c<U0>@2", 5, '\0', "a<U0>b<U0>c", 0),
TEST ("<U0>ba<U0>c<U0>@2", 1, '\0', "<U0>", 0),
TEST ("<U0>ba<U0>c<U0>@2", 0, '\0', "", 0),
TEST ("x@540", 127, 'a', "x@127", 0),
TEST ("x@873", 127, 'a', "x@127", 0),
TEST ("x@1412", 127, 'a', "x@127", 0),
TEST ("x@2284", 127, 'a', "x@127", 0),
TEST ("x@127", 128, 'a', "x@127a", 0),
TEST ("x@128", 207, 'a', "x@128a@79", 0),
TEST ("x@207", 334, 'a', "x@207a@127", 0),
TEST ("x@334", 540, 'a', "x@334a@206", 0),
TEST ("x@540", 873, 'a', "x@540a@333", 0),
TEST ("x@873", 1412, 'a', "x@873a@539", 0),
TEST ("x@1412", 2284, 'a', "x@1412a@872", 0),
TEST ("x@2284", 3695, 'a', "x@2284a@1411", 0),
TEST ("last", 4, 't', "last", 0)
};
/**************************************************************************/
// used to exercise
// resize (size_type)
static const ContainerTestCase
resize_size_test_cases [] = {
#undef TEST
#define TEST(str, size, res, bthrow) { \
__LINE__, -1, size, -1, -1, -1, \
str, sizeof str - 1, 0, 0, \
res, sizeof res - 1, bthrow \
}
// +------------------------------------------ controlled sequence
// | +------------------- new size
// | | +-------------- expected result sequence
// | | | +-- exception info
// | | | | 0 - no exception
// | | | | 1 - length_error
// | | | |
// V V V V
TEST ("", 0, "", 0),
TEST ("", 5, "\0@5", 0),
TEST ("", 334, "\0@334", 0),
TEST ("<U0>", 0, "", 0),
TEST ("<U0>", 2, "\0@2", 0),
TEST ("<U0>", 1, "\0", 0),
TEST ("<U0>", 127, "\0@127", 0),
TEST ("a", 0, "", 0),
TEST ("a", 2, "a\0", 0),
TEST ("a", 539, "a\0@538", 0),
TEST ("a<U0>@3b", 10, "a<U0>@3b\0@5", 0),
TEST ("ab<U0>@3", 10, "ab<U0>@3\0@5", 0),
TEST ("<U0>@3ab", 10, "<U0>@3ab\0@5", 0),
TEST ("a<U0>@3b", 7, "a<U0>@3b\0@2", 0),
TEST ("ab<U0>@3", 7, "ab<U0>@3\0@2", 0),
TEST ("<U0>@3ba", 7, "<U0>@3ba\0@2", 0),
TEST ("a<U0>b<U0>c<U0>@2", 5, "a<U0>b<U0>c", 0),
TEST ("a<U0>b<U0>c<U0>@2", 4, "a<U0>b<U0>", 0),
TEST ("<U0>ba<U0>c<U0>@2", 1, "<U0>", 0),
TEST ("<U0>ba<U0>c<U0>@2", 0, "", 0),
TEST ("x@540", 127, "x@127", 0),
TEST ("x@873", 127, "x@127", 0),
TEST ("x@1412", 127, "x@127", 0),
TEST ("x@2284", 127, "x@127", 0),
TEST ("x@127", 128, "x@127\0", 0),
TEST ("x@128", 207, "x@128\0@79", 0),
TEST ("x@207", 334, "x@207\0@127", 0),
TEST ("x@334", 540, "x@334\0@206", 0),
TEST ("x@540", 873, "x@540\0@333", 0),
TEST ("x@873", 1412, "x@873\0@539", 0),
TEST ("x@1412", 2284, "x@1412\0@872", 0),
TEST ("x@2284", 3695, "x@2284\0@1411", 0),
TEST ("last", 4, "last", 0)
};
/**************************************************************************/
// used to exercise
// clear ()
static const ContainerTestCase
clear_void_test_cases [] = {
#undef TEST
#define TEST(str) { \
__LINE__, -1, -1, -1, -1, -1, \
str, sizeof str - 1, 0, 0, \
"", 0, -1 \
}
// +------------------------------ controlled sequence
// |
// |
// |
// V
TEST (0),
TEST (""),
TEST ("<U0>"),
TEST ("a"),
TEST ("test string"),
TEST ("a<U0>b<U0>c<U0>@2"),
TEST ("x@128"),
TEST ("x@207"),
TEST ("x@334"),
TEST ("x@540"),
TEST ("x@873"),
TEST ("x@1412"),
TEST ("x@2284"),
TEST ("x@3695"),
TEST ("x@4096"),
TEST ("last")
};
/**************************************************************************/
// used to exercise
// empty ()
static const ContainerTestCase
empty_void_test_cases [] = {
#undef TEST
#define TEST(str, res) { \
__LINE__, -1, -1, -1, -1, -1, \
str, sizeof str - 1, 0, 0, \
0, res, -1 \
}
// +------------------------------ controlled sequence
// | +--------------- expected result
// | |
// | |
// V V
TEST (0, 1),
TEST ("", 1),
TEST ("<U0>", 0),
TEST ("a", 0),
TEST ("<U0>ab<U0>c", 0),
TEST ("x@128", 0),
TEST ("x@3695", 0),
TEST ("last", 0)
};
/**************************************************************************/
template <class T, class Allocator>
void test_capacity (T*, Allocator*,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list<T, Allocator> List;
typedef typename List::iterator ListIter;
typedef typename List::const_iterator ListCIter;
typedef ListState<List> ListState;
const ContainerFunc &func = tdata.func_;
const ContainerTestCase &tcase = tdata.tcase_;
// construct the list object to be modified and constant one
List lst (tdata.str_, tdata.str_ + tdata.strlen_, Allocator ());
const List clst (tdata.str_, tdata.str_ + tdata.strlen_, Allocator ());
// save the state of the list object before the call
// to detect exception safety violations (changes to
// the state of the object after an exception)
const ListState lst_state (lst);
const T arg_val = T::from_char (-1 != tcase.val ? char (tcase.val) : char ());
rwt_free_store* const pst = rwt_get_free_store (0);
SharedAlloc* const pal = SharedAlloc::instance ();
// iterate for`throw_after' starting at the next call to operator new,
// forcing each call to throw an exception, until the function finally
// succeeds (i.e, no exception is thrown)
std::size_t throw_count;
for (throw_count = 0; ; ++throw_count) {
// (name of) expected and caught exception
const char* expected = 0;
const char* caught = 0;
#ifndef _RWSTD_NO_EXCEPTIONS
if (0 == tcase.bthrow) {
// by default exercise the exception safety of the function
// by iteratively inducing an exception at each call to operator
// new or Allocator::allocate() until the call succeeds
expected = exceptions [1]; // bad_alloc
*pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
pal->throw_at_calls_ [pal->m_allocate] =
pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
}
else {
// exceptions disabled for this test case
}
#else // if defined (_RWSTD_NO_EXCEPTIONS)
if (tcase.bthrow) {
return;
}
#endif // _RWSTD_NO_EXCEPTIONS
const bool is_class = ListIds::UserClass == func.elem_id_;
const std::size_t x_count_save = UserClass::count_;
// start checking for memory leaks
rw_check_leaks (lst.get_allocator ());
std::size_t res = 0;
try {
// reset function call counters
if (is_class)
UserClass::reset_totals ();
switch (func.which_) {
case Size (void):
res = clst.size ();
break;
case MaxSize (void):
res = clst.max_size ();
break;
case Resize (size_val):
lst.resize (tcase.size, arg_val);
break;
case Resize (size):
lst.resize (tcase.size);
break;
case Clear (void):
lst.clear ();
break;
case Empty (void):
res = clst.empty () ? 1 : 0;
break;
default:
RW_ASSERT (!"test logic error: unknown capacity overload");
}
if (is_class
&&
(func.which_ == ListIds::clear_void
|| func.which_ == ListIds::resize_size
|| func.which_ == ListIds::resize_size_val)) {
std::size_t nctors = tdata.reslen_ > tdata.strlen_ ?
tdata.reslen_ - tdata.strlen_ : 0;
std::size_t ndtors = tdata.reslen_ < tdata.strlen_ ?
tdata.strlen_ - tdata.reslen_ : 0;
std::size_t new_count = x_count_save + nctors - ndtors;
std::size_t ndefctors = 0;
if (func.which_ == ListIds::resize_size_val)
++nctors;
else if (func.which_ == ListIds::resize_size)
++ndefctors;
bool success = UserClass::is_total (new_count, ndefctors,
nctors, 0, 0, 0);
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL} called default/copy ctor "
"and operator=() %zu, %zu, and %zu times, "
"respectively, %zu, %zu, 0 expected",
__LINE__,
UserClass::n_total_def_ctor_,
UserClass::n_total_copy_ctor_,
UserClass::n_total_op_assign_,
ndefctors, nctors);
}
// verify the returned value
if (func.which_ == ListIds::size_void
|| func.which_ == ListIds::empty_void) {
rw_assert (res == tcase.nres, 0, tcase.line,
"line %d. %{$FUNCALL} expected %zu, got %zu",
__LINE__, tcase.nres, res);
}
if (func.which_ == ListIds::max_size_void) {
std::size_t cur_sz = clst.size ();
rw_assert (cur_sz <= res, 0, tcase.line,
"line %d. %{$FUNCALL} == %zu, expected res > %zu",
__LINE__, res, cur_sz);
}
if (func.which_ == ListIds::resize_size_val
|| func.which_ == ListIds::resize_size
|| func.which_ == ListIds::clear_void) {
// for convenience
static const int cwidth = sizeof (T);
const std::size_t got_size = lst.size ();
char* const got = new char [got_size + 1];
std::size_t index = 0;
for (ListCIter it = lst.begin (),
end = lst.end (); it != end; ++it) {
got [index++] = char (it->data_.val_);
}
got [got_size] = '\0';
// verify that strings length are equal
rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
"line %d. %{$FUNCALL} expected \"%{X=*}\" "
"with length %zu, got %{/*.*Gs} with length %zu",
__LINE__, cwidth, int (tdata.reslen_),
tdata.res_, tdata.reslen_,
1, int (got_size), got, got_size);
if (tdata.reslen_ == got_size) {
// if the result length matches the expected length
// (and only then), also verify that the modified
// list matches the expected result
const std::size_t match = rw_match (tcase.res,
got, got_size);
rw_assert (match == tdata.reslen_, 0, tcase.line,
"line %d. %{$FUNCALL} expected \"%{X=*}\", "
"got %{/*.*Gs}, difference at offset %zu",
__LINE__,
cwidth, int (tdata.reslen_), tdata.res_,
1, int (got_size), got, match);
}
delete [] got;
}
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::bad_alloc &ex) {
caught = exceptions [1];
rw_assert (0 == tcase.bthrow, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (const std::exception &ex) {
caught = exceptions [2];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (...) {
caught = exceptions [0];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught %s",
__LINE__, 0 != expected, expected, caught);
}
#endif // _RWSTD_NO_EXCEPTIONS
// FIXME: verify the number of blocks the function call
// is expected to allocate and detect any memory leaks
rw_check_leaks (lst.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
if (caught) {
// verify that an exception thrown during allocation
// didn't cause a change in the state of the object
lst_state.assert_equal (ListState (lst),
__LINE__, tcase.line, caught);
if (0 == tcase.bthrow) {
// allow this call to operator new to succeed and try
// to make the next one to fail during the next call
// to the same function again
continue;
}
}
break;
}
// disable bad_alloc exceptions
*pst->throw_at_calls_ [0] = 0;
pal->throw_at_calls_ [pal->m_allocate] = 0;
}
/**************************************************************************/
DEFINE_CONTAINER_TEST_FUNCTIONS (test_capacity);
int main (int argc, char** argv)
{
static const ContainerTest
tests [] = {
#undef TEST
#define TEST(gsig, sig) { \
gsig, sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (ListIds::size_void, size_void),
TEST (ListIds::max_size_void, max_size_void),
TEST (ListIds::resize_size_val, resize_size_val),
TEST (ListIds::resize_size, resize_size),
TEST (ListIds::clear_void, clear_void),
TEST (ListIds::empty_void, empty_void)
};
const std::size_t test_count = sizeof tests / sizeof *tests;
return rw_run_cont_test (argc, argv, __FILE__,
"lib.list.capacity",
ContainerIds::List,
test_capacity_func_array, tests, test_count);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,492 @@
/***************************************************************************
*
* 23.list.erase.cpp - test exercising [lib.list::erase]
*
* $Id: 23.list.erase.cpp 523692 2007-03-29 13:01:55Z 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.
*
**************************************************************************/
#include <list> // for list
#include <cstddef> // for ptrdiff_t, size_t
#include <stdexcept> // for out_of_range
#include <23.list.h> // for ListMembers
#include <driver.h> // for rw_test()
#include <rw_allocator.h> // for UserAlloc
#include <rw_char.h> // for rw_expand()
#include <rw_new.h> // for bad_alloc, replacement operator new
/**************************************************************************/
// for convenience and brevity
#define Erase(sig) ListIds::erase_ ## sig
static const char* const exceptions[] = {
"unknown exception", "exception"
};
/**************************************************************************/
// used to exercise
// erase (iterator, iterator)
static const ContainerTestCase
iter_iter_test_cases [] = {
#undef TEST
#define TEST(str, off, size, res) { \
__LINE__, off, size, -1, -1, -1, str, sizeof str - 1, \
0, 0, res, sizeof res - 1, 0 }
// +----------------------------------------- controlled sequence
// | +--------------------- erase() pos argument
// | | +----------- erase() n argument
// | | | +------- expected result sequence
// | | | |
// | | | |
// | | | |
// | | | |
// | | | |
// V V V V
TEST ("", 0, 0, "" ),
TEST ("<U0>", 0, 1, "" ),
TEST ("<U0>", 0, 0, "<U0>" ),
TEST ("<U0>", 1, 1, "<U0>" ),
TEST ("<U0>@2", 1, 1, "<U0>" ),
TEST ("<U0>@2", 0, 1, "<U0>" ),
TEST ("a", 0, 1, "" ),
TEST ("a", 0, 0, "a" ),
TEST ("a", 1, 1, "a" ),
TEST ("abc", 0, 3, "" ),
TEST ("abc", 0, 2, "c" ),
TEST ("abc", 1, 2, "a" ),
TEST ("abc", 1, 1, "ac" ),
TEST ("abc", 2, 1, "ab" ),
TEST ("abc", 3, 0, "abc" ),
TEST ("t<U0> s", 0, 3, "s" ),
TEST ("t<U0> s", 0, 4, "" ),
TEST ("t<U0> s", 0, 1, "<U0> s" ),
TEST ("t<U0> s", 1, 3, "t" ),
TEST ("t<U0> s", 1, 2, "ts" ),
TEST ("t<U0> s", 2, 2, "t<U0>" ),
TEST ("t<U0> s", 2, 1, "t<U0>s" ),
TEST ("t<U0> s", 3, 2, "t<U0> " ),
TEST ("t<U0> s", 4, 0, "t<U0> s" ),
TEST ("a<U0>@3b", 2, 0, "a<U0>@3b" ),
TEST ("a<U0>@3b", 2, 3, "a<U0>" ),
TEST ("a<U0>@3b", 2, 2, "a<U0>b" ),
TEST ("a<U0>@3b", 1, 4, "a" ),
TEST ("a<U0>@3b", 0, 5, "" ),
TEST ("a<U0>@3b", 0, 2, "<U0>@2b" ),
TEST ("a<U0>b<U0>@2c", 0, 6, "" ),
TEST ("a<U0>b<U0>@2c", 4, 2, "a<U0>b<U0>" ),
TEST ("a<U0>b<U0>@2c", 4, 1, "a<U0>b<U0>c" ),
TEST ("<U0>ab<U0>@2c", 2, 5, "<U0>a" ),
TEST ("<U0>ab<U0>@2c", 0, 4, "<U0>c" ),
TEST ("ab<U0>c<U0>@2", 5, 1, "ab<U0>c<U0>" ),
TEST ("a", 0, 3, "" ),
TEST ("t<U0> s", 0, 9, "" ),
TEST ("ab<U0>c<U0>@2", 0, 10, "" ),
TEST ("x@4096", 0, 4105, "" ),
TEST ("a", 3, 1, "a" ),
TEST ("t<U0> s", 5, 1, "t<U0> s" ),
TEST ("ab<U0>c<U0>@2", 10, 1, "ab<U0>c<U0>@2" ),
TEST ("x@4096", 4106, 1, "x@4096" ),
TEST ("x@4096", 0, 4096, "" ),
TEST ("x@4096", 1, 4095, "x" ),
TEST ("x@4096", 4, 4092, "xxxx" ),
TEST ("x@4096", 4, 4090, "xxxxxx" ),
TEST ("x@4096", 4096, 4096, "x@4096" ),
TEST ("x@2048y@2048", 1, 4094, "xy" ),
TEST ("last test", 4, 1, "lasttest" )
};
/**************************************************************************/
// used to exercise
// erase (iterator)
static const ContainerTestCase
iter_test_cases [] = {
#undef TEST
#define TEST(str, off, res) { \
__LINE__, off, -1, -1, -1, -1, str, sizeof str - 1, \
0, 0, res, sizeof res - 1, 0 }
// +-------------------------------------- controlled sequence
// | +------------------ iterator offset
// | | +------------- expected result sequence
// | | |
// V V V
TEST ("a", 0, ""),
TEST ("<U0>", 0, ""),
TEST ("<U0>@2", 0, "<U0>"),
TEST ("<U0>@2", 1, "<U0>"),
TEST ("abc", 0, "bc"),
TEST ("abc", 1, "ac"),
TEST ("abc", 2, "ab"),
TEST ("t<U0> s", 0, "<U0> s"),
TEST ("t<U0> s", 1, "t s"),
TEST ("t<U0> s", 2, "t<U0>s"),
TEST ("t<U0> s", 3, "t<U0> "),
TEST ("a<U0>@3b", 4, "a<U0>@3"),
TEST ("a<U0>@3b", 2, "a<U0>@2b"),
TEST ("a<U0>@3b", 1, "a<U0>@2b"),
TEST ("a<U0>@3b", 0, "<U0>@3b"),
TEST ("a<U0>b<U0>@2c", 4, "a<U0>b<U0>c"),
TEST ("<U0>ab<U0>@2c", 0, "ab<U0>@2c"),
TEST ("<U0>ab<U0>@2c", 2, "<U0>a<U0>@2c"),
TEST ("ab<U0>c<U0>@2", 5, "ab<U0>c<U0>"),
TEST ("x@4096y", 4096, "x@4096"),
TEST ("x@4096", 4088, "x@4095"),
TEST ("ax@4096", 0, "x@4096"),
TEST ("x@4096", 9, "x@4095"),
TEST ("last test", 4, "lasttest")
};
/**************************************************************************/
// used to exercise
// pop_front ()
static const ContainerTestCase
pop_front_test_cases [] = {
#undef TEST
#define TEST(str, res) { \
__LINE__, -1, -1, -1, -1, -1, str, sizeof str - 1, \
0, 0, res, sizeof res - 1, 0 }
// +----------------------------------------- controlled sequence
// | +------------------------ expected result sequence
// | |
// | |
// | |
// | |
// | |
// V V
TEST ("<U0>", "" ),
TEST ("<U0>@2", "<U0>" ),
TEST ("a", "" ),
TEST ("abc", "bc" ),
TEST ("t<U0> s", "<U0> s" ),
TEST ("a<U0>@3b", "<U0>@3b" ),
TEST ("a<U0>b<U0>@2c", "<U0>b<U0>@2c" ),
TEST ("<U0>ab<U0>@2c", "ab<U0>@2c" ),
TEST ("ab<U0>c<U0>@2", "b<U0>c<U0>@2" ),
TEST ("x@4096", "x@4095" ),
TEST (" last test", "last test" )
};
/**************************************************************************/
// used to exercise
// pop_back ()
static const ContainerTestCase
pop_back_test_cases [] = {
#undef TEST
#define TEST(str, res) { \
__LINE__, -1, -1, -1, -1, -1, str, sizeof str - 1, \
0, 0, res, sizeof res - 1, 0 }
// +----------------------------------------- controlled sequence
// | +------------------------ expected result sequence
// | |
// | |
// | |
// | |
// | |
// V V
TEST ("<U0>", "" ),
TEST ("<U0>@2", "<U0>" ),
TEST ("a", "" ),
TEST ("abc", "ab" ),
TEST ("t<U0> s", "t<U0> " ),
TEST ("a<U0>@3b", "a<U0>@3" ),
TEST ("a<U0>b<U0>@2c", "a<U0>b<U0>@2" ),
TEST ("<U0>ab<U0>@2c", "<U0>ab<U0>@2" ),
TEST ("ab<U0>c<U0>@2", "ab<U0>c<U0>" ),
TEST ("x@4096", "x@4095" ),
TEST ("last test ", "last test" )
};
/**************************************************************************/
template <class InputIterator, class Distance>
inline void
_rw_advance (InputIterator& it, Distance dist) {
while (0 < dist) {
--dist;
++it;
}
}
template<class InputIterator>
inline std::size_t
_rw_distance(InputIterator first, InputIterator last)
{
std::size_t dist = 0;
for (; first != last; ++first)
++dist;
return dist;
}
template <class T, class Allocator>
void test_erase (T*, Allocator*,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list <T, Allocator> List;
typedef typename List::iterator ListIter;
typedef typename List::const_iterator ListCIter;
typedef ListState<List> ListState;
const ContainerFunc &func = tdata.func_;
const ContainerTestCase &tcase = tdata.tcase_;
// construct the list object to be modified
List lst (tdata.str_, tdata.str_ + tdata.strlen_);
// compute the offset and the extent (the number of elements)
// of the first range into the list object being modified
const std::size_t size1 = tdata.strlen_;
const std::size_t off1 =
std::size_t (tcase.off) < size1 ? std::size_t (tcase.off) : size1;
const std::size_t ext1 =
off1 + tcase.size < size1 ? tcase.size : size1 - off1;
// create a pair of iterators into the list object being modified
ListIter it_first (lst.begin ());
_rw_advance (it_first, off1);
#ifndef _RWSTD_NO_EXCEPTIONS
// is some exception expected ?
const char* expected = 0;
const char* caught = 0;
#else // if defined (_RWSTD_NO_EXCEPTIONS)
if (tcase.bthrow)
return;
#endif // _RWSTD_NO_EXCEPTIONS
// start checking for memory leaks
rwt_check_leaks (0, 0);
ListIter res_iter;
const bool is_class = ListIds::UserClass == func.elem_id_;
const std::size_t x_count_save = UserClass::count_;
try {
// reset function call counters
if (is_class)
UserClass::reset_totals ();
std::size_t delcnt = 0;
switch (func.which_) {
case Erase (iter):
res_iter = lst.erase (it_first);
delcnt = 1;
break;
case Erase (iter_iter): {
ListIter it_last (it_first);
_rw_advance (it_last, ext1);
res_iter = lst.erase (it_first, it_last);
delcnt = ext1;
break;
}
case ListIds::pop_front_void:
lst.pop_front ();
delcnt = 1;
break;
case ListIds::pop_back_void:
lst.pop_back ();
delcnt = 1;
break;
default:
RW_ASSERT (!"test logic error: unknown erase overload");
return;
}
if (is_class) {
// verify that the erase method calls only dtor
// of UserClass and only the given number of times each
bool success = UserClass::is_total (x_count_save - delcnt,
0, 0, 0, 0, 0)
&& UserClass::n_total_dtor_ == delcnt;
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL} called default/copy ctor, "
"operator=() and dtor %zu, %zu, %zu, and %zu times, "
"respectively, 0, 0, 0, %zu expected",
__LINE__,
UserClass::n_total_def_ctor_,
UserClass::n_total_copy_ctor_,
UserClass::n_total_op_assign_,
UserClass::n_total_dtor_, delcnt);
}
if (ListIds::pop_front_void != func.which_
&& ListIds::pop_back_void != func.which_) {
// verify the returned value
std::size_t dist = _rw_distance (lst.begin (), res_iter);
rw_assert (dist <= lst.size(), 0, tcase.line,
"line %d. %{$FUNCALL} returned invalid iterator, "
"difference with begin is %zu",
__LINE__, dist);
if (std::size_t (tcase.off) >= tdata.reslen_) {
rw_assert (res_iter == lst.end (), 0, tcase.line,
"line %d. %{$FUNCALL} != end()", __LINE__);
}
else {
bool success =
tdata.res_ [tcase.off].data_.val_ == res_iter->data_.val_;
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL} == %{#c}, got %{#c}",
__LINE__, char (tdata.res_ [tcase.off].data_.val_),
char (res_iter->data_.val_));
}
}
// for convenience
static const int cwidth = sizeof (T);
const std::size_t got_size = lst.size ();
char* const got = new char [got_size + 1];
std::size_t index = 0;
for (ListCIter it = lst.begin (),
end = lst.end (); it != end; ++it) {
got [index++] = char (it->data_.val_);
}
got [got_size] = '\0';
// verify that strings length are equal
rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
"line %d. %{$FUNCALL} expected \"%{X=*}\" with length "
"%zu, got %{/*.*Gs} with length %zu",
__LINE__, cwidth, int (tdata.reslen_), tdata.res_,
tdata.reslen_, 1, int (got_size), got, got_size);
if (tdata.reslen_ == got_size) {
// if the result length matches the expected length
// (and only then), also verify that the modified
// list matches the expected result
const T* pmatch = T::mismatch (tdata.res_, got, got_size);
rw_assert (0 == pmatch, 0, tcase.line,
"line %d. %{$FUNCALL} expected \"%{X=*}\", "
"got %{/*.*Gs}, difference at offset %zu",
__LINE__, cwidth, int (tdata.reslen_), tdata.res_,
1, int (got_size), got, pmatch - tdata.res_);
}
delete [] got;
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::exception &ex) {
caught = exceptions [1];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (...) {
caught = exceptions [0];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught %s",
__LINE__, 0 != expected, expected, caught);
}
#endif // _RWSTD_NO_EXCEPTIONS
// FIXME: verify the number of blocks the function call
// is expected to allocate and detect any memory leaks
rw_check_leaks (lst.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
}
/**************************************************************************/
DEFINE_CONTAINER_TEST_FUNCTIONS (test_erase);
int main (int argc, char** argv)
{
static const ContainerTest
tests [] = {
#undef TEST
#define TEST(sig) { \
Erase (sig), sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (iter),
TEST (iter_iter),
#undef TEST
#define TEST(sig) { \
ListIds::sig ## _void, sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (pop_front),
TEST (pop_back)
};
const std::size_t test_count = sizeof tests / sizeof *tests;
return rw_run_cont_test (argc, argv, __FILE__,
"lib.list.erase",
ContainerIds::List,
test_erase_func_array, tests, test_count);
}

View File

@@ -0,0 +1,831 @@
/***************************************************************************
*
* 23.list.insert.cpp - test exercising [lib.list.insert]
*
* $Id: 23.list.insert.cpp 580483 2007-09-28 20:55:52Z sebor $
*
***************************************************************************
*
* 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.
*
**************************************************************************/
#include <list> // for list
#include <stdexcept> // for out_of_range, length_error
#include <cstddef> // for size_t
#include <23.list.h> // for ListMembers
#include <alg_test.h> // for InputIter
#include <driver.h> // for rw_test()
#include <rw_allocator.h> // for UserAlloc
#include <rw_new.h> // for bad_alloc, replacement operator new
/**************************************************************************/
// for convenience and brevity
#define Insert(sig) ListIds::insert_ ## sig
static const char* const exceptions[] = {
"unknown exception", "bad_alloc", "exception"
};
/**************************************************************************/
// exercises
// insert (iterator, InputIterator, InputIterator)
static const ContainerTestCase
iter_range_test_cases [] = {
#undef TEST
#define TEST(lst, off, arg, off2, size2, res, bthrow) { \
__LINE__, off, -1, off2, size2, -1, lst, sizeof lst - 1, \
arg, sizeof arg - 1, res, sizeof res - 1, bthrow \
}
// +----------------------------------------- controlled sequence
// | +------------------------ insert() pos argument
// | | +--------------------- sequence to be inserted
// | | | +-------- insert() off2 argument
// | | | | +----- insert() num argument
// | | | | | +-- expected result sequence
// | | | | | | +--- exception info
// | | | | | | | 0 - no exception
// | | | | | | | 1 - out_of_range
// | | | | | | | 2 - length_error
// | | | | | | | -1 - exc. safety
// | | | | | | |
// | | | | | | +----------------+
// V V V V V V V
TEST ("ab", 0, "c", 0, 1, "cab", 0),
TEST ("", 0, "", 0, 0, "", 0),
TEST ("", 0, "abc", 1, 1, "b", 0),
TEST ("", 0, "<U0>", 0, 1, "<U0>", 0),
TEST ("<U0>", 0, "", 0, 0, "<U0>", 0),
TEST ("<U0>", 1, "", 0, 0, "<U0>", 0),
TEST ("abc", 0, "", 0, 0, "abc", 0),
TEST ("abc", 1, "", 0, 0, "abc", 0),
TEST ("abc", 3, "", 0, 0, "abc", 0),
TEST ("<U0>", 0, "a", 0, 1, "a<U0>", 0),
TEST ("<U0>", 1, "a", 0, 1, "<U0>a", 0),
TEST ("<U0>", 0, "<U0>@2", 1, 1, "<U0>@2", 0),
TEST ("<U0>", 1, "<U0>@2", 0, 2, "<U0>@3", 0),
TEST ("cde", 0, "ab", 0, 2, "abcde", 0),
TEST ("cde", 1, "ab", 0, 1, "cade", 0),
TEST ("cde", 3, "ab", 1, 1, "cdeb", 0),
TEST ("ab", 0, "c<U0>e", 0, 3, "c<U0>eab", 0),
TEST ("ab", 1, "c<U0>e", 1, 2, "a<U0>eb", 0),
TEST ("ab", 2, "c<U0>e", 0, 2, "abc<U0>", 0),
TEST ("<U0>e<U0>", 1, "<U0>ab<U0>@2c", 0, 6, "<U0>@2ab<U0>@2ce<U0>",0),
TEST ("<U0>e<U0>", 1, "<U0>ab<U0>@2c", 0, 3, "<U0>@2abe<U0>", 0),
TEST ("a<U0>b<U0>@2c", 3, "<U0>e<U0>", 0, 3, "a<U0>b<U0>e<U0>@3c", 0),
TEST ("a<U0>b<U0>@2c", 2, "<U0>@2e<U0>", 0, 2, "a<U0>@3b<U0>@2c", 0),
TEST ("<U0>ab<U0>@2c", 0, "<U0>e<U0>", 2, 1, "<U0>@2ab<U0>@2c", 0),
TEST ("a<U0>bc<U0>@2", 6, "<U0>e", 0, 2, "a<U0>bc<U0>@3e", 0),
TEST ("", 0, "x@4096", 0, 4096, "x@4096", 0),
TEST ("x@4096", 0, "", 0, 0, "x@4096", 0),
TEST ("a@1000", 0, "b@1000", 0, 999, "b@999a@1000", 0),
TEST ("a@1000", 1, "b@1001", 0, 1000, "ab@1000a@999", 0),
TEST ("a@1000", 2, "b@1002", 0, 1001, "aab@1001a@998", 0),
TEST ("a@1000", 998, "b@1000", 1, 999, "a@998b@999aa", 0),
TEST ("a@1000", 999, "b@1001", 2, 999, "a@999b@999a", 0),
TEST ("a@1000", 2, "b@1002", 999, 3, "aabbba@998", 0),
TEST ("x@10", 1, "x@118", 0, 118, "x@128", 0),
TEST ("x@128", 0, "x@129", 50, 79, "x@207", 0),
TEST ("x@207", 207, "x@127", 0, 127, "x@334", 0),
TEST ("x@207", 128, "x@207", 10, 127, "x@334", 0),
TEST ("x@334", 334, "x@208", 2, 206, "x@540", 0),
TEST ("x@540", 0, "x@336", 3, 333, "x@873", 0),
TEST ("x@539", 538, "x@873", 0, 873, "x@1412", 0),
TEST ("x@873", 540, "x@540", 1, 539, "x@1412", 0),
TEST ("x@872", 0, "x@1412", 0, 1412, "x@2284", 0),
TEST ("x@1411", 1411, "x@2288", 4, 2284, "x@3695", 0),
TEST ("x@1411", 872, "x@3695", 128, 2284, "x@3695", 0),
TEST ("x@1412", 0, "x@2284", 0, 2284, "x@3696", 0),
TEST ("<U0>", 2, "", 0, 0, "<U0>", 1),
TEST ("", 0, "<U0>", 2, 0, "", 2),
TEST ("a", 2, "", 0, 0, "a", 1),
TEST ("", 0, "a", 2, 0, "", 2),
TEST ("x@4096", 4106, "", 0, 0, "x@4096", 1),
TEST ("", 0, "x@4096", 4106, 0, "", 2),
TEST ("last", 4, "test", 0, 4, "lasttest", 0)
};
/**************************************************************************/
// exercises
// insert (iterator, size_type, const value_type&)
static const ContainerTestCase
iter_size_cref_test_cases [] = {
#undef TEST
#define TEST(lst, off, size, val, res, bthrow) { \
__LINE__, off, size, -1, -1, val, lst, sizeof lst - 1, \
0, 0, res, sizeof res - 1, bthrow \
}
// +---------------------------------------- controlled sequence
// | +----------------------- insert() pos argument
// | | +-------------------- insert() size argument
// | | | +------------- character to be inserted
// | | | | +--------- expected result sequence
// | | | | | +- exception info
// | | | | | | 0 - no exception
// | | | | | | 1 - out_of_range
// | | | | | | 2 - length_error
// | | | | | | -1 - exc. safety
// | | | | | |
// | | | | | +---------+
// V V V V V V
TEST ("ab", 0, 1, 'c', "cab", 0),
TEST ("", 0, 0, ' ', "", 0),
TEST ("", 0, 1, 'b', "b", 0),
TEST ("<U0>", 0, 0, ' ', "<U0>", 0),
TEST ("<U0>", 1, 0, ' ', "<U0>", 0),
TEST ("", 0, 2, '\0', "<U0>@2", 0),
TEST ("<U0>", 0, 1, 'a', "a<U0>", 0),
TEST ("<U0>", 1, 1, 'a', "<U0>a", 0),
TEST ("<U0>", 0, 1, '\0', "<U0>@2", 0),
TEST ("<U0>", 1, 2, '\0', "<U0>@3", 0),
TEST ("<U0>", 1, 0, '\0', "<U0>", 0),
TEST ("cde", 0, 2, 'a', "aacde", 0),
TEST ("cde", 1, 1, 'a', "cade", 0),
TEST ("cde", 3, 3, 'a', "cdeaaa", 0),
TEST ("cde", 2, 3, 'a', "cdaaae", 0),
TEST ("ab", 0, 2, '\0', "<U0>@2ab", 0),
TEST ("ab", 1, 1, '\0', "a<U0>b", 0),
TEST ("ab", 2, 2, '\0', "ab<U0>@2", 0),
TEST ("a<U0>b<U0>@2c", 3, 2, '\0', "a<U0>b<U0>@3<U0>c", 0),
TEST ("a<U0>b<U0>@2c", 2, 1, '\0', "a<U0>@2b<U0>@2c", 0),
TEST ("<U0>ab<U0>@2c", 0, 3, '\0', "<U0>@3<U0>ab<U0>@2c", 0),
TEST ("a<U0>bc<U0>@2", 6, 2, 'a', "a<U0>bc<U0>@2aa", 0),
TEST ("", 0, 4106, 'x', "x@4106", 0),
TEST ("x@4096", 0, 2, 'a', "aax@4096", 0),
TEST ("x@4096", 0, 2, 'a', "aax@4096", 0),
TEST ("x@4096", 1, 2, 'a', "xaax@4095", 0),
TEST ("x@4096", 1, 1, '\0', "x<U0>x@4095", 0),
TEST ("x@127", 0, 1, 'x', "x@128", 0),
TEST ("x@200", 128, 7, 'x', "x@207", 0),
TEST ("x@331", 331, 3, 'x', "x@334", 0),
TEST ("x@539", 0, 1, 'x', "x@540", 0),
TEST ("x@539", 0, 873, 'x', "x@1412", 0),
TEST ("x@873", 873, 1411, 'x', "x@2284", 0),
TEST ("x@3694", 128, 1, 'x', "x@3695", 0),
TEST ("x@540", 0, 1, 'x', "x@541", 0),
TEST ("", 0, 3695, 'x', "x@3695", 0),
TEST ("a", 0, 4095, 'x', "x@4095a", 0),
TEST ("x@4096", 0, 2047, 'b', "b@2047x@4096", 0),
TEST ("x@4096", 2047, 2048, 'x', "x@6144", 0),
TEST ("last", 4, 4, 't', "lasttttt", 0)
};
/**************************************************************************/
// used to exercise
// insert (iterator, const value_type&)
static const ContainerTestCase
iter_cref_test_cases [] = {
#undef TEST
#define TEST(lst, off, val, res, bthrow) \
{ __LINE__, off, -1, -1, -1, val, lst, sizeof lst - 1, 0, \
0, res, sizeof res - 1, bthrow }
// +----------------------------------------- controlled sequence
// | +------------------------ insert() pos argument
// | | +------------------- character to be inserted
// | | | +--------------- expected result sequence
// | | | | +--- exception info
// | | | | | 0 - no exception
// | | | | | 1 - out_of_range
// | | | | | 2 - length_error
// | | | | | -1 - exc. safety
// | | | | |
// | | | | |
// V V V V V
TEST ("ab", 0, 'c', "cab", 0),
TEST ("", 0, 'b', "b", 0),
TEST ("", 0, '\0', "<U0>", 0),
TEST ("<U0>", 0, 'a', "a<U0>", 0),
TEST ("<U0>", 1, 'a', "<U0>a", 0),
TEST ("<U0>", 0, '\0', "<U0>@2", 0),
TEST ("<U0>", 1, '\0', "<U0>@2", 0),
TEST ("cde", 0, 'a', "acde", 0),
TEST ("cde", 1, 'a', "cade", 0),
TEST ("cde", 2, 'a', "cdae", 0),
TEST ("cde", 3, 'a', "cdea", 0),
TEST ("a<U0>b<U0>@2c", 3, '\0', "a<U0>b<U0>@3c", 0),
TEST ("<U0>ab<U0>@2c", 0, '\0', "<U0>@2ab<U0>@2c", 0),
TEST ("a<U0>bc<U0>@2", 6, 'a', "a<U0>bc<U0>@2a", 0),
TEST ("x@4096", 0, 'a', "ax@4096", 0),
TEST ("x@4096", 1, 'a', "xax@4095", 0),
TEST ("x@4096", 1, '\0', "x<U0>x@4095", 0),
TEST ("x@127", 0, 'x', "x@128", 0),
TEST ("x@206", 1, 'x', "x@207", 0),
TEST ("x@333", 333, 'x', "x@334", 0),
TEST ("x@539", 128, 'x', "x@540", 0),
TEST ("x@1411", 0, 'x', "x@1412", 0),
TEST ("x@2283", 10, 'x', "x@2284", 0),
TEST ("x@3694", 3694, 'x', "x@3695", 0),
TEST ("x@540", 538, 'x', "x@541", 0),
TEST ("last", 4, 't', "lastt", 0)
};
/**************************************************************************/
// used to exercise
// push_front (const value_type&)
static const ContainerTestCase
push_front_test_cases [] = {
#undef TEST
#define TEST(str, val, res) { \
__LINE__, -1, -1, -1, -1, val, str, sizeof str - 1, \
0, 0, res, sizeof res - 1, 0 }
// +----------------------------------------- controlled sequence
// | +------------------------ character to be inserted
// | | +------------------ expected result sequence
// | | |
// | | |
// | | |
// | | |
// | | |
// V V V
TEST ("", 'x', "x" ),
TEST ("<U0>", '\0', "<U0>@2" ),
TEST ("", 'a', "a" ),
TEST ("bc", 'a', "abc" ),
TEST ("<U0> s", 't', "t<U0> s" ),
TEST ("<U0>@3b", 'a', "a<U0>@3b" ),
TEST ("<U0>b<U0>@2c", 'a', "a<U0>b<U0>@2c" ),
TEST ("ab<U0>@2c", '\0', "<U0>ab<U0>@2c" ),
TEST ("b<U0>c<U0>@2", 'a', "ab<U0>c<U0>@2" ),
TEST ("x@4095", 'x', "x@4096" ),
TEST ("ast test", 'l', "last test" )
};
/**************************************************************************/
// used to exercise
// push_back (const value_type&)
static const ContainerTestCase
push_back_test_cases [] = {
#undef TEST
#define TEST(str, val, res) { \
__LINE__, -1, -1, -1, -1, val, str, sizeof str - 1, \
0, 0, res, sizeof res - 1, 0 }
// +----------------------------------------- controlled sequence
// | +------------------------ character to be inserted
// | | +------------------ expected result sequence
// | | |
// | | |
// | | |
// | | |
// | | |
// V V V
TEST ("", 'x', "x" ),
TEST ("<U0>", '\0', "<U0>@2" ),
TEST ("", 'a', "a" ),
TEST ("ab", 'c', "abc" ),
TEST ("t<U0> ", 's', "t<U0> s" ),
TEST ("a<U0>@3", 'b', "a<U0>@3b" ),
TEST ("a<U0>b<U0>@2", 'c', "a<U0>b<U0>@2c" ),
TEST ("<U0>ab<U0>@2", 'c', "<U0>ab<U0>@2c" ),
TEST ("ab<U0>c<U0>", '\0', "ab<U0>c<U0>@2" ),
TEST ("x@4095", 'x', "x@4096" ),
TEST ("last tes", 't', "last test" )
};
/**************************************************************************/
template <class InputIterator, class Distance>
inline void
_rw_advance (InputIterator& it, Distance dist) {
while (0 < dist) {
--dist;
++it;
}
}
template<class InputIterator>
inline std::size_t
_rw_distance(InputIterator first, InputIterator last)
{
std::size_t dist = 0;
for (; first != last; ++first)
++dist;
return dist;
}
// invokes specializations of the member function template
// on the required iterator categories
template <class List, class Iterator>
struct InsertRange: ContRangeBase<List> {
typedef typename List::iterator ListIter;
typedef typename List::value_type ListVal;
InsertRange () { }
virtual List&
operator() (List &lst,
const ContainerTestCaseData<ListVal>& tdata) const {
// create a pair of iterators into the list object being modified
ListIter first1 (lst.begin ());
_rw_advance (first1, tdata.off1_);
const ListVal* const beg = tdata.arg_ + tdata.off2_;
const ListVal* const end = beg + tdata.ext2_;
const Iterator first2 (beg, beg, end);
const Iterator last2 (end, beg, end);
lst.insert (first1, first2, last2);
return lst;
}
};
// invokes possible overloads of the member function template
// on common RandomAccessIterator types
template <class List, class Iterator>
struct InsertRangeOverload: ContRangeBase<List>
{
typedef typename List::iterator ListIter;
typedef typename List::value_type ListVal;
InsertRangeOverload () { }
virtual List&
operator() (List &lst,
const ContainerTestCaseData<ListVal>& tdata) const {
// create a pair of iterators into the list object being modified
ListIter first1 (lst.begin ());
_rw_advance (first1, tdata.off1_);
bool reverse_iter = ListIds::ReverseIterator == tdata.func_.iter_id_
|| ListIds::ConstReverseIterator == tdata.func_.iter_id_;
const std::size_t srclen_ = tdata.arglen_;
const std::size_t off =
reverse_iter ? srclen_ - tdata.off2_ - tdata.ext2_ : tdata.off2_;
const std::size_t ext = tdata.ext2_;
List str_arg (tdata.arg_, tdata.arg_ + tdata.arglen_);
Iterator first2 (this->begin (str_arg, (Iterator*)0));
_rw_advance (first2, off);
Iterator last2 (first2);
_rw_advance (last2, ext);
if (ListIds::UserClass == tdata.func_.elem_id_)
UserClass::reset_totals ();
lst.insert (first1, first2, last2);
return lst;
}
};
// invokes specializations of the member function template
// on the required iterator categories
template <class List, class Iterator>
struct InsertRangePtrOverload: ContRangeBase<List> {
typedef typename List::iterator ListIter;
typedef typename List::value_type ListVal;
InsertRangePtrOverload () { }
virtual List&
operator() (List& lst,
const ContainerTestCaseData<ListVal>& tdata) const {
ListIter first1 (lst.begin ());
_rw_advance (first1, tdata.off1_);
const ListVal* const beg = tdata.arg_ + tdata.off2_;
const ListVal* const end = beg + tdata.ext2_;
const Iterator first2 = _RWSTD_CONST_CAST (Iterator, beg);
const Iterator last2 = _RWSTD_CONST_CAST (Iterator, end);
lst.insert (first1, first2, last2);
return lst;
}
};
/**************************************************************************/
template <class T, class Allocator>
void test_insert (T*, Allocator*,
const ContRangeBase< std::list <T, Allocator> > &rng,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list <T, Allocator> List;
typedef typename List::iterator ListIter;
typedef typename List::const_iterator ListCIter;
typedef ListState<List> ListState;
const ContainerFunc &func = tdata.func_;
const ContainerTestCase &tcase = tdata.tcase_;
// construct the list object to be modified
List lst (tdata.str_, tdata.str_ + tdata.strlen_);
// save the state of the list object before the call
// to detect exception safety violations (changes to
// the state of the object after an exception)
const ListState lst_state (lst);
std::ptrdiff_t exp_off = Insert (iter_cref) == func.which_ ? tcase.off : 0;
// compute the offset and the extent (the number of elements)
// of the first range into the list object being modified
const std::size_t size1 = tdata.strlen_;
const std::size_t off1 =
std::size_t (tcase.off) < size1 ? std::size_t (tcase.off) : size1;
const T arg_val = T::from_char (char (tcase.val));
rwt_free_store* const pst = rwt_get_free_store (0);
SharedAlloc* const pal = SharedAlloc::instance ();
// iterate for`throw_after' starting at the next call to operator new,
// forcing each call to throw an exception, until the function finally
// succeeds (i.e, no exception is thrown)
std::size_t throw_count;
for (throw_count = 0; ; ++throw_count) {
// (name of) expected and caught exception
const char* expected = 0;
const char* caught = 0;
#ifndef _RWSTD_NO_EXCEPTIONS
if (0 == tcase.bthrow) {
// by default exercise the exception safety of the function
// by iteratively inducing an exception at each call to operator
// new or Allocator::allocate() until the call succeeds
expected = exceptions [1]; // bad_alloc
*pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
pal->throw_at_calls_ [pal->m_allocate] =
pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
}
else {
// exceptions disabled for this test case
}
#else // if defined (_RWSTD_NO_EXCEPTIONS)
if (tcase.bthrow)
return;
#endif // _RWSTD_NO_EXCEPTIONS
// pointer to the returned reference
const List* ret_ptr = 0;
// start checking for memory leaks
rw_check_leaks (lst.get_allocator ());
const bool is_class = ListIds::UserClass == func.elem_id_;
const std::size_t x_count_save = UserClass::count_;
try {
// reset function call counters
if (is_class)
UserClass::reset_totals ();
std::size_t newcnt = 0;
switch (func.which_) {
case Insert (iter_size_cref): {
ListIter it (lst.begin ());
_rw_advance (it, off1);
lst.insert (it, tcase.size, arg_val);
ret_ptr = &lst; // function returns void
newcnt = tcase.size;
break;
}
case Insert (iter_cref): {
ListIter it (lst.begin ());
_rw_advance (it, off1);
it = lst.insert (it, arg_val);
ret_ptr = &lst + _rw_distance (lst.begin (), it);
newcnt = 1;
break;
}
case Insert (iter_range): {
ret_ptr = &rng (lst, tdata); // function returns void
newcnt = tcase.size2;
break;
}
case ListIds::push_front_cref:
lst.push_front (arg_val);
ret_ptr = &lst; // function returns void
newcnt = 1;
break;
case ListIds::push_back_cref:
lst.push_back (arg_val);
ret_ptr = &lst; // function returns void
newcnt = 1;
break;
default:
RW_ASSERT (!"logic error: unknown insert overload");
return;
}
if (is_class) {
// verify that the erase method calls only dtor
// of UserClass and only the given number of times each
bool success = UserClass::is_total (x_count_save + newcnt,
0, newcnt, 0, 0, 0);
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL} called default/copy ctor "
"and operator=() %zu, %zu and %zu times, "
"respectively, 0, %zu, 0, expected",
__LINE__,
UserClass::n_total_def_ctor_,
UserClass::n_total_copy_ctor_,
UserClass::n_total_op_assign_,
newcnt);
}
// verify that the reference returned from the function
// refers to the modified list object (i.e., *this
// within the function)
const std::ptrdiff_t ret_off = ret_ptr - &lst;
// verify the returned value
rw_assert (exp_off == ret_off, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}== begin() + %td, got %td%{;}"
"%{?}returned invalid reference, offset is %td%{;}",
__LINE__, Insert (iter_cref) == func.which_,
exp_off, ret_off,
Insert (iter_cref) != func.which_, ret_off);
// for convenience
static const int cwidth = sizeof (T);
const std::size_t got_size = lst.size ();
char* const got = new char [got_size + 1];
std::size_t index = 0;
for (ListCIter it = lst.begin (),
end = lst.end (); it != end; ++it) {
got [index++] = char (it->data_.val_);
}
got [got_size] = '\0';
// verify that strings length are equal
rw_assert (tdata.reslen_ == got_size, 0, tcase.line,
"line %d. %{$FUNCALL} expected \"%{X=*}\" with length "
"%zu, got %{/*.*Gs} with length %zu", __LINE__,
cwidth, int (tdata.reslen_), tdata.res_, tdata.reslen_,
1, int (got_size), got, got_size);
if (tdata.reslen_ == got_size) {
// if the result length matches the expected length
// (and only then), also verify that the modified
// list matches the expected result
const T* pmatch = T::mismatch (tdata.res_, got, got_size);
rw_assert (0 == pmatch, 0, tcase.line,
"line %d. %{$FUNCALL} expected \"%{X=*}\", "
"got %{/*.*Gs}, difference at offset %zu",
__LINE__, cwidth, int (tdata.reslen_), tdata.res_,
1, int (got_size), got, pmatch - tdata.res_);
}
delete [] got;
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::bad_alloc &ex) {
caught = exceptions [1];
rw_assert (0 == tcase.bthrow, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (const std::exception &ex) {
caught = exceptions [2];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (...) {
caught = exceptions [0];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught %s",
__LINE__, 0 != expected, expected, caught);
}
#endif // _RWSTD_NO_EXCEPTIONS
// FIXME: verify the number of blocks the function call
// is expected to allocate and detect any memory leaks
rw_check_leaks (lst.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
if (caught) {
// verify that an exception thrown during allocation
// didn't cause a change in the state of the object
lst_state.assert_equal (ListState (lst),
__LINE__, tcase.line, caught);
if (0 == tcase.bthrow) {
// allow this call to operator new to succeed and try
// to make the next one to fail during the next call
// to the same function again
continue;
}
}
else if (0 < tcase.bthrow) {
rw_assert (caught == expected, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s, caught %s"
"%{:}unexpectedly caught %s%{;}",
__LINE__, 0 != expected, expected, caught, caught);
}
break;
}
// disable bad_alloc exceptions
*pst->throw_at_calls_ [0] = 0;
pal->throw_at_calls_ [pal->m_allocate] = 0;
}
/**************************************************************************/
template <class T, class Allocator>
void test_insert (T*, Allocator*,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list<T, Allocator> List;
if (tdata.func_.which_ == Insert (iter_range)) {
switch (tdata.func_.iter_id_) {
// exercise possible overloads of the member function template
// on common RandomAccessIterator types
#undef TEST
#define TEST(Iterator) do { \
typedef typename List::Iterator Iter; \
static const \
InsertRangePtrOverload<List, Iter> rng; \
test_insert ((T*)0, (Allocator*)0, rng, tdata); \
} while (0)
case ListIds::Pointer: TEST (pointer); break;
case ListIds::ConstPointer: TEST (const_pointer); break;
#undef TEST
#define TEST(Iterator) do { \
typedef typename List::Iterator Iter; \
static const \
InsertRangeOverload<List, Iter> rng; \
test_insert ((T*)0, (Allocator*)0, rng, tdata); \
} while (0)
case ListIds::Iterator: TEST (iterator); break;
case ListIds::ConstIterator: TEST (const_iterator); break;
case ListIds::ReverseIterator: TEST (reverse_iterator); break;
case ListIds::ConstReverseIterator: TEST (const_reverse_iterator);
break;
// exercise specializations of the member function template
// on the required iterator categories
#undef TEST
#define TEST(Iterator) do { \
typedef Iterator<T> Iter; \
static const \
InsertRange<List, Iter> rng; \
test_insert ((T*)0, (Allocator*)0, rng, tdata); \
} while (0)
case ListIds::Input: TEST (InputIter); break;
case ListIds::Forward: TEST (ConstFwdIter); break;
case ListIds::Bidir: TEST (ConstBidirIter); break;
case ListIds::Random: TEST (ConstRandomAccessIter); break;
default:
rw_error (0, 0, __LINE__, "bad iterator id");
}
}
else {
// exercise ordinary overloads of the member function
static const ContRangeBase<List> rng;
test_insert ((T*)0, (Allocator*)0, rng, tdata);
}
}
/**************************************************************************/
DEFINE_CONTAINER_TEST_FUNCTIONS (test_insert);
int main (int argc, char** argv)
{
static const ContainerTest
tests [] = {
#undef TEST
#define TEST(sig) { \
Insert (sig), sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (iter_cref),
TEST (iter_size_cref),
TEST (iter_range),
#undef TEST
#define TEST(sig) { \
ListIds::sig ## _cref, sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (push_front),
TEST (push_back)
};
const std::size_t test_count = sizeof tests / sizeof *tests;
const int status =
rw_run_cont_test (argc, argv, __FILE__,
"lib.list.insert",
ContainerIds::List,
test_insert_func_array, tests, test_count);
return status;
}

View File

@@ -0,0 +1,426 @@
/***************************************************************************
*
* 23.list.iterators.cpp - test exercising [lib.list.iterators]
*
* $Id: 23.list.iterators.cpp 523692 2007-03-29 13:01:55Z 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.
*
**************************************************************************/
#include <list> // for list
#include <stdexcept> // for out_of_range, length_error
#include <cstddef> // for size_t
#include <23.list.h> // for ListMembers
#include <driver.h> // for rw_test()
#include <rw_allocator.h> // for UserAlloc
#include <rw_new.h> // for bad_alloc, replacement operator new
/**************************************************************************/
static const char* const exceptions[] = {
"unknown exception", "bad_alloc", "exception"
};
/**************************************************************************/
// used to exercise
// begin () and rend () and front ()
static const ContainerTestCase
begin_void_test_cases [] = {
#undef TEST
#define TEST(lst, res) { \
__LINE__, -1, -1, -1, -1, -1, \
lst, sizeof (lst) - 1, \
0, 0, 0, res, 0 \
}
// +--------------------------------- controlled sequence
// | +---------------- expected result
// | |
// V V
TEST ("", _RWSTD_SIZE_MAX),
TEST ("a", 'a' ),
TEST ("<U0>", '\0'),
TEST ("abc", 'a' ),
TEST ("<U0>ab<U0>@2c", '\0'),
TEST ("a<U0>b<U0>@2c", 'a' ),
TEST ("a<U0>bc<U0>@2", 'a' ),
TEST ("x@4096", 'x' ),
TEST ("last", 'l' )
};
/**************************************************************************/
// used to exercise
// end () and rbegin () and back ()
static const ContainerTestCase
end_void_test_cases [] = {
#undef TEST
#define TEST(lst, res) { \
__LINE__, -1, -1, -1, -1, -1, \
lst, sizeof (lst) - 1, \
0, 0, 0, res, 0 \
}
// +--------------------------------- controlled sequence
// | +---------------- expected result
// | |
// V V
TEST ("", _RWSTD_SIZE_MAX),
TEST ("a", 'a' ),
TEST ("<U0>", '\0'),
TEST ("abc", 'c' ),
TEST ("<U0>ab<U0>@2c", 'c' ),
TEST ("a<U0>b<U0>@2c", 'c' ),
TEST ("a<U0>bc<U0>@2", '\0'),
TEST ("x@4096", 'x' ),
TEST ("last", 't' )
};
/**************************************************************************/
// exercises:
// get_allocator ()
static const ContainerTestCase
get_allocator_void_test_cases [] = {
#undef TEST
#define TEST(lst) { \
__LINE__, -1, -1, -1, -1, -1, \
lst, sizeof (lst) - 1, \
0, 0, 0, 0, 0 \
}
// +------------------------------------------ controlled sequence
// |
// |
// |
// |
// |
// |
// |
// V
TEST ("" ),
TEST ("ab" ),
TEST ("<U0>" ),
TEST ("x@4096" ),
TEST ("a<U0>b" ),
TEST ("a@2048cb@2047" ),
TEST ("last" )
};
/**************************************************************************/
template <class T, class Allocator>
void test_iterators (T*, Allocator*,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list <T, Allocator> List;
typedef typename List::iterator ListIter;
typedef typename List::const_iterator ListCIter;
typedef typename List::reverse_iterator ListRIter;
typedef typename List::const_reverse_iterator ListCRIter;
typedef ListState<List> ListState;
const ContainerFunc &func = tdata.func_;
const ContainerTestCase &tcase = tdata.tcase_;
const bool test_iters =
func.which_ == ListIds::begin_void
|| func.which_ == ListIds::begin_const_void
|| func.which_ == ListIds::end_void
|| func.which_ == ListIds::end_const_void
|| func.which_ == ListIds::rbegin_void
|| func.which_ == ListIds::rbegin_const_void
|| func.which_ == ListIds::rend_void
|| func.which_ == ListIds::rend_const_void
|| func.which_ == ListIds::front_void
|| func.which_ == ListIds::front_const_void
|| func.which_ == ListIds::back_void
|| func.which_ == ListIds::back_const_void;
const bool test_const_list =
func.which_ == ListIds::begin_const_void
|| func.which_ == ListIds::end_const_void
|| func.which_ == ListIds::rbegin_const_void
|| func.which_ == ListIds::rend_const_void
|| func.which_ == ListIds::front_const_void
|| func.which_ == ListIds::back_const_void;
const bool test_end_iters =
func.which_ == ListIds::end_void
|| func.which_ == ListIds::end_const_void
|| func.which_ == ListIds::rend_void
|| func.which_ == ListIds::rend_const_void;
// allocator object for test get_allocator
Allocator alloc;
// construct the list object
List lst (tdata.str_, tdata.str_ + tdata.strlen_, alloc);
// construct the constant list object
const List clst (tdata.str_, tdata.str_ + tdata.strlen_, alloc);
const std::size_t s_size = test_const_list ? clst.size () : lst.size ();
// save the state of the list object before the call
// to detect exception safety violations (changes to
// the state of the object after an exception)
const ListState lst_state (lst);
// start checking for memory leaks
rw_check_leaks (lst.get_allocator ());
try {
// methods result
const T* res_ptr = 0;
// for begin () and end ()
ListIter it;
// for begin () const and end () const
ListCIter cit;
// for rbegin () and rend ()
ListRIter rit;
// for rbegin () const and rend () const
ListCRIter crit;
// for get_allocator ()
Allocator resalloc;
bool it_relations = true;
switch (func.which_) {
case ListIds::begin_void:
it = lst.begin();
it_relations = it == lst.rend ().base ();
if (s_size) res_ptr = &*it;
break;
case ListIds::begin_const_void:
cit = clst.begin();
it_relations = cit == clst.rend ().base ();
if (s_size) res_ptr = &*cit;
break;
case ListIds::end_void:
it = lst.end();
it_relations = it == lst.rbegin ().base ();
if (s_size) res_ptr = &*--it;
break;
case ListIds::end_const_void:
cit = clst.end();
it_relations = cit == clst.rbegin ().base ();
if (s_size) res_ptr = &*--cit;
break;
case ListIds::rbegin_void:
rit = lst.rbegin();
it_relations = rit.base () == lst.end ();
if (s_size) res_ptr = &*rit;
break;
case ListIds::rbegin_const_void:
crit = clst.rbegin();
it_relations = crit.base () == clst.end ();
if (s_size) res_ptr = &*crit;
break;
case ListIds::rend_void:
rit = lst.rend();
it_relations = rit.base () == lst.begin ();
if (s_size) res_ptr = &*--rit;
break;
case ListIds::rend_const_void:
crit = clst.rend();
it_relations = crit.base () == clst.begin ();
if (s_size) res_ptr = &*--crit;
break;
case ListIds::front_void:
if (s_size) {
res_ptr = &lst.front ();
it_relations = res_ptr == &*lst.begin ();
}
break;
case ListIds::front_const_void:
if (s_size) {
res_ptr = &clst.front ();
it_relations = res_ptr == &*clst.begin ();
}
break;
case ListIds::back_void:
if (s_size) {
res_ptr = &lst.back ();
it_relations = res_ptr == &*--lst.end ();
}
break;
case ListIds::back_const_void:
if (s_size) {
res_ptr = &clst.back ();
it_relations = res_ptr == &*--clst.end ();
}
break;
case ListIds::get_allocator_void:
resalloc = clst.get_allocator ();
break;
default:
RW_ASSERT (!"test logic error: unknown iterators overload");
return;
}
if (res_ptr) {
const char exp_res =
(_RWSTD_SIZE_MAX != tcase.nres ? char (tcase.nres) : char ());
const bool success = 0 == T::mismatch (res_ptr, &exp_res, 1);
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL}%{?} - 1%{;} expected "
"%{#c}, got %{#c}", __LINE__,
test_end_iters, exp_res, char (res_ptr->data_.val_));
}
if (test_iters) {
if (0 == s_size) {
bool success = true;
if ( func.which_ == ListIds::begin_void
|| func.which_ == ListIds::end_void)
success = it == lst.begin () && it == lst.end ();
if ( func.which_ == ListIds::begin_const_void
|| func.which_ == ListIds::end_const_void)
success = cit == clst.begin () && cit == clst.end ();
if ( func.which_ == ListIds::rbegin_void
|| func.which_ == ListIds::rend_void)
success = rit == lst.rbegin () && rit == lst.rend ();
if ( func.which_ == ListIds::rbegin_const_void
|| func.which_ == ListIds::rend_const_void)
success = crit == clst.rbegin () && crit == clst.rend ();
// check the begin () == end (), rbegin () == rend ()
rw_assert(success, 0, tcase.line,
"line %d. %{$FUNCALL} returned iterator is not "
"equal to begin and end for an empty list",
__LINE__);
}
// check the iterators relationship
rw_assert(it_relations, 0, tcase.line,
"line %d. %{$FUNCALL} iterators "
"relationship is broken", __LINE__);
}
if (func.which_ == ListIds::get_allocator_void) {
// verify that the allocator returned from the function
// equal to allocator passed to the ctor
const bool success = (alloc == resalloc);
rw_assert(success, 0, tcase.line,
"line %d. %{$FUNCALL} expected equal to allocator "
"passed to the ctor", __LINE__);
}
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::bad_alloc &ex) {
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} unexpectedly caught std::%s(%#s)",
__LINE__, exceptions [1], ex.what ());
}
catch (const std::exception &ex) {
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} unexpectedly caught std::%s(%#s)",
__LINE__, exceptions [2], ex.what ());
}
catch (...) {
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} unexpectedly caught %s",
__LINE__, exceptions [0]);
}
#endif // _RWSTD_NO_EXCEPTIONS
// FIXME: verify the number of blocks the function call
// is expected to allocate and detect any memory leaks
rw_check_leaks (lst.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
// verify that state of the object didn't changed
lst_state.assert_equal (ListState (lst),
__LINE__, tcase.line, "call");
}
/**************************************************************************/
DEFINE_CONTAINER_TEST_FUNCTIONS (test_iterators);
int main (int argc, char** argv)
{
static const ContainerTest
tests [] = {
#undef TEST
#define TEST(gsig, sig) { \
gsig, sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases \
}
TEST (ListIds::begin_void, begin_void),
TEST (ListIds::begin_const_void, begin_void),
TEST (ListIds::end_void, end_void),
TEST (ListIds::end_const_void, end_void),
TEST (ListIds::rbegin_void, end_void),
TEST (ListIds::rbegin_const_void, end_void),
TEST (ListIds::rend_void, begin_void),
TEST (ListIds::rend_const_void, begin_void),
TEST (ListIds::front_void, begin_void),
TEST (ListIds::front_const_void, begin_void),
TEST (ListIds::back_void, end_void),
TEST (ListIds::back_const_void, end_void),
TEST (ListIds::get_allocator_void, get_allocator_void)
};
const std::size_t test_count = sizeof tests / sizeof *tests;
return rw_run_cont_test (argc, argv, __FILE__,
"lib.list.iterators", ContainerIds::List,
test_iterators_func_array, tests, test_count);
}

View File

@@ -0,0 +1,421 @@
/***************************************************************************
*
* 23.list.special.cpp - test exercising [lib.list.special]
*
* $Id: 23.list.special.cpp 522951 2007-03-27 15:16:23Z 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.
*
**************************************************************************/
#include <list> // for list
#include <cstddef> // size_t
#include <23.list.h> // for ListMembers
#include <driver.h> // for rw_assert()
#include <rw_allocator.h> // for UserAlloc
#include <rw_new.h> // for bad_alloc, replacement operator new
/**************************************************************************/
// for convenience and brevity
#define Swap(sig) ListIds::swap_ ## sig
static const char* const exceptions[] = {
"unknown exception", "bad_alloc", "exception"
};
/**************************************************************************/
// exercises:
// swap (list&)
static const ContainerTestCase
cont_cont_test_cases [] = {
#undef TEST
#define TEST(str, arg) \
{ __LINE__, -1, -1, -1, -1, -1, \
str, sizeof str - 1, arg, sizeof arg - 1, \
0, 0, 0 \
}
// +------------------------- controlled "destination" sequence
// | +-------- controlled "source" sequence
// | |
// V V
TEST ("", ""),
};
// exercises:
// swap (list&)
static const ContainerTestCase
cont_test_cases [] = {
// +------------------------- controlled "destination" sequence
// | +-------- controlled "source" sequence
// | |
// V V
TEST ("", ""),
TEST ("", "a"),
TEST ("a", ""),
TEST ("", "<U0>"),
TEST ("<U0>", ""),
TEST ("a", "b"),
TEST ("a", "bc"),
TEST ("ab", "c"),
TEST ("a<U0>b<U0>@2c", "<U0>b<U0>@2c"),
TEST ("<U0>b<U0>@2c", "a<U0>b<U0>@2c"),
TEST ("a<U0>b<U0>@2c", "<U0>@2"),
TEST ("<U0>@2", "a<U0>b<U0>@2c"),
TEST ("x@4096", ""),
TEST ("", "x@4096"),
TEST ("x@4096", "<U0>@3"),
TEST ("<U0>@3", "x@4096"),
TEST ("x@4096", "x@4096"),
TEST ("", "x@128"),
TEST ("x@207", "x@128"),
TEST ("x@128", "x@334"),
TEST ("x@873", "x@334"),
TEST ("x@1412", "x@540"),
TEST ("x@540", "x@2284"),
TEST ("x@3695", "x@2284"),
TEST ("x@3695", "x@128"),
TEST ("", 0),
TEST ("<U0>", 0),
TEST ("abc", 0),
TEST ("a<U0>b<U0>@2c", 0),
TEST ("x@4096", 0),
TEST (0, ""),
TEST (0, "<U0>"),
TEST (0, "abc@1024"),
TEST (0, "a<U0>b<U0>@2c"),
TEST (0, "x@4096"),
TEST ("last", "test")
};
/**************************************************************************/
struct ListValueType { };
typedef std::allocator<ListValueType> ListAllocator;
typedef std::list<ListValueType, ListAllocator> ListType;
static int list_swap_called;
_RWSTD_NAMESPACE (std) {
// define an explicit specialization of the list::swap() member
// to verify tha the non-member swap function calls the member
_RWSTD_SPECIALIZED_FUNCTION
void ListType::swap (ListType&)
{
++list_swap_called;
}
} // namespace std
/**************************************************************************/
void test_std_swap ()
{
static bool tested = false;
if (tested)
return;
tested = true;
rw_info (0, 0, 0,
"Testing std::swap (std::list&, std::list&) "
"calls std::list::swap");
// verify the signature of the function specialization
void (*pswap)(ListType&, ListType&) =
&std::swap<ListValueType, ListAllocator>;
_RWSTD_UNUSED (pswap);
// verify that std::swap() calls std::list::swap()
ListType lst;
std::swap (lst, lst);
rw_assert (1 == list_swap_called, 0, __LINE__,
"std::swap (std::list<T, A>&, std::list<T, A>&) called "
"std::list<T, A>::swap (std::list<T, A>&) exactly once; "
"got %d times", list_swap_called);
}
/**************************************************************************/
template <class T, class Allocator>
void test_swap (T*,
Allocator &a1,
Allocator &a2,
const ContainerTestCaseData<T> &tdata)
{
typedef std::list <T, Allocator> List;
typedef ListState<List> ListState;
const ContainerTestCase &tcase = tdata.tcase_;
const ContainerFunc &func = tdata.func_;
// construct the list object to be modified
// and the argument list
List src_list (tdata.str_, tdata.str_ + tdata.strlen_, a1);
List dst_list (tdata.arg_, tdata.arg_ + tdata.arglen_, a2);
List& arg_list = tcase.arg ? dst_list : src_list;
// save the state of the list object before the call
// to detect exception safety violations (changes to
// the state of the object after an exception)
const ListState src_state (src_list);
const ListState arg_state (arg_list);
rwt_free_store* const pst = rwt_get_free_store (0);
SharedAlloc* const pal = SharedAlloc::instance ();
// iterate for`throw_count' starting at the next call to operator new,
// forcing each call to throw an exception, until the function finally
// succeeds (i.e, no exception is thrown)
std::size_t throw_count;
for (throw_count = 0; ; ++throw_count) {
const char* expected = 0;
const char* caught = 0;
#ifndef _RWSTD_NO_EXCEPTIONS
// no exceptions expected
if (0 == tcase.bthrow && a1 == a2) {
// by default exercise the exception safety of the function
// by iteratively inducing an exception at each call to operator
// new or Allocator::allocate() until the call succeeds
expected = exceptions [1]; // bad_alloc
*pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_count + 1;
pal->throw_at_calls_ [pal->m_allocate] =
pal->throw_at_calls_ [pal->m_allocate] + throw_count + 1;
}
#else // if defined (_RWSTD_NO_EXCEPTIONS)
if (tcase.bthrow)
return;
#endif // _RWSTD_NO_EXCEPTIONS
// start checking for memory leaks
rw_check_leaks (src_list.get_allocator ());
rw_check_leaks (arg_list.get_allocator ());
try {
const bool is_class = ListIds::UserClass == func.elem_id_;
// reset function call counters
if (is_class)
UserClass::reset_totals ();
src_list.swap (arg_list);
if (is_class && a1 == a2) {
bool success = 0 == (UserClass::n_total_def_ctor_
| UserClass::n_total_copy_ctor_
| UserClass::n_total_op_assign_);
rw_assert (success, 0, tcase.line,
"line %d. %{$FUNCALL}: complexity: %zu def ctors, "
"%zu copy ctors, %zu assigns", __LINE__,
UserClass::n_total_def_ctor_,
UserClass::n_total_copy_ctor_,
UserClass::n_total_op_assign_);
}
if (0 == tcase.str) {
rw_assert (0 == arg_list.size (), 0, tcase.line,
"line %d. %{$FUNCALL}: expected 0 size, "
"got %zu", __LINE__, arg_list.size ());
}
if (a1 == a2) {
src_state.assert_equal (ListState (arg_list),
__LINE__, tcase.line, "swap");
arg_state.assert_equal (ListState (src_list),
__LINE__, tcase.line, "swap");
}
}
#ifndef _RWSTD_NO_EXCEPTIONS
catch (const std::bad_alloc &ex) {
caught = exceptions [1];
rw_assert (0 == tcase.bthrow, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (const std::exception &ex) {
caught = exceptions [2];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught std::%s(%#s)",
__LINE__, 0 != expected, expected, caught, ex.what ());
}
catch (...) {
caught = exceptions [0];
rw_assert (0, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s,%{:}"
"unexpectedly%{;} caught %s",
__LINE__, 0 != expected, expected, caught);
}
#endif // _RWSTD_NO_EXCEPTIONS
// FIXME: verify the number of blocks the function call
// is expected to allocate and detect any memory leaks
rw_check_leaks (src_list.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
rw_check_leaks (arg_list.get_allocator (), tcase.line,
std::size_t (-1), std::size_t (-1));
if (caught) {
// verify that an exception thrown during allocation
// didn't cause a change in the state of the object
src_state.assert_equal (ListState (src_list),
__LINE__, tcase.line, caught);
arg_state.assert_equal (ListState (arg_list),
__LINE__, tcase.line, caught);
if (0 == tcase.bthrow) {
// allow this call to operator new to succeed and try
// to make the next one to fail during the next call
// to the same function again
continue;
}
}
else if (0 < tcase.bthrow) {
rw_assert (caught == expected, 0, tcase.line,
"line %d. %{$FUNCALL} %{?}expected %s, caught %s"
"%{:}unexpectedly caught %s%{;}",
__LINE__, 0 != expected, expected, caught, caught);
}
break;
}
// no exception expected
const std::size_t expect_throws = 0;
rw_assert (expect_throws == throw_count, 0, tcase.line,
"line %d: %{$FUNCALL}: expected exactly 0 %s exception "
"while the swap, got %zu",
__LINE__, exceptions [1], throw_count);
// disable bad_alloc exceptions
*pst->throw_at_calls_ [0] = 0;
pal->throw_at_calls_ [pal->m_allocate] = 0;
}
/**************************************************************************/
template <class T>
std::allocator<T>
make_alloc (SharedAlloc&, std::allocator<T>*) {
return std::allocator<T>();
}
template <class T, class Types>
UserAlloc<T, Types>
make_alloc (SharedAlloc &shal, UserAlloc<T, Types>*) {
return UserAlloc<T, Types>(&shal);
}
/**************************************************************************/
template <class T, class Allocator>
void test_swap (T*, Allocator*,
const ContainerTestCaseData<T> &tdata)
{
if (Swap (cont_cont) == tdata.func_.which_) {
test_std_swap ();
return;
}
SharedAlloc sa1;
Allocator a1 = make_alloc(sa1, (Allocator*)0);
// test swap using the same allocator objects
test_swap ((T*)0, a1, a1, tdata);
SharedAlloc sa2;
Allocator a2 = make_alloc(sa2, (Allocator*)0);
if (a1 != a2) {
// test swap using different allocator objects
test_swap ((T*)0, a1, a2, tdata);
}
}
/**************************************************************************/
DEFINE_CONTAINER_TEST_FUNCTIONS (test_swap);
int main (int argc, char** argv)
{
static const ContainerTest
tests [] = {
#undef TEST
#define TEST(sig) { \
Swap (sig), sig ## _test_cases, \
sizeof sig ## _test_cases / sizeof *sig ## _test_cases, \
}
TEST (cont),
TEST (cont_cont)
};
const std::size_t test_count = sizeof tests / sizeof *tests;
const int status =
rw_run_cont_test (argc, argv, __FILE__,
"lib.list.special",
ContainerIds::List,
test_swap_func_array, tests, test_count);
return status;
}

View File

@@ -0,0 +1,278 @@
/************************************************************************
*
* 23.vector.allocator.cpp:
*
* Test exercising vector specialized on a user-defined allocator
* with a user-defined pointer type.
*
* $Id: 23.vector.allocator.cpp 588744 2007-10-26 18:51:03Z 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 2007 Rogue Wave Software, Inc.
*
**************************************************************************/
// disable debug iterators to prevent compilation errors
#include <rw/_config.h>
#ifndef _RWSTD_NO_DEBUG_ITER
# define _RWSTD_NO_DEBUG_ITER
#endif // _RWSTD_NO_DEBUG_ITER
#include <memory>
#include <vector>
#include <cstddef> // for ptrdiff_t, size_t
#include <driver.h>
/**************************************************************************/
// DESCRIPTION:
// Test instantiates std::vector on a user-defined type, user-defined
// allocator and a user-defined pointer type, making sure that everything
// still compiles and runs with expected results
// Note: 20.1.5, p2, Allocator requirements specifies that the type
// std::allocator<T>::pointer be a "pointer to T", which might
// make this test case not well-defined; it is expected that
// this will be changed in a future revision of the Standard
// user-defined pointer type
template <class T>
struct Pointer
{
typedef T value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::random_access_iterator_tag iterator_category;
Pointer (): offset_ (0) { }
Pointer (const Pointer &rhs)
: offset_ (rhs.offset_) { }
Pointer (difference_type off, int) : offset_ (off) {}
reference operator* () const {
return *_RWSTD_REINTERPRET_CAST (pointer, offset_);
}
bool operator== (const Pointer &rhs) const {
return offset_ == rhs.offset_;
}
bool operator!= (const Pointer &rhs) const {
return !operator== (rhs);
}
bool operator< (const Pointer &rhs) const {
return offset_ < rhs.offset_;
}
bool operator<= (const Pointer &rhs) const {
return !(*this > rhs);
}
bool operator> (const Pointer &rhs) const {
return rhs < *this;
}
bool operator>= (const Pointer &rhs) const {
return !(*this < rhs);
}
Pointer& operator++ () {
pointer ptr = _RWSTD_REINTERPRET_CAST (pointer, offset_);
offset_ = _RWSTD_REINTERPRET_CAST (difference_type, ++ptr);
return *this;
}
Pointer& operator-- () {
pointer ptr = _RWSTD_REINTERPRET_CAST (pointer, offset_);
offset_ = _RWSTD_REINTERPRET_CAST (difference_type, --ptr);
return *this;
}
Pointer& operator+= (difference_type i) {
pointer ptr = _RWSTD_REINTERPRET_CAST (pointer, offset_);
offset_ = _RWSTD_REINTERPRET_CAST (difference_type, ptr += i);
return *this;
}
Pointer& operator-= (difference_type i) {
return *this += -i;
}
Pointer operator+ (difference_type i) const {
return Pointer (*this) += i;
}
Pointer operator- (difference_type i) const {
return Pointer (*this) -= i;
}
difference_type operator- (const Pointer &rhs) const {
pointer p1 = _RWSTD_REINTERPRET_CAST (pointer, offset_);
pointer p2 = _RWSTD_REINTERPRET_CAST (pointer, rhs.offset_);
return p1 - p2;
}
difference_type offset_;
private:
// deliberately not defined to detect their use
void operator++ (int);
void operator-- (int);
};
/**************************************************************************/
// user-defined allocator
template <class T>
class Allocator
{
public:
typedef T value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef Pointer<T> pointer;
typedef const Pointer<T> const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::random_access_iterator_tag iterator_category;
pointer address (reference r) const {
return pointer (_RWSTD_REINTERPRET_CAST (difference_type, &r), 1);
}
const_pointer address (const_reference r) const {
return const_pointer (_RWSTD_REINTERPRET_CAST (difference_type, &r),
1);
}
Allocator () throw () {}
template <class U>
Allocator (const Allocator<U>&) throw () {}
pointer allocate (size_type n, const void* = 0) {
void* const ptr = operator new (n * sizeof (T));
return pointer (_RWSTD_REINTERPRET_CAST (difference_type, ptr), 1);
}
void deallocate (pointer ptr, size_type) {
operator delete (_RWSTD_REINTERPRET_CAST (void*, ptr.offset_));
}
void construct (pointer ptr, const_reference val) {
new (_RWSTD_REINTERPRET_CAST (void*, ptr.offset_)) value_type (val);
}
void destroy (pointer ptr) {
_RWSTD_REINTERPRET_CAST (T*, ptr.offset_)->~value_type ();
}
size_type max_size () const throw () {
return size_type (-1) / sizeof (T);
}
template <class U>
struct rebind { typedef Allocator<U> other; };
bool operator== (const Allocator&) const {
return 1;
}
bool operator!= (const Allocator &rhs) const {
return !operator== (rhs);
}
};
/**************************************************************************/
// user-defined type
struct MyClass
{
int i_;
int j_;
};
/**************************************************************************/
#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
// explicitly instantiate to better exercise the template
template class std::vector<MyClass, Allocator<MyClass> >;
#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
static int
run_test (int, char**)
{
rw_warn (0, 0, __LINE__, "debugging iterators disabled");
typedef std::vector<MyClass, Allocator<MyClass> > Vector;
const Vector::size_type nelems = 256;
const MyClass value = { 0, 0 };
Vector v (nelems, value);
rw_assert (nelems == v.size (), 0, __LINE__,
"vector(%zu, value_type).size() == %1$zu, got %zu",
nelems, v.size ());
Vector ().swap (v);
rw_assert (0 == v.size (), 0, __LINE__,
"vector().swap(vector&).size() == 0, got %zu",
v.size ());
Vector::size_type i;
for (i = 0; i != nelems; ++i)
v.push_back (value);
rw_assert (nelems == v.size (), 0, __LINE__,
"vector::size() == %1$zu, got %zu",
nelems, v.size ());
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.vector",
"with a user-defined allocator and pointer types",
run_test,
"",
(void*)0);
}

View File

@@ -0,0 +1,192 @@
/***************************************************************************
*
* 23.vector.capacity.cpp - test exercising [lib.vector.capacity]
*
* $Id: 23.vector.capacity.cpp 510071 2007-02-21 15:58:53Z 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 2006 Rogue Wave Software.
*
**************************************************************************/
#include <stdexcept> // for length_error
#include <vector> // for vector
#include <alg_test.h>
#include <rw_value.h> // for UserClass
#include <driver.h>
/**************************************************************************/
static unsigned rw_opt_nloops = 1024;
static int rw_opt_no_exceptions;
/**************************************************************************/
typedef std::vector<UserClass, std::allocator<UserClass> > Vector;
// exercise vector<>::capacity() and vector<>::reserve()
// focus on the complexity of the function
void test_capacity (Vector::size_type nelems)
{
// create a vector with nelems elements
Vector v (nelems);
const Vector::size_type cap = v.capacity ();
const Vector::size_type size = v.size ();
Vector::const_pointer begin = size ? &v [0] : 0;
UserClass::reset_totals ();
// call reserve capacity that is less than or equal to the current value
v.reserve (cap / 2);
// verify that the call had no effect
rw_assert (v.capacity () == cap, 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu); capacity() == %zu, "
"got %zu", nelems, cap / 2, cap, v.capacity ());
if (size) {
// verify that no reallocation took place
rw_assert (begin == &v [0], 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu) unexpectedly "
"reallocated", nelems, cap / 2);
}
// call reserve the same capacity as the current value
v.reserve (cap);
// verify that the call had no effect
rw_assert (v.capacity () == cap, 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu); capacity() == %zu, "
"got %zu", nelems, cap / 2, cap, v.capacity ());
if (size) {
// verify that no reallocation took place
rw_assert (begin == &v [0], 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu) unexpectedly "
"reallocated", nelems, cap / 2);
}
// call reserve with a larger capacity then is available
v.reserve (cap + 1);
// 23.2.4.2, p2: After reserve (), capacity () is greater or equal
// to the reserve value if reallocation happens
rw_assert (v.capacity () >= cap + 1, 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu); capacity() > %zu, got %zu",
nelems, cap + 1, cap, v.capacity ());
// 23.2.3.2, p3: reserve shall not change the size of the sequence
rw_assert (v.size () == size, 0, __LINE__,
"vector<UserClass>(%zu).reserve(); size() == %zu, got %zu",
nelems, size, v.size ());
// 23.2.3.2, p3: takes at most linear time in the size of the sequence
rw_assert (UserClass::n_total_copy_ctor_ == v.size (), 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu) complexity: "
"copy ctor called %zu times when size() = %zu",
nelems, cap + 1, UserClass::n_total_copy_ctor_, v.size ());
if (size) {
begin = &v [0];
// verify 23.2.4.2, p5: no reallocation takes place until
// the size of the container would exceed its capacity
for (Vector::size_type i = 0; i != v.capacity () - size; ++i) {
v.push_back (UserClass ());
rw_assert (begin == &v [0], 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu); insertion of "
"element %zu unexpectedly reallocated; size() = %zu",
nelems, cap + 1, v.size ());
}
}
if (rw_opt_no_exceptions)
return;
#ifndef _RWSTD_NO_EXCEPTIONS
// exercise reserve exception
const char *caught = 0;
Vector::size_type too_much = v.max_size () + 1;
if (!too_much)
too_much = v.max_size ();
try {
v.reserve (too_much);
}
catch (std::length_error) {
caught = "";
}
catch (...) {
caught = "unknown exception";
}
rw_assert (0 != caught, 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu) "
"expected exception not thrown",
nelems, too_much);
if (caught)
rw_assert ('\0' == *caught, 0, __LINE__,
"vector<UserClass>(%zu).reserve(%zu) "
"expected length_error, got %s",
nelems, too_much, caught);
#endif // _RWSTD_NO_EXCEPTIONS
}
/**************************************************************************/
static int
run_test (int /* argc */, char** /* argv */)
{
rw_info (0, 0, 0, "std::vector<UserClass>::capacity() const");
rw_info (0, 0, 0, "std::vector<UserClass>::reserve(size_type)");
const Vector::size_type max_elems = Vector::size_type (rw_opt_nloops);
rw_note (0 == rw_opt_no_exceptions, 0, 0, "exception test disabled");
for (Vector::size_type i = 0; i < max_elems; ++i) {
test_capacity (i);
}
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.vector.capacity",
0 /* no comment */,
run_test,
"|-no-exceptions# "
"|-nloops#0",
&rw_opt_no_exceptions,
&rw_opt_nloops);
}

View File

@@ -0,0 +1,805 @@
/***************************************************************************
*
* 23.vector.cons.cpp - test exercising [lib.vector.cons]
*
* $Id: 23.vector.cons.cpp 550991 2007-06-26 23:58:07Z sebor $
*
***************************************************************************
*
* 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 2006 Rogue Wave Software.
*
**************************************************************************/
#include <memory> // for placement operator new()
#include <vector> // for vector
#include <cstddef> // for size_t
#include <alg_test.h>
#include <rw_value.h> // for UserClass
#include <driver.h>
#include <rw_new.h>
/**************************************************************************/
static unsigned rw_opt_nloops;
static int rw_opt_no_int_spec;
static int rw_opt_no_short_spec;
static int rw_opt_no_types;
static int rw_opt_no_signatures;
static int rw_opt_no_ctors;
/**************************************************************************/
template <class RandomAccessIterator,
class T,
class Reference,
class Pointer,
class Difference>
struct test_iterator
{
test_iterator ();
};
/**************************************************************************/
// outlined to prevent gcc -Winline warnings
template <class RandomAccessIterator,
class T,
class Reference,
class Pointer,
class Difference>
test_iterator<RandomAccessIterator, T, Reference, Pointer, Difference>::
test_iterator ()
{
static int i; // zeroed out
if (++i) // prevent "unreachable code" warnings
return; // compile only
// exercise RandomAccessIterator requirements
RandomAccessIterator it = RandomAccessIterator ();
RandomAccessIterator it_cpy (it);
Difference d (it - it);
RandomAccessIterator &it_ref1 = ++it;
const RandomAccessIterator &it_ref2 = it++;
RandomAccessIterator &it_ref3 = --it;
const RandomAccessIterator &it_ref4 = it--;
RandomAccessIterator &it_ref5 = it += 1;
it_cpy = it + d;
it_cpy = d + it;
RandomAccessIterator &it_ref6 = it -= 1;
it_cpy = it - d;
T t (it [d]);
Reference ref1 (*it);
Reference ref2 (*it++);
bool b (it == it);
b = it != it;
b = it > it;
b = it >= it;
b = it <= it;
_RWSTD_UNUSED (it);
_RWSTD_UNUSED (it_cpy);
_RWSTD_UNUSED (it_ref1);
_RWSTD_UNUSED (it_ref2);
_RWSTD_UNUSED (it_ref3);
_RWSTD_UNUSED (it_ref4);
_RWSTD_UNUSED (it_ref5);
_RWSTD_UNUSED (it_ref6);
_RWSTD_UNUSED (d);
_RWSTD_UNUSED (t);
_RWSTD_UNUSED (ref1);
_RWSTD_UNUSED (ref2);
_RWSTD_UNUSED (b);
}
/***************************************************************************/
// verify that nested types are properly defined
template <class Vector, class T, class Allocator>
void test_types (Vector*, T*, Allocator)
{
#define TEST_TYPE(T, vectorT) { \
T *t = (typename Vector::vectorT*)0; \
_RWSTD_UNUSED (t); \
}
#define TEST_REFERENCE(T, vectorT) { \
typename Vector::value_type v; \
T t = v; \
_RWSTD_UNUSED (t); \
}
// verify nested types
TEST_TYPE (T, value_type);
TEST_TYPE (Allocator, allocator_type);
TEST_TYPE (typename Allocator::pointer, pointer);
TEST_TYPE (typename Allocator::const_pointer, const_pointer);
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
typedef std::reverse_iterator<typename Vector::iterator>
ReverseIterator;
typedef std::reverse_iterator<typename Vector::const_iterator>
ConstReverseIterator;
#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
typedef std::reverse_iterator<typename Vector::iterator,
std::random_access_iterator_tag, T /*non-const T&, non-const T* */>
ReverseIterator;
typedef std::reverse_iterator<typename Vector::const_iterator,
std::random_access_iterator_tag, T, const T&, const T*>
ConstReverseIterator;
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
TEST_TYPE (ReverseIterator, reverse_iterator);
TEST_TYPE (ConstReverseIterator, const_reverse_iterator);
test_iterator<typename Vector::iterator, T, T&, T*, std::ptrdiff_t>
ti; // exercise iterator requirements
test_iterator<typename Vector::const_iterator, T, const T&, const T*,
std::ptrdiff_t>
tci; // exercise iterator requirements
test_iterator<ReverseIterator, T, T&, T*, std::ptrdiff_t>
tri; // exercise iterator requirements
test_iterator<ConstReverseIterator, T, const T&, const T*, std::ptrdiff_t>
tcri; // exercise iterator requirements
_RWSTD_UNUSED (ti); _RWSTD_UNUSED (tci);
_RWSTD_UNUSED (tri); _RWSTD_UNUSED (tcri);
// special treatment
TEST_REFERENCE (typename Allocator::reference, reference);
TEST_REFERENCE (typename Allocator::const_reference, const_reference);
}
/**************************************************************************/
// verify that member functions are properly defined
template <class Vector, class T, class Allocator>
void test_signatures (Vector*, T*, Allocator)
{
// 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 (Vector::*pf) arg_list = &Vector::name; \
_RWSTD_UNUSED (pf); \
} while (0)
MEMFUN (Vector&, operator=, (const Vector&));
// helpers to work around a SunPro 5.3 bug (see PR #25972)
typedef typename Vector::size_type SizeType;
typedef typename Vector::value_type ValueType;
typedef typename Vector::iterator Iterator;
// verify signatures of iterator accessors
MEMFUN (typename Vector::iterator, begin, ());
MEMFUN (typename Vector::const_iterator, begin, () const);
MEMFUN (typename Vector::iterator, end, ());
MEMFUN (typename Vector::const_iterator, end, () const);
// verify signatures of reverse iterator accessors
MEMFUN (typename Vector::reverse_iterator, rbegin, ());
MEMFUN (typename Vector::const_reverse_iterator, rbegin, () const);
MEMFUN (typename Vector::reverse_iterator, rend, ());
MEMFUN (typename Vector::const_reverse_iterator, rend, () const);
// verify signatures of capacity accessors
MEMFUN (SizeType, size, () const);
MEMFUN (SizeType, max_size, () const);
MEMFUN (void, resize, (SizeType, ValueType));
MEMFUN (SizeType, capacity, () const);
MEMFUN (bool, empty, () const);
MEMFUN (void, reserve, (SizeType));
// verify signature of the element access functions
MEMFUN (const T&, operator[], (SizeType) const);
MEMFUN (T&, operator[], (SizeType));
MEMFUN (const T&, at, (SizeType) const);
MEMFUN (T&, at, (SizeType));
MEMFUN (const T&, front, () const);
MEMFUN (T&, front, ());
MEMFUN (const T&, back, () const);
MEMFUN (T&, back, ());
// verify signatures of modifiers
MEMFUN (void, push_back, (const T&));
MEMFUN (void, pop_back, ());
MEMFUN (Iterator, insert, (Iterator, const T&));
MEMFUN (void, insert, (Iterator, SizeType, const T&));
#if !defined (_MSC_VER) || _MSC_VER >= 1300
// member function template insert
MEMFUN (void, insert, (Iterator, InputIter<T>, InputIter<T>));
#endif // !defined (_MSC_VER) || _MSC_VER >= 1300
MEMFUN (Iterator, erase, (Iterator));
MEMFUN (Iterator, erase, (Iterator, Iterator));
MEMFUN (void, swap, (Vector&));
MEMFUN (void, clear, ());
#if !defined (_MSC_VER) || _MSC_VER > 1300
#define FUN(result, name, arg_list) do { \
result (*pf) arg_list = &name; \
_RWSTD_UNUSED (pf); \
} while (0)
// verify signatures of non-member functions
FUN (bool, std::operator==, (const Vector&, const Vector&));
FUN (bool, std::operator<, (const Vector&, const Vector&));
FUN (bool, std::operator!=, (const Vector&, const Vector&));
FUN (bool, std::operator>, (const Vector&, const Vector&));
FUN (bool, std::operator>=, (const Vector&, const Vector&));
FUN (bool, std::operator<=, (const Vector&, const Vector&));
FUN (void, std::swap, (Vector&, Vector&));
#else // MSVC <= 7.0
// working around a bug in MSVC 7 and prior (see PR #26625)
if (0 /* compile only */) {
Vector *pv = 0;
const Vector *pcv = 0;
bool b;
b = std::operator== (*pcv, *pcv);
b = std::operator< (*pcv, *pcv);
b = std::operator!= (*pcv, *pcv);
b = std::operator> (*pcv, *pcv);
b = std::operator>= (*pcv, *pcv);
b = std::operator<= (*pcv, *pcv);
std::swap (*pv, *pv);
}
#endif // MSVC <= 7.0
}
/**************************************************************************/
// exercise [lib.vector.cons] and vector<>::operator=()
// focus on the correct construction and destruction of values
void test_ctors ()
{
typedef std::vector<UserClass, std::allocator<UserClass> > Vector;
if (1) {
rw_info (0, 0, 0,
"std::vector<UserClass>::vector(size_type, "
"const_reference, const allocator_type&)");
rw_info (0, 0, 0, "std::vector<UserClass>::vector(const vector&)");
// reset function call counters
UserClass::reset_totals ();
// total number of objects of type UserClass in existence
const std::size_t x_count = UserClass::count_;
for (Vector::size_type i = 0; i != rw_opt_nloops; ++i) {
rw_assert (UserClass::count_ == x_count, 0, __LINE__,
"vector<UserClass>::vector(size_type, const_reference); "
"leaked %zu objects of value_type",
UserClass::count_ - x_count);
// reset function call counters
UserClass::reset_totals ();
const UserClass val;
// initialize a vector with `i' copies of `val'
const Vector v0 (i, val);
rw_assert ( i == v0.size ()
&& v0.begin () + i == v0.end ()
&& v0.rbegin () + i == v0.rend (),
0, __LINE__,
"vector<UserClass>::vector(size_type, const_reference)");
// verify that the vector ctor calls only copy ctor
// of UserClass and anly the given number of times each
rw_assert (UserClass::is_total (i + 1, 1, i, 0, 0, 0), 0, __LINE__,
"vector<UserClass>::vector(size_type, const_reference); "
"called default/copy ctor and operator=() %zu, %zu, "
"and %zu times, respectively, 0, %zu, 0 expected",
UserClass::n_total_def_ctor_ - 1,
UserClass::n_total_copy_ctor_,
UserClass::n_total_op_assign_, i);
// create a copy
Vector v1 (v0);
rw_assert ( i == v1.size ()
&& v1.begin () + i == v1.end ()
&& v1.rbegin () + i == v1.rend (),
0, __LINE__,
"vector<UserClass>::vector(const vector&)");
// verify that the vector copy ctor calls only copy ctor
// of UserClass and anly the given number of times each
rw_assert (UserClass::is_total (2 * i + 1, 1, 2 * i, 0, 0, 0),
0, __LINE__,
"vector<UserClass>::vector(size_type, const_reference); "
"called default/copy ctor and operator=() %zu, %zu, "
"and %zu times, respectively, 0, %zu, 0 expected",
UserClass::n_total_def_ctor_ - 1,
UserClass::n_total_copy_ctor_,
UserClass::n_total_op_assign_, i);
// exercise vector<>operator=(const vector&)
Vector v2 (i, val);
for (Vector::size_type j = 0; j != rw_opt_nloops; ++j) {
Vector v3 (j, val);
// assign a vector (of a possibly unequal size)
v3 = v2;
rw_assert (v3.size () == v2.size (), 0, __LINE__,
"%zu. vector<UserClass>::operator=(const vector&)",
j);
rw_assert (v3 == v2, 0, __LINE__,
"%zu. vector<UserClass>::operator=(const vector&)",
j);
}
#ifndef _RWSTD_NO_EXCEPTIONS
// exercise vector exception safety
bool thrown = false;
// create a suitably aligned buffer in which to construct
// the vector object
union {
void *pad;
char buf [sizeof (Vector)];
} buf = { 0 };
std::size_t x_count_save = UserClass::count_;
try {
// have UserClass copy ctor throw an exception during
// the copying of the last value
UserClass::copy_ctor_throw_count_ =
UserClass::n_total_copy_ctor_ + i;
// create a vector object, throw an exception
// expect vector ctor to destroy any values
// constructed prior to throwing the exception
// and to free all already allocated memory
// use placement new to prevent vector destruction
// at scope exit (the object should be destroyed
// during stack unwinding instead)
Vector *p = new (&buf.buf) Vector (i, val);
// destroy explicitly if ctor doesn't propagate exception
#if !defined (__HP_aCC) || _RWSTD_HP_aCC_MINOR > 3800
p->~Vector ();
#else
// work around aCC bug (see PR #25356)
p->~vector ();
#endif // HP aCC
}
catch (...) {
thrown = true;
}
// no exception thrown if (i == 0), no elements constructed
rw_assert (i == 0 || thrown, 0, __LINE__,
"logic error: failed to throw");
rw_assert (x_count_save == UserClass::count_, 0, __LINE__,
"vector<UserClass>::vector(size_type, const_reference) "
"leaked %zu value(s) of %zu after an exception",
UserClass::count_ - x_count_save, i);
// exercise vector<>::vector(const vector&)
thrown = false;
x_count_save = UserClass::count_;
try {
// have UserClass copy ctor throw an exception during
// the copying of the last value
UserClass::copy_ctor_throw_count_ =
UserClass::n_total_copy_ctor_ + i;
// use placement new to prevent vector destruction
// at scope exit (the object should be destroyed
// during stack unwinding instead)
Vector *p = new (&buf) Vector (v1);
// destroy explicitly if ctor doesn't propagate exception
#if !defined (__HP_aCC) || _RWSTD_HP_aCC_MINOR > 3800
p->~Vector ();
#else
// work around aCC bug (see PR #25356)
p->~vector ();
#endif // HP aCC
}
catch (...) {
// vector should have been destroyed
thrown = true;
}
// no exception thrown if (i == 0), no elements constructed
rw_assert(i == 0 || thrown, 0, __LINE__,
"logic error: failed to throw");
rw_assert (x_count_save == UserClass::count_, 0, __LINE__,
"vector<UserClass>::vector(const vector&) leaked "
"%zu value(s) of %zu after an exception",
UserClass::count_ - x_count_save, i);
// disable exceptions
UserClass::copy_ctor_throw_count_ = std::size_t (-1);
// remember v1's size and capacity
const Vector::size_type v1_size = v1.size ();
const Vector::size_type v1_cap = v1.capacity ();
// create and initialize vector with some values
// make sure v3's capacity is greater than that of v1
// (otherwise the assignment isn't exception safe since
// it simply overwrites existing values for efficiency)
const Vector v3 (v1_cap * 2, val);
// exrecise vector<>::operator=(const vector&)
thrown = false;
x_count_save = UserClass::count_;
try {
// have UserClass copy ctor throw an exception during
// the copying of the last value
UserClass::copy_ctor_throw_count_ =
UserClass::n_total_copy_ctor_ + v3.size ();
// assign over the existing elements, the last copy ctor or
// operator=() throws, destroying all values assigned so far
v1 = v3;
}
catch (...) {
// original vector must remain unchanged
thrown = true;
}
// disable exceptions
UserClass::copy_ctor_throw_count_ = std::size_t (-1);
rw_assert (i == 0 || thrown, 0, __LINE__,
"logic error: failed to throw");
// verify that no values leaked
rw_assert (x_count_save == UserClass::count_, 0, __LINE__,
"vector<UserClass>::vector(const vector&) leaked "
"%zu value(s) of %zu after an exception",
UserClass::count_ - x_count_save, i);
// verify that the size of the left hand size operand
// of the assignment hasn't changed
rw_assert (v1.size () == v1_size && v1.capacity () == v1_cap,
0, __LINE__, "vector<UserClass>::operator="
"(const vector&) changed size of *this from "
"%zu to %zu after exception",
i / 2, v3.size ());
#endif // _RWSTD_NO_EXCEPTIONS
// vectors go out of scope, must destroy all elements
}
}
}
// exercise [lib.vector.cons]
template <class Vector, class T, class Alloc>
void test_ctors (Vector*, T*, Alloc alloc)
{
if (1) {
rw_info (0, 0, 0,
"std::vector<UserClass>::vector(const allocator_type&)");
// verify default ctor arguments
Vector v0;
Vector v1 (alloc);
rw_assert ( 0 == v0.size ()
&& v0.empty () && v0.begin () == v0.end ()
&& v0.rbegin () == v0.rend (), 0, __LINE__,
("vector<UserClass>::vector()"));
rw_assert ( 0 == v1.size ()
&& v1.empty () && v1.begin () == v1.end ()
&& v1.rbegin () == v1.rend (), 0, __LINE__,
"vector<UserClass>::vector()");
}
if (1) {
rw_info (0, 0, 0,
"std::vector<UserClass>::vector(size_type, "
"const_reference, const allocator_type&)");
for (typename Vector::size_type i = 0; i != rw_opt_nloops; ++i) {
const T val = i;
Vector v0 (i, val);
Vector v1 (i, val, alloc);
rw_assert ( i == v0.size ()
&& v0.begin () + i == v0.end ()
&& v0.rbegin () + i == v0.rend (),
0, __LINE__,
"vector<UserClass>::vector"
"(size_type, const_reference)");
rw_assert ( i == v1.size ()
&& v1.begin () + i == v1.end ()
&& v1.rbegin () + i == v1.rend (),
0, __LINE__,
"vector<UserClass>::vector(size_type, "
"const_reference, const allocator_type&)");
bool success = true;
for (typename Vector::size_type j = 0; j != i; ++j) {
if (!(success = v0 [j] == val))
break;
if (!(success = v1 [j] == val))
break;
}
rw_assert (success, 0, __LINE__,
"vector<UserClass>::vector(size_type, const_reference); "
"all elements initialized");
}
}
#if !defined (_MSC_VER) || _MSC_VER >= 1300
if (1) {
rw_info (0, 0, 0,
"template <class InputIterator> std::vector<UserClass>::vector"
"(InputIterator, InputIterator)");
bool success = true;
// allocate nloops elements, do not initialize
typename Vector::value_type *vals = alloc.allocate (rw_opt_nloops);
for (typename Vector::size_type i = 0; i != rw_opt_nloops; ++i) {
// construct an element at then end of array
alloc.construct (vals + i, i);
// verify ctor with a strict InputIterator
InputIter<T> first (vals, vals, vals + i);
InputIter<T> last (vals + i, vals + i, vals + i);
const Vector v0 (first, last);
// reset iterators since they are single-pass and their
// copies have been passed through by the ctor above
first = InputIter<T>(vals, vals, vals + i);
last = InputIter<T>(vals + i, vals + i, vals + i);
const Vector v1 (first, last, alloc);
if ( i != v0.size ()
|| (!(i && !v0.empty () || !i && v0.empty ()))
|| (i != v1.size ())
|| (!(i && !v1.empty () || !i && v1.empty ())))
success = false;
// verify size() and empty()
rw_assert (i == v0.size (), 0, __LINE__,
"size () == %zu, got %zu", i, v0.size ());
rw_assert (i && !v0.empty () || !i && v0.empty (),
0, __LINE__, "size () == %zu, empty () == %d",
v0.size (), v0.empty ());
rw_assert (i == v1.size (), 0, __LINE__,
"size () == %zu, got %zu", i, v1.size ());
rw_assert (i && !v1.empty () || !i && v1.empty (),
0, __LINE__, "size () == %zu, empty () == %d",
v1.size (), v1.empty ());
}
rw_assert (success, 0, __LINE__,
"template <class InputIterator> "
"std::vector<UserClass>::vector"
"(InputIterator, InputIterator)");
// destroy and deallocate...
for (typename Vector::size_type j = 0; j != rw_opt_nloops; ++j)
alloc.destroy (vals + j);
alloc.deallocate (vals, rw_opt_nloops);
}
#endif // !defined (_MSC_VER) || _MSC_VER >= 1300
}
/**************************************************************************/
static int
run_test (int /* argc */, char** /* argv */)
{
static int int_noted = 0;
static int short_noted = 0;
static int types_noted = 0;
static int sign_noted = 0;
static int ctors_noted = 0;
#ifndef _RWSTD_NO_EXCEPTIONS
try {
// throw an exception to initialize the lib (allocates
// memory that's never deallocated; shows up as leaks)
_RW::__rw_throw (_RWSTD_ERROR_LOGIC_ERROR, "", "");
}
catch (...) {
}
#endif // _RWSTD_NO_EXCEPTIONS
// for convenience (in case default template arguments are disabled)
#define VECTOR(T) std::vector<T, std::allocator<T> >
#define TEST(what, T) \
do { \
/* establish a checkpoint for memory leaks */ \
rwt_check_leaks (0, 0); \
test_ ##what ((VECTOR (T)*)0, (T*)0, std::allocator<T>()); \
/* verify that no memory leaked */ \
std::size_t nbytes; \
const std::size_t nblocks = rwt_check_leaks (&nbytes, 0); \
rw_assert (!nblocks && !nbytes, 0, __LINE__, \
#what " test leaked %lu bytes in %lu blocks", \
nbytes, nblocks); \
} while (0)
if (rw_opt_no_int_spec) {
rw_note (int_noted++, 0, __LINE__,
"int specializations test disabled.");
}
else {
// exercise vector and its default template argument
if (rw_opt_no_types) {
rw_note (types_noted++, 0, __LINE__, "Types test disabled.");
}
else {
TEST (types, int);
}
if (rw_opt_no_signatures) {
rw_note (sign_noted++, 0, __LINE__, "Signatures test disabled.");
}
else {
TEST (signatures, int);
}
if (rw_opt_no_ctors) {
rw_note (ctors_noted++, 0, __LINE__, "Ctors test disabled.");
}
else {
TEST (ctors, int);
}
}
// exercise vector with a template argument other than the default
#undef VECTOR
#define VECTOR(T, A) std::vector<T, A<T> >
#undef TEST
#define TEST(what,T,A) test_ ##what ((VECTOR (T, A)*)0, (T*)0, A<T>())
if (rw_opt_no_short_spec) {
rw_note (short_noted++, 0, __LINE__,
"short specializations test disabled.");
}
else {
if (rw_opt_no_types) {
rw_note (types_noted++, 0, __LINE__, "Types test disabled.");
}
else {
TEST (types, short, std::allocator);
}
if (rw_opt_no_signatures) {
rw_note (sign_noted++, 0, __LINE__, "Signatures test disabled.");
}
else {
TEST (signatures, short, std::allocator);
}
if (rw_opt_no_ctors) {
rw_note (ctors_noted++, 0, __LINE__, "Ctors test disabled.");
}
else {
TEST (ctors, short, std::allocator);
}
}
if (rw_opt_no_ctors) {
rw_note (ctors_noted++, 0, __LINE__, "Ctors test disabled.");
}
else {
test_ctors ();
}
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
"lib.vector.cons",
0 /* no comment */,
run_test,
"|-nloops#1 "
"|-no-int_specializations# "
"|-no-short_specializations# "
"|-no-types# "
"|-no-signatures# "
"|-no-ctors#",
&rw_opt_nloops,
&rw_opt_no_int_spec,
&rw_opt_no_short_spec,
&rw_opt_no_types,
&rw_opt_no_signatures,
&rw_opt_no_ctors);
}

File diff suppressed because it is too large Load Diff