first commit
This commit is contained in:
805
extern/stdcxx/4.2.1/tests/containers/23.vector.cons.cpp
vendored
Normal file
805
extern/stdcxx/4.2.1/tests/containers/23.vector.cons.cpp
vendored
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user