testsuite_allocator.h: New file.
2002-11-25 Stephen M. Webb <stephen@bregmasoft.com> * testsuite/testsuite_allocator.h: New file. * testsuite/testsuite_allocator.cc: New file. * testsuite/Makefile.am: Added testsuite_allocator to test library. * testsuite/testsuite_hooks.h: Added more detailed tracker objects gnu_copy_constructor, gnu_assignment_operator, and gnu_destructor. * testsuite/testsuite_hooks.cc: Added new static objects definitions. * testsuite/23_containers/vector_capacity.cc: Added reserve() tests. * testsuite/23_containers/vector_ctor.cc: Added a plethora of tests. * testsuite/23_containers/deque_ctor.cc: Added a slew of new tests. From-SVN: r59484
This commit is contained in:
parent
83bbd9b6c0
commit
162c7cd92d
|
@ -1,3 +1,15 @@
|
|||
2002-11-25 Stephen M. Webb <stephen@bregmasoft.com>
|
||||
|
||||
* testsuite/testsuite_allocator.h: New file.
|
||||
* testsuite/testsuite_allocator.cc: New file.
|
||||
* testsuite/Makefile.am: Added testsuite_allocator to test library.
|
||||
* testsuite/testsuite_hooks.h: Added more detailed tracker objects
|
||||
gnu_copy_constructor, gnu_assignment_operator, and gnu_destructor.
|
||||
* testsuite/testsuite_hooks.cc: Added new static objects definitions.
|
||||
* testsuite/23_containers/vector_capacity.cc: Added reserve() tests.
|
||||
* testsuite/23_containers/vector_ctor.cc: Added a plethora of tests.
|
||||
* testsuite/23_containers/deque_ctor.cc: Added a slew of new tests.
|
||||
|
||||
2002-11-25 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* libsupc++/Makefile.am (sources): Add guard.cc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
dnl aclocal.m4 generated automatically by aclocal 1.4-p6
|
||||
dnl aclocal.m4 generated automatically by aclocal 1.4-p5
|
||||
|
||||
dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
|
@ -2262,7 +2262,7 @@ AC_MSG_RESULT($enable_symvers)
|
|||
])
|
||||
|
||||
|
||||
# isc-posix.m4 serial 2 (gettext-0.11.2)
|
||||
# isc-posix.m4 serial 1 (gettext-0.10.40)
|
||||
dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
|
||||
dnl This file is free software, distributed under the terms of the GNU
|
||||
dnl General Public License. As a special exception to the GNU General
|
||||
|
@ -2270,8 +2270,6 @@ dnl Public License, this file may be distributed as part of a program
|
|||
dnl that contains a configuration script generated by Autoconf, under
|
||||
dnl the same distribution terms as the rest of that program.
|
||||
|
||||
# This file is not needed with autoconf-2.53 and newer. Remove it in 2005.
|
||||
|
||||
# This test replaces the one in autoconf.
|
||||
# Currently this macro should have the same name as the autoconf macro
|
||||
# because gettext's gettext.m4 (distributed in the automake package)
|
||||
|
@ -2332,8 +2330,7 @@ dnl Usage:
|
|||
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
|
||||
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])
|
||||
[AC_REQUIRE([AC_PROG_INSTALL])
|
||||
PACKAGE=[$1]
|
||||
AC_SUBST(PACKAGE)
|
||||
VERSION=[$2]
|
||||
|
@ -2349,42 +2346,13 @@ AC_REQUIRE([AM_SANITY_CHECK])
|
|||
AC_REQUIRE([AC_ARG_PROGRAM])
|
||||
dnl FIXME This is truly gross.
|
||||
missing_dir=`cd $ac_aux_dir && pwd`
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir)
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])])
|
||||
|
||||
# Copyright 2002 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION so it can be traced.
|
||||
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.4-p6])])
|
||||
|
||||
#
|
||||
# Check to make sure that the build environment is sane.
|
||||
#
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
// Define if GCC supports weak symbols.
|
||||
#undef _GLIBCPP_SUPPORTS_WEAK
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
// 2001-12-27 pme
|
||||
//
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
|
@ -21,12 +21,16 @@
|
|||
// 23.2.1.1 deque constructors, copy, and assignment
|
||||
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <testsuite_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
typedef std::deque<gnu_counting_struct> gdeque;
|
||||
|
||||
bool test = true;
|
||||
|
||||
// basic alloc/dealloc sanity check
|
||||
// see http://gcc.gnu.org/ml/libstdc++/2001-11/msg00139.html
|
||||
void
|
||||
test01()
|
||||
{
|
||||
|
@ -38,9 +42,490 @@ test01()
|
|||
assert_count (0);
|
||||
}
|
||||
|
||||
|
||||
// 23.2.1 required types
|
||||
//
|
||||
// A missing required type will cause a compile failure.
|
||||
//
|
||||
void
|
||||
requiredTypesCheck()
|
||||
{
|
||||
typedef int T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
typedef X::reference reference;
|
||||
typedef X::const_reference const_reference;
|
||||
typedef X::iterator iterator;
|
||||
typedef X::const_iterator const_iterator;
|
||||
typedef X::size_type size_type;
|
||||
typedef X::difference_type difference_type;
|
||||
typedef X::value_type value_type;
|
||||
typedef X::allocator_type allocator_type;
|
||||
typedef X::pointer pointer;
|
||||
typedef X::const_pointer const_pointer;
|
||||
typedef X::reverse_iterator reverse_iterator;
|
||||
typedef X::const_reverse_iterator const_reverse_iterator;
|
||||
}
|
||||
|
||||
|
||||
// @fn defaultConstructorCheck
|
||||
// Explicitly checks the default deque constructor and destructor for both
|
||||
// trivial and non-trivial types. In addition, the size() and empty()
|
||||
// member functions are explicitly checked here since it should be their
|
||||
// first use. Checking those functions means checking the begin() and
|
||||
// end() and their const brethren functions as well.
|
||||
//
|
||||
// @verbatim
|
||||
// 23.2.1.1 default ctor/dtor
|
||||
// effects:
|
||||
// 23.2.1.1 constructs an empty deque using the specified allocator
|
||||
// postconditions:
|
||||
// 23.1 table 65 u.size() == 0
|
||||
// throws:
|
||||
// complexity:
|
||||
// 23.1 table 65 constant
|
||||
//
|
||||
// 23.2.1.2 bool empty() const
|
||||
// semantics:
|
||||
// 23.1 table 65 a.size() == 0
|
||||
// 23.1 (7) a.begin() == a.end()
|
||||
// throws:
|
||||
// complexity:
|
||||
// 23.1 table 65 constant
|
||||
//
|
||||
// 23.2.1.2 size_type size() const
|
||||
// semantics:
|
||||
// 23.1 table 65 a.end() - a.begin()
|
||||
// throws:
|
||||
// complexity:
|
||||
// 23.1 table 65(A) should be constant
|
||||
//
|
||||
// 23.2.1 iterator begin()
|
||||
// const_iterator begin() const
|
||||
// iterator end()
|
||||
// const_iterator end() const
|
||||
// throws:
|
||||
// 23.1 (10) pt. 4 does not throw
|
||||
// complexity:
|
||||
// 23.1 table 65 constant
|
||||
// @endverbatim
|
||||
void
|
||||
defaultConstructorCheckPOD()
|
||||
{
|
||||
// setup
|
||||
typedef int T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
// run test
|
||||
X u;
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(u.empty());
|
||||
VERIFY(0 == u.size());
|
||||
VERIFY(u.begin() == u.end());
|
||||
VERIFY(0 == std::distance(u.begin(), u.end()));
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
defaultConstructorCheck()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// run test
|
||||
const X u;
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(u.empty());
|
||||
VERIFY(0 == u.size());
|
||||
VERIFY(u.begin() == u.end());
|
||||
VERIFY(0 == std::distance(u.begin(), u.end()));
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
|
||||
// @fn copyConstructorCheck()
|
||||
// Explicitly checks the deque copy constructor. Continues verificaton of
|
||||
// ancillary member functions documented under defaultConstructorCheck().
|
||||
//
|
||||
// This check also tests the push_back() member function.
|
||||
//
|
||||
// @verbatim
|
||||
// 23.2.1 copy constructor
|
||||
// effects:
|
||||
// postconditions:
|
||||
// 22.1.1 table 65 a == X(a)
|
||||
// u == a
|
||||
// throws:
|
||||
// complexity:
|
||||
// 22.1.1 table 65 linear
|
||||
// @endverbatim
|
||||
void
|
||||
copyConstructorCheck()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const int copyBaseSize = 17; // arbitrary
|
||||
|
||||
X a;
|
||||
for (int i = 0; i < copyBaseSize; ++i)
|
||||
a.push_back(i);
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(!a.empty());
|
||||
VERIFY(copyBaseSize == a.size());
|
||||
VERIFY(a.begin() != a.end());
|
||||
VERIFY(copyBaseSize == std::distance(a.begin(), a.end()));
|
||||
|
||||
// run test
|
||||
X u = a;
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(u == a);
|
||||
VERIFY(copyBaseSize == gnu_copy_constructor::count());
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
|
||||
// @fn fillConstructorCheck()
|
||||
// This test explicitly verifies the basic fill constructor. Like the default
|
||||
// constructor, later tests depend on the fill constructor working correctly.
|
||||
// That means this explicit test should preceed the later tests so the error
|
||||
// message given on assertion failure can be more helpful n tracking the
|
||||
// problem.
|
||||
//
|
||||
// 23.2.1.1 fill constructor
|
||||
// complexity:
|
||||
// 23.2.1.1 linear in N
|
||||
void
|
||||
fillConstructorCheck()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const X::size_type n(23);
|
||||
const X::value_type t(111);
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// run test
|
||||
X a(n, t);
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(n == a.size());
|
||||
VERIFY(n == gnu_copy_constructor::count());
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
|
||||
// @fn fillConstructorCheck2()
|
||||
// Explicit check for fill constructors masqueraded as range constructors as
|
||||
// elucidated in clause 23.1.1 paragraph 9 of the standard.
|
||||
//
|
||||
// 23.1.1 (9) fill constructor looking like a range constructor
|
||||
void
|
||||
fillConstructorCheck2()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const int f = 23;
|
||||
const int l = 111;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
X a(f, l);
|
||||
|
||||
VERIFY(f == a.size());
|
||||
VERIFY(f == gnu_copy_constructor::count());
|
||||
}
|
||||
|
||||
|
||||
// @fn rangeConstructorCheckForwardIterator()
|
||||
// This test copies from one deque to another to force the copy
|
||||
// constructor for T to be used because the compiler will kindly
|
||||
// elide copies if the default constructor can be used with
|
||||
// type conversions. Trust me.
|
||||
//
|
||||
// 23.2.1.1 range constructor, forward iterators
|
||||
void
|
||||
rangeConstructorCheckForwardIterator()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const X::size_type n(726);
|
||||
const X::value_type t(307);
|
||||
X source(n, t);
|
||||
X::iterator i = source.begin();
|
||||
X::iterator j = source.end();
|
||||
X::size_type rangeSize = std::distance(i, j);
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// test
|
||||
X a(i, j);
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(rangeSize == a.size());
|
||||
VERIFY(gnu_copy_constructor::count() <= rangeSize);
|
||||
}
|
||||
|
||||
|
||||
// @fn rangeConstructorCheckInputIterator()
|
||||
// An explicit check for range construction on an input iterator
|
||||
// range, which the standard expounds upon as having a different
|
||||
// complexity than forward iterators.
|
||||
//
|
||||
// 23.2.1.1 range constructor, input iterators
|
||||
void
|
||||
rangeConstructorCheckInputIterator()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
std::istringstream ibuf("1234567890123456789");
|
||||
const X::size_type rangeSize = ibuf.str().size();
|
||||
std::istream_iterator<char> i(ibuf);
|
||||
std::istream_iterator<char> j;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
X a(i, j);
|
||||
|
||||
VERIFY(rangeSize == a.size());
|
||||
VERIFY(gnu_copy_constructor::count() <= (2 * rangeSize));
|
||||
}
|
||||
|
||||
|
||||
// 23.2.1 copy assignment
|
||||
void
|
||||
copyAssignmentCheck()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const X::size_type n(18);
|
||||
const X::value_type t(1023);
|
||||
X a(n, t);
|
||||
X r;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
r = a;
|
||||
|
||||
VERIFY(r == a);
|
||||
VERIFY(n == gnu_copy_constructor::count());
|
||||
}
|
||||
|
||||
|
||||
// 23.2.1.1 fill assignment
|
||||
//
|
||||
// The complexity check must check dtors+copyAssign and
|
||||
// copyCtor+copyAssign because that's the way the SGI implementation
|
||||
// works. Dunno if it's true standard compliant (which specifies fill
|
||||
// assignment in terms of erase and insert only), but it should work
|
||||
// as (most) users expect and is more efficient.
|
||||
void
|
||||
fillAssignmentCheck()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const X::size_type starting_size(10);
|
||||
const X::value_type starting_value(66);
|
||||
const X::size_type n(23);
|
||||
const X::value_type t(111);
|
||||
|
||||
X a(starting_size, starting_value);
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// preconditions
|
||||
VERIFY(starting_size == a.size());
|
||||
|
||||
// test
|
||||
a.assign(n, t);
|
||||
|
||||
// postconditions
|
||||
VERIFY(n == a.size());
|
||||
VERIFY(n == (gnu_copy_constructor::count() + gnu_assignment_operator::count()));
|
||||
VERIFY(starting_size == (gnu_destructor::count() + gnu_assignment_operator::count()));
|
||||
}
|
||||
|
||||
|
||||
// @verbatim
|
||||
// 23.2.1 range assignment
|
||||
// 23.2.1.1 deque constructors, copy, and assignment
|
||||
// effects:
|
||||
// Constructs a deque equal to the range [first, last), using the
|
||||
// specified allocator.
|
||||
//
|
||||
// template<typename InputIterator>
|
||||
// assign(InputIterator first, InputIterator last);
|
||||
//
|
||||
// is equivalent to
|
||||
//
|
||||
// erase(begin(), end());
|
||||
// insert(begin(), first, last);
|
||||
//
|
||||
// postconditions:
|
||||
// throws:
|
||||
// complexity:
|
||||
// forward iterators: N calls to the copy constructor, 0 reallocations
|
||||
// input iterators: 2N calls to the copy constructor, log(N) reallocations
|
||||
// @endverbatim
|
||||
void
|
||||
rangeAssignmentCheck()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
const X::size_type source_size(726);
|
||||
const X::value_type source_value(307);
|
||||
const X::size_type starting_size(10);
|
||||
const X::value_type starting_value(66);
|
||||
|
||||
X source(source_size, source_value);
|
||||
X::iterator i = source.begin();
|
||||
X::iterator j = source.end();
|
||||
X::size_type rangeSize = std::distance(i, j);
|
||||
|
||||
X a(starting_size, starting_value);
|
||||
VERIFY(starting_size == a.size());
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
a.assign(i, j);
|
||||
|
||||
VERIFY(source == a);
|
||||
VERIFY(rangeSize == (gnu_copy_constructor::count() + gnu_assignment_operator::count()));
|
||||
VERIFY(starting_size == (gnu_destructor::count() + gnu_assignment_operator::count()));
|
||||
}
|
||||
|
||||
|
||||
// 23.1 (10) range assignment
|
||||
// 23.2.1.3 with exception
|
||||
void
|
||||
rangeAssignmentCheckWithException()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
// test
|
||||
// What does "no effects" mean?
|
||||
}
|
||||
|
||||
|
||||
// 23.1.1 (9) fill assignment looking like a range assignment
|
||||
void
|
||||
fillAssignmentCheck2()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T> X;
|
||||
|
||||
// test
|
||||
// What does "no effects" mean?
|
||||
}
|
||||
|
||||
// Verify that the default deque constructor offers the basic exception
|
||||
// guarantee.
|
||||
void
|
||||
test_default_ctor_exception_safety()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T, gnu_new_allocator<T> > X;
|
||||
|
||||
T::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// test
|
||||
try
|
||||
{
|
||||
X a(7);
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
// Verify that the copy constructor offers the basic exception guarantee.
|
||||
void
|
||||
test_copy_ctor_exception_safety()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::deque<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
T::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
|
||||
|
||||
// test
|
||||
try
|
||||
{
|
||||
X u(a);
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// basic functionality and standard conformance checks
|
||||
requiredTypesCheck();
|
||||
defaultConstructorCheckPOD();
|
||||
defaultConstructorCheck();
|
||||
test_default_ctor_exception_safety();
|
||||
copyConstructorCheck();
|
||||
test_copy_ctor_exception_safety();
|
||||
fillConstructorCheck();
|
||||
fillConstructorCheck2();
|
||||
rangeConstructorCheckInputIterator();
|
||||
rangeConstructorCheckForwardIterator();
|
||||
copyAssignmentCheck();
|
||||
fillAssignmentCheck();
|
||||
fillAssignmentCheck2();
|
||||
rangeAssignmentCheck();
|
||||
rangeAssignmentCheckWithException();
|
||||
|
||||
// specific bug fix checks
|
||||
test01();
|
||||
|
||||
return 0;
|
||||
return !test;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <testsuite_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
|
@ -119,10 +120,72 @@ void test03()
|
|||
VERIFY( test );
|
||||
}
|
||||
|
||||
// Verifies basic functionality of reserve() with forced reallocation.
|
||||
void
|
||||
test_reserve()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(3);
|
||||
const X::size_type old_size = a.size();
|
||||
const X::size_type old_capacity = a.capacity();
|
||||
const X::size_type new_capacity = old_capacity + 10;
|
||||
T::reset();
|
||||
|
||||
a.reserve(new_capacity);
|
||||
|
||||
// [23.2.4.1 (2)]
|
||||
VERIFY(new_capacity <= a.capacity());
|
||||
// [23.2.4.1 (3)]
|
||||
VERIFY(old_size == a.size());
|
||||
VERIFY(gnu_copy_constructor::count() <= old_size);
|
||||
VERIFY(gnu_destructor::count() <= old_size);
|
||||
}
|
||||
// check for memory leaks
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
}
|
||||
|
||||
// Verifies that reserve() with reallocation offers the strong
|
||||
// exception guarantee.
|
||||
void
|
||||
test_reserve_exception_guarantee()
|
||||
{
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
const X::size_type old_size = a.size();
|
||||
const X::size_type old_capacity = a.capacity();
|
||||
const X::size_type new_capacity = old_capacity + 10;
|
||||
T::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
|
||||
try
|
||||
{
|
||||
a.reserve(new_capacity);
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
VERIFY(old_capacity == a.capacity());
|
||||
VERIFY(gnu_copy_constructor::count() == gnu_destructor::count()+1);
|
||||
}
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test_reserve();
|
||||
test_reserve_exception_guarantee();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// 1999-06-29 bkoz
|
||||
|
||||
// Copyright (C) 1999-2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 1999-2001, 2002 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <testsuite_allocator.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
|
@ -94,12 +95,550 @@ void test04()
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// @fn test_default_ctor_exception_gurantee This test verifies that if
|
||||
// one of the vector's contained objects throws an exception from its
|
||||
// constructor while the vector is being constructed and filled with
|
||||
// default values, all memory is returned to the allocator whence it
|
||||
// came.
|
||||
void
|
||||
test_default_ctor_exception_gurantee()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// run test
|
||||
try
|
||||
{
|
||||
X a(7);
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(("memory leak detected:",
|
||||
gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal()));
|
||||
|
||||
// teardown
|
||||
}
|
||||
|
||||
// @fn test_copy_ctor_exception_gurantee This test verifies that if
|
||||
// one of the vector's contained objects throws an exception from its
|
||||
// constructor while the vector is being copy constructed, all memory
|
||||
// is returned to the allocator whence it came.
|
||||
void
|
||||
test_copy_ctor_exception_gurantee()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
|
||||
// run test
|
||||
try
|
||||
{
|
||||
X u(a);
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
// operator=()
|
||||
//
|
||||
// case 1: lhs.size() > rhs.size()
|
||||
// case 2: lhs.size() < rhs.size() < lhs.capacity()
|
||||
// case 3: lhs.capacity() < rhs.size()
|
||||
//
|
||||
void
|
||||
test_assignment_operator_1()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X r(9);
|
||||
X a(r.size() - 2);
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// preconditions
|
||||
VERIFY(r.size() > a.size());
|
||||
|
||||
// run test
|
||||
r = a;
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(r == a);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_assignment_operator_2()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X r(1);
|
||||
r.reserve(17);
|
||||
X a(r.size() + 7);
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// preconditions
|
||||
VERIFY(r.size() < a.size());
|
||||
VERIFY(a.size() < r.capacity());
|
||||
|
||||
// run test
|
||||
r = a;
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(r == a);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_assignment_operator_3()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X r(1);
|
||||
X a(r.capacity() + 7);
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// preconditions
|
||||
VERIFY(r.capacity() < a.size());
|
||||
|
||||
// run test
|
||||
r = a;
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(r == a);
|
||||
}
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_assignment_operator_3_exception_guarantee()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X r(1);
|
||||
X a(r.capacity() + 7);
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
|
||||
// preconditions
|
||||
VERIFY(r.capacity() < a.size());
|
||||
|
||||
// run test
|
||||
try
|
||||
{
|
||||
r = a;
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
// fill assign()
|
||||
//
|
||||
// case 1: [23.2.4.1 (3)] n <= size()
|
||||
// case 2: [23.2.4.1 (3)] size() < n <= capacity()
|
||||
// case 3: [23.2.4.1 (3)] n > capacity()
|
||||
// case 4: [23.2.4.1 (3)] n > capacity(), exception guarantees
|
||||
// case 5: [23.1.1 (9)] fill assign disguised as a range assign
|
||||
//
|
||||
void
|
||||
test_fill_assign_1()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X a(7);
|
||||
X::size_type old_size = a.size();
|
||||
X::size_type new_size = old_size - 2;
|
||||
const T t;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// run test
|
||||
a.assign(new_size, t);
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == new_size);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_fill_assign_2()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X a(7);
|
||||
a.reserve(11);
|
||||
X::size_type old_size = a.size();
|
||||
X::size_type old_capacity = a.capacity();
|
||||
X::size_type new_size = old_size + 2;
|
||||
const T t;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(old_size < new_size);
|
||||
VERIFY(new_size <= old_capacity);
|
||||
|
||||
// run test
|
||||
a.assign(new_size, t);
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == new_size);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_fill_assign_3()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
X::size_type old_size = a.size();
|
||||
X::size_type old_capacity = a.capacity();
|
||||
X::size_type new_size = old_capacity + 4;
|
||||
const T t;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(new_size > old_capacity);
|
||||
|
||||
// run test
|
||||
a.assign(new_size, t);
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == new_size);
|
||||
}
|
||||
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() > 0);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_fill_assign_3_exception_guarantee()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
X::size_type old_size = a.size();
|
||||
X::size_type old_capacity = a.capacity();
|
||||
X::size_type new_size = old_capacity + 4;
|
||||
const T t;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(new_size > old_capacity);
|
||||
|
||||
// run test
|
||||
try
|
||||
{
|
||||
a.assign(new_size, t);
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == old_size);
|
||||
VERIFY(a.capacity() == old_capacity);
|
||||
}
|
||||
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() > 0);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_fill_assign_4()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X a(7);
|
||||
X::size_type old_size = a.size();
|
||||
X::size_type new_size = old_size - 2;
|
||||
X::size_type new_value = 117;
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// run test
|
||||
a.assign(new_size, new_value);
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == new_size);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
// range assign()
|
||||
//
|
||||
// case 1: [23.2.4.1 (2)] input iterator
|
||||
// case 2: [23.2.4.1 (2)] forward iterator, distance(first, last) <= size()
|
||||
// case 3: [23.2.4.1 (2)]
|
||||
// forward iterator, size() < distance(first, last) <= capacity()
|
||||
// case 4: [23.2.4.1 (2)] forward iterator, distance(first, last) > capacity()
|
||||
// case 5: [23.2.4.1 (2)]
|
||||
// forward iterator, distance(first, last) > capacity(),
|
||||
// exception guarantees
|
||||
void
|
||||
test_range_assign_1()
|
||||
{
|
||||
// @TODO
|
||||
}
|
||||
|
||||
void
|
||||
test_range_assign_2()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X a(7);
|
||||
X b(3);
|
||||
X::size_type old_size = a.size();
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(b.size() < a.capacity());
|
||||
|
||||
// run test
|
||||
a.assign(b.begin(), b.end());
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == b.size());
|
||||
VERIFY(a == b);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_range_assign_3()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
X a(7);
|
||||
a.reserve(a.size() + 7);
|
||||
X b(a.size() + 3);
|
||||
X::size_type old_size = a.size();
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(a.size() < b.size());
|
||||
VERIFY(b.size() < a.capacity());
|
||||
|
||||
// run test
|
||||
a.assign(b.begin(), b.end());
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == b.size());
|
||||
VERIFY(a == b);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == 0);
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_range_assign_4()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
X b(a.capacity() + 7);
|
||||
X::size_type old_size = a.size();
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(b.size() > a.capacity());
|
||||
|
||||
// run test
|
||||
a.assign(b.begin(), b.end());
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(a.size() == b.size());
|
||||
VERIFY(a == b);
|
||||
}
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() > 0);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
void
|
||||
test_range_assign_4_exception_guarantee()
|
||||
{
|
||||
// setup
|
||||
typedef gnu_copy_tracker T;
|
||||
typedef std::vector<T, gnu_new_allocator<T> > X;
|
||||
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
{
|
||||
X a(7);
|
||||
X b(a.capacity() + 7);
|
||||
X::size_type old_size = a.size();
|
||||
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_copy_constructor::throw_on(3);
|
||||
|
||||
// assert preconditions
|
||||
VERIFY(b.size() > a.capacity());
|
||||
|
||||
// run test
|
||||
try
|
||||
{
|
||||
a.assign(b.begin(), b.end());
|
||||
VERIFY(("no exception thrown", false));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// assert postconditions
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() > 0);
|
||||
VERIFY(gnu_allocator_tracker::allocationTotal() == gnu_allocator_tracker::deallocationTotal());
|
||||
|
||||
// teardown
|
||||
gnu_copy_tracker::reset();
|
||||
gnu_allocator_tracker::resetCounts();
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
test_default_ctor_exception_gurantee();
|
||||
test_copy_ctor_exception_gurantee();
|
||||
test_assignment_operator_1();
|
||||
test_assignment_operator_2();
|
||||
test_assignment_operator_3();
|
||||
test_assignment_operator_3_exception_guarantee();
|
||||
test_fill_assign_1();
|
||||
test_fill_assign_2();
|
||||
test_fill_assign_3();
|
||||
test_fill_assign_3_exception_guarantee();
|
||||
test_fill_assign_4();
|
||||
test_range_assign_1();
|
||||
test_range_assign_2();
|
||||
test_range_assign_3();
|
||||
test_range_assign_4();
|
||||
test_range_assign_4_exception_guarantee();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ INCLUDES = \
|
|||
|
||||
## Build support library.
|
||||
noinst_LIBRARIES = libv3test.a
|
||||
libv3test_a_SOURCES = testsuite_hooks.cc
|
||||
libv3test_a_SOURCES = testsuite_hooks.cc testsuite_allocator.cc
|
||||
|
||||
## Build support utilities.
|
||||
## Only build this as native, as need to find startup files and libc to link.
|
||||
|
|
|
@ -162,7 +162,7 @@ INCLUDES = \
|
|||
|
||||
|
||||
noinst_LIBRARIES = libv3test.a
|
||||
libv3test_a_SOURCES = testsuite_hooks.cc
|
||||
libv3test_a_SOURCES = testsuite_hooks.cc testsuite_allocator.cc
|
||||
@GLIBCPP_BUILD_ABI_CHECK_TRUE@noinst_PROGRAMS = @GLIBCPP_BUILD_ABI_CHECK_TRUE@abi_check
|
||||
@GLIBCPP_BUILD_ABI_CHECK_FALSE@noinst_PROGRAMS =
|
||||
abi_check_SOURCES = abi_check.cc
|
||||
|
@ -177,7 +177,8 @@ CPPFLAGS = @CPPFLAGS@
|
|||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
libv3test_a_LIBADD =
|
||||
libv3test_a_OBJECTS = testsuite_hooks.$(OBJEXT)
|
||||
libv3test_a_OBJECTS = testsuite_hooks.$(OBJEXT) \
|
||||
testsuite_allocator.$(OBJEXT)
|
||||
@GLIBCPP_BUILD_ABI_CHECK_FALSE@noinst_PROGRAMS =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
//
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
gnu_allocator_tracker::size_type gnu_allocator_tracker::allocationTotal_ = 0;
|
||||
gnu_allocator_tracker::size_type gnu_allocator_tracker::deallocationTotal_ = 0;
|
||||
int gnu_allocator_tracker::constructCount_ = 0;
|
||||
int gnu_allocator_tracker::destructCount_ = 0;
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
// Testing allocator for the C++ library testsuite.
|
||||
//
|
||||
// Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 2, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
// USA.
|
||||
//
|
||||
// As a special exception, you may use this file as part of a free software
|
||||
// library without restriction. Specifically, if other files instantiate
|
||||
// templates or use macros or inline functions from this file, or you compile
|
||||
// this file and link it with other files to produce an executable, this
|
||||
// file does not by itself cause the resulting executable to be covered by
|
||||
// the GNU General Public License. This exception does not however
|
||||
// invalidate any other reasons why the executable file might be covered by
|
||||
// the GNU General Public License.
|
||||
|
||||
// This file provides an test instrumentation allocator that can be
|
||||
// used to verify allocation functionality of standard library
|
||||
// containers. 2002.11.25 smw
|
||||
|
||||
#ifndef _GLIBCPP_TESTSUITE_ALLOCATOR_H
|
||||
#define _GLIBCPP_TESTSUITE_ALLOCATOR_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
class gnu_allocator_tracker
|
||||
{
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
static void*
|
||||
allocate(size_type blocksize)
|
||||
{
|
||||
allocationTotal_ += blocksize;
|
||||
return ::operator new(blocksize);
|
||||
}
|
||||
|
||||
static void
|
||||
construct()
|
||||
{ constructCount_++; }
|
||||
|
||||
static void
|
||||
destroy()
|
||||
{ destructCount_++; }
|
||||
|
||||
static void
|
||||
deallocate(void* p, size_type blocksize)
|
||||
{
|
||||
::operator delete(p);
|
||||
deallocationTotal_ += blocksize;
|
||||
}
|
||||
|
||||
static size_type
|
||||
allocationTotal()
|
||||
{ return allocationTotal_; }
|
||||
|
||||
static size_type
|
||||
deallocationTotal()
|
||||
{ return deallocationTotal_; }
|
||||
|
||||
static int
|
||||
constructCount()
|
||||
{ return constructCount_; }
|
||||
|
||||
static int
|
||||
destructCount()
|
||||
{ return destructCount_; }
|
||||
|
||||
static void
|
||||
resetCounts()
|
||||
{
|
||||
allocationTotal_ = 0;
|
||||
deallocationTotal_ = 0;
|
||||
constructCount_ = 0;
|
||||
destructCount_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static size_type allocationTotal_;
|
||||
static size_type deallocationTotal_;
|
||||
static int constructCount_;
|
||||
static int destructCount_;
|
||||
};
|
||||
|
||||
// A simple basic allocator that just forwards to the
|
||||
// gnu_allocator_tracker to fulfill memory requests. This class is
|
||||
// templated on the target object type, but gnu_allocator_tracker
|
||||
// isn't.
|
||||
template<class T>
|
||||
class gnu_new_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template<class U> struct rebind { typedef gnu_new_allocator<U> other; };
|
||||
|
||||
pointer
|
||||
address(reference value) const
|
||||
{ return &value; }
|
||||
|
||||
const_pointer
|
||||
address(const_reference value) const
|
||||
{ return &value; }
|
||||
|
||||
gnu_new_allocator() throw()
|
||||
{ }
|
||||
|
||||
gnu_new_allocator(const gnu_new_allocator&) throw()
|
||||
{ }
|
||||
|
||||
template<class U>
|
||||
gnu_new_allocator(const gnu_new_allocator<U>&) throw()
|
||||
{ }
|
||||
|
||||
~gnu_new_allocator() throw()
|
||||
{ }
|
||||
|
||||
size_type
|
||||
max_size() const throw()
|
||||
{ return std::numeric_limits<std::size_t>::max() / sizeof(T); }
|
||||
|
||||
pointer
|
||||
allocate(size_type num, const void* = 0)
|
||||
{
|
||||
return static_cast<pointer>(gnu_allocator_tracker::allocate(num *
|
||||
sizeof(T)));
|
||||
}
|
||||
|
||||
void
|
||||
construct(pointer p, const T& value)
|
||||
{
|
||||
new (p) T(value);
|
||||
gnu_allocator_tracker::construct();
|
||||
}
|
||||
|
||||
void
|
||||
destroy(pointer p)
|
||||
{
|
||||
p->~T();
|
||||
gnu_allocator_tracker::destroy();
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(pointer p, size_type num)
|
||||
{ gnu_allocator_tracker::deallocate(p, num * sizeof(T)); }
|
||||
};
|
||||
|
||||
template<class T1, class T2>
|
||||
bool
|
||||
operator==(const gnu_new_allocator<T1>&,
|
||||
const gnu_new_allocator<T2>&) throw()
|
||||
{ return true; }
|
||||
|
||||
template<class T1, class T2>
|
||||
bool
|
||||
operator!=(const gnu_new_allocator<T1>&,
|
||||
const gnu_new_allocator<T2>&) throw()
|
||||
{ return false; }
|
||||
|
||||
#endif // _GLIBCPP_TESTSUITE_ALLOCATOR_H
|
||||
|
|
@ -78,6 +78,10 @@ __set_testsuite_memlimit(float) { }
|
|||
|
||||
gnu_counting_struct::size_type gnu_counting_struct::count = 0;
|
||||
|
||||
int gnu_copy_tracker::itsCopyCount = 0;
|
||||
int gnu_copy_tracker::itsDtorCount = 0;
|
||||
unsigned int gnu_copy_constructor::count_ = 0;
|
||||
unsigned int gnu_copy_constructor::throw_on_ = 0;
|
||||
unsigned int gnu_assignment_operator::count_ = 0;
|
||||
unsigned int gnu_assignment_operator::throw_on_ = 0;
|
||||
unsigned int gnu_destructor::count_ = 0;
|
||||
int gnu_copy_tracker::next_id_ = 0;
|
||||
|
||||
|
|
|
@ -100,58 +100,177 @@ struct gnu_counting_struct
|
|||
|
||||
#define assert_count(n) VERIFY(gnu_counting_struct::count == n)
|
||||
|
||||
// A (static) class for counting copy constructors and possibly throwing an
|
||||
// exception on a desired count.
|
||||
class gnu_copy_constructor
|
||||
{
|
||||
public:
|
||||
static unsigned int
|
||||
count()
|
||||
{ return count_; }
|
||||
|
||||
static void
|
||||
mark_call()
|
||||
{
|
||||
count_++;
|
||||
if (count_ == throw_on_)
|
||||
{
|
||||
__throw_exception_again "copy constructor exception";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset()
|
||||
{
|
||||
count_ = 0;
|
||||
throw_on_ = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
throw_on(unsigned int count)
|
||||
{ throw_on_ = count; }
|
||||
|
||||
private:
|
||||
static unsigned int count_;
|
||||
static unsigned int throw_on_;
|
||||
};
|
||||
|
||||
// A (static) class for counting assignment operator calls and possibly
|
||||
// throwing an exception on a desired count.
|
||||
class gnu_assignment_operator
|
||||
{
|
||||
public:
|
||||
static unsigned int
|
||||
count()
|
||||
{ return count_; }
|
||||
|
||||
static void
|
||||
mark_call()
|
||||
{
|
||||
count_++;
|
||||
if (count_ == throw_on_)
|
||||
{
|
||||
__throw_exception_again "assignment operator exception";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset()
|
||||
{
|
||||
count_ = 0;
|
||||
throw_on_ = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
throw_on(unsigned int count)
|
||||
{ throw_on_ = count; }
|
||||
|
||||
private:
|
||||
static unsigned int count_;
|
||||
static unsigned int throw_on_;
|
||||
};
|
||||
|
||||
// A (static) class for tracking calls to an object's destructor.
|
||||
class gnu_destructor
|
||||
{
|
||||
public:
|
||||
static unsigned int
|
||||
count()
|
||||
{ return count_; }
|
||||
|
||||
static void
|
||||
mark_call()
|
||||
{ count_++; }
|
||||
|
||||
static void
|
||||
reset()
|
||||
{ count_ = 0; }
|
||||
|
||||
private:
|
||||
static unsigned int count_;
|
||||
};
|
||||
|
||||
// An class of objects that can be used for validating various behaviours and
|
||||
// guarantees of containers and algorithms defined in the standard library.
|
||||
class gnu_copy_tracker
|
||||
{
|
||||
public:
|
||||
// Cannot be explicit. Conversion ctor used by list_modifiers.cc's
|
||||
// test03(), "range fill at beginning".
|
||||
gnu_copy_tracker (int anId, bool throwOnDemand = false)
|
||||
: itsId(anId), willThrow(throwOnDemand)
|
||||
{}
|
||||
|
||||
gnu_copy_tracker (const gnu_copy_tracker& rhs)
|
||||
: itsId(rhs.id()), willThrow(rhs.willThrow)
|
||||
// Creates a copy-tracking object with the given ID number.
|
||||
// If "throw_on_copy" is set, an exception will be thrown if
|
||||
// an attempt is made to copy this object.
|
||||
gnu_copy_tracker(int id = next_id_--, bool throw_on_copy = false)
|
||||
: id_(id)
|
||||
, throw_on_copy_(throw_on_copy)
|
||||
{
|
||||
++itsCopyCount;
|
||||
if (willThrow)
|
||||
__throw_exception_again "copy tracker exception";
|
||||
}
|
||||
|
||||
gnu_copy_tracker& operator=(const gnu_copy_tracker& rhs)
|
||||
// Copy-constructs the object, marking a call to the copy
|
||||
// constructor and forcing an exception if indicated.
|
||||
gnu_copy_tracker(const gnu_copy_tracker& rhs)
|
||||
: id_(rhs.id()), throw_on_copy_(rhs.throw_on_copy_)
|
||||
{
|
||||
itsId = rhs.id();
|
||||
// willThrow must obviously already be false to get this far
|
||||
int kkk = throw_on_copy_;
|
||||
if (throw_on_copy_)
|
||||
{
|
||||
gnu_copy_constructor::throw_on(gnu_copy_constructor::count() + 1);
|
||||
}
|
||||
gnu_copy_constructor::mark_call();
|
||||
}
|
||||
|
||||
~gnu_copy_tracker() { ++itsDtorCount; }
|
||||
// Assigns the value of another object to this one, tracking the
|
||||
// number of times this member function has been called and if the
|
||||
// other object is supposed to throw an exception when it is
|
||||
// copied, well, make it so.
|
||||
gnu_copy_tracker&
|
||||
operator=(const gnu_copy_tracker& rhs)
|
||||
{
|
||||
id_ = rhs.id();
|
||||
if (rhs.throw_on_copy_)
|
||||
{
|
||||
gnu_assignment_operator::throw_on(gnu_assignment_operator::count()
|
||||
+ 1);
|
||||
}
|
||||
gnu_assignment_operator::mark_call();
|
||||
}
|
||||
|
||||
~gnu_copy_tracker()
|
||||
{ gnu_destructor::mark_call(); }
|
||||
|
||||
int
|
||||
id() const
|
||||
{ return itsId; }
|
||||
{ return id_; }
|
||||
|
||||
private:
|
||||
int itsId;
|
||||
const bool willThrow;
|
||||
int id_;
|
||||
const bool throw_on_copy_;
|
||||
|
||||
public:
|
||||
static void
|
||||
reset()
|
||||
{ itsCopyCount = 0; itsDtorCount = 0; }
|
||||
{
|
||||
gnu_copy_constructor::reset();
|
||||
gnu_assignment_operator::reset();
|
||||
gnu_destructor::reset();
|
||||
}
|
||||
|
||||
// for backwards-compatibility
|
||||
static int
|
||||
copyCount()
|
||||
{ return itsCopyCount; }
|
||||
{ return gnu_copy_constructor::count(); }
|
||||
|
||||
// for backwards-compatibility
|
||||
static int
|
||||
dtorCount()
|
||||
{ return itsDtorCount; }
|
||||
{ return gnu_destructor::count(); }
|
||||
|
||||
private:
|
||||
static int itsCopyCount;
|
||||
static int itsDtorCount;
|
||||
static int next_id_;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const gnu_copy_tracker& lhs, const gnu_copy_tracker& rhs)
|
||||
{ return lhs.id() == rhs.id(); }
|
||||
|
||||
struct gnu_char
|
||||
{
|
||||
unsigned long c;
|
||||
|
|
Loading…
Reference in New Issue