607 lines
17 KiB
C++
607 lines
17 KiB
C++
// -*- C++ -*-
|
|
/***************************************************************************
|
|
*
|
|
* 2.smartptr.weak.cpp - test exercising class template weak_ptr
|
|
*
|
|
* $Id: 2.smartptr.weak.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 <cassert>
|
|
#include <tr1/_smartptr.h>
|
|
|
|
#include <driver.h>
|
|
|
|
/**************************************************************************/
|
|
|
|
template <class T>
|
|
struct Base
|
|
{
|
|
static int n_dtors;
|
|
|
|
virtual ~Base () {
|
|
++n_dtors;
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
int Base<T>::n_dtors;
|
|
|
|
|
|
template <class T>
|
|
struct Derived: Base<T>
|
|
{
|
|
static int n_dtors;
|
|
|
|
virtual ~Derived () {
|
|
++n_dtors;
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
int Derived<T>::n_dtors;
|
|
|
|
|
|
template <class T>
|
|
struct Derived2: Base<T>
|
|
{
|
|
static int n_dtors;
|
|
|
|
virtual ~Derived2 () {
|
|
++n_dtors;
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
int Derived2<T>::n_dtors;
|
|
|
|
|
|
template <class T>
|
|
struct Deleter
|
|
{
|
|
static int n_def_ctors;
|
|
static int n_cpy_ctors;
|
|
static int n_dtors;
|
|
static int n_funcalls;
|
|
|
|
Deleter () {
|
|
++n_def_ctors;
|
|
}
|
|
|
|
Deleter (const Deleter&) {
|
|
++n_cpy_ctors;
|
|
}
|
|
|
|
virtual ~Deleter () {
|
|
++n_dtors;
|
|
}
|
|
|
|
void operator()(T *p) {
|
|
++n_funcalls;
|
|
delete p;
|
|
}
|
|
|
|
private:
|
|
void operator=(Deleter&); // not defined
|
|
};
|
|
|
|
template <class T>
|
|
int Deleter<T>::n_def_ctors;
|
|
|
|
template <class T>
|
|
int Deleter<T>::n_cpy_ctors;
|
|
|
|
template <class T>
|
|
int Deleter<T>::n_dtors;
|
|
|
|
template <class T>
|
|
int Deleter<T>::n_funcalls;
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_ctor ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.cons", 0,
|
|
"weak_ptr constructors");
|
|
|
|
{ // default ctor
|
|
std::tr1::weak_ptr<char> weak;
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // shared_ptr converting ctor
|
|
std::tr1::shared_ptr<char> shared;
|
|
std::tr1::weak_ptr<char> weak (shared);
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // shared_ptr converting ctor
|
|
std::tr1::shared_ptr<char> shared;
|
|
std::tr1::weak_ptr<void> weak (shared);
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // shared_ptr converting ctor
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<int> shared (p);
|
|
std::tr1::weak_ptr<int> weak (shared);
|
|
rw_assert (shared.use_count () == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // shared_ptr converting ctor
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<int> shared0 (p);
|
|
std::tr1::shared_ptr<int> shared1 (shared0);
|
|
std::tr1::weak_ptr<int> weak (shared1);
|
|
rw_assert (shared1.use_count () == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
|
|
{ // shared_ptr converting ctor
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<int> shared (p);
|
|
std::tr1::weak_ptr<void> weak (shared);
|
|
shared.reset ();
|
|
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // shared_ptr converting ctor
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::shared_ptr<Derived<int> > shared (p);
|
|
std::tr1::weak_ptr<Base<int> > weak (shared);
|
|
shared.reset ();
|
|
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_copy_ctor ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.copy", 0,
|
|
"weak_ptr copy constructors");
|
|
|
|
{
|
|
// weak_ptr (const weak_ptr&)
|
|
std::tr1::weak_ptr<void> weak;
|
|
std::tr1::weak_ptr<void> copy (weak);
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
rw_assert (0 == copy.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// weak_ptr (const weak_ptr&)
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<int> shared (p);
|
|
std::tr1::weak_ptr<int> weak (shared);
|
|
std::tr1::weak_ptr<int> copy (weak);
|
|
|
|
rw_assert (weak.use_count () == shared.use_count (), 0, __LINE__, "");
|
|
rw_assert (copy.use_count () == shared.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// weak_ptr (const weak_ptr&)
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<int> shared0 (p);
|
|
std::tr1::shared_ptr<int> shared1 (shared0);
|
|
std::tr1::weak_ptr<int> weak (shared1);
|
|
std::tr1::weak_ptr<int> copy (weak);
|
|
|
|
rw_assert (weak.use_count () == shared1.use_count (), 0, __LINE__, "");
|
|
rw_assert (copy.use_count () == shared1.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// weak_ptr (const weak_ptr&)
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<int> shared0 (p);
|
|
std::tr1::shared_ptr<int> shared1 (shared0);
|
|
std::tr1::weak_ptr<int> weak (shared1);
|
|
std::tr1::weak_ptr<void> copy (weak);
|
|
|
|
rw_assert (weak.use_count () == shared1.use_count (), 0, __LINE__, "");
|
|
rw_assert (copy.use_count () == shared1.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// weak_ptr (const weak_ptr&)
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::shared_ptr<Derived<int> > shared0 (p);
|
|
std::tr1::shared_ptr<Derived<int> > shared1 (shared0);
|
|
std::tr1::weak_ptr<Derived<int> > weak (shared1);
|
|
std::tr1::weak_ptr<Base<int> > copy (weak);
|
|
|
|
rw_assert (weak.use_count () == shared1.use_count (), 0, __LINE__, "");
|
|
rw_assert (copy.use_count () == shared1.use_count (), 0, __LINE__, "");
|
|
|
|
shared1.reset ();
|
|
rw_assert (copy.use_count () == weak.use_count (), 0, __LINE__, "");
|
|
rw_assert (copy.use_count () == shared0.use_count (), 0, __LINE__, "");
|
|
|
|
shared0.reset ();
|
|
rw_assert (copy.use_count () == weak.use_count (), 0, __LINE__, "");
|
|
rw_assert (copy.use_count () == shared0.use_count (), 0, __LINE__, "");
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_dtor ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.dest", 0,
|
|
"weak_ptr destructor");
|
|
|
|
{
|
|
// ~weak_ptr()
|
|
const int base_dtors = Base<int>::n_dtors;
|
|
{
|
|
std::tr1::weak_ptr<Base<int> > weak;
|
|
}
|
|
rw_assert (base_dtors == Base<int>::n_dtors, 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// ~weak_ptr()
|
|
const int base_dtors = Base<int>::n_dtors;
|
|
Base<int>* const p = new Base<int>;
|
|
std::tr1::shared_ptr<Base<int> > shared (p);
|
|
{
|
|
std::tr1::weak_ptr<Base<int> > weak (shared);
|
|
}
|
|
rw_assert (base_dtors == Base<int>::n_dtors, 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// ~weak_ptr()
|
|
const int base_dtors = Base<int>::n_dtors;
|
|
const int derived_dtors = Derived<int>::n_dtors;
|
|
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::shared_ptr<Derived<int> > shared (p);
|
|
|
|
{
|
|
std::tr1::weak_ptr<Base<int> > weak (shared);
|
|
}
|
|
rw_assert (base_dtors == Base<int>::n_dtors, 0, __LINE__, "");
|
|
rw_assert (derived_dtors == Derived<int>::n_dtors, 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// ~weak_ptr()
|
|
const int base_dtors = Base<int>::n_dtors;
|
|
const int derived_dtors = Derived<int>::n_dtors;
|
|
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::shared_ptr<Derived<int> > shared (p);
|
|
|
|
{
|
|
std::tr1::weak_ptr<Base<int> > weak (shared);
|
|
std::tr1::weak_ptr<Base<int> > copy (shared);
|
|
}
|
|
rw_assert (base_dtors == Base<int>::n_dtors, 0, __LINE__, "");
|
|
rw_assert (derived_dtors == Derived<int>::n_dtors, 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// ~weak_ptr()
|
|
const int base_dtors = Base<int>::n_dtors;
|
|
const int derived_dtors = Derived<int>::n_dtors;
|
|
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::shared_ptr<Derived<int> > shared (p);
|
|
|
|
{
|
|
std::tr1::weak_ptr<Base<int> > weak (shared);
|
|
shared.reset ();
|
|
}
|
|
rw_assert (base_dtors + 1 == Base<int>::n_dtors, 0, __LINE__, "");
|
|
rw_assert (derived_dtors + 1 == Derived<int>::n_dtors, 0, __LINE__, "");
|
|
}
|
|
|
|
{
|
|
// ~weak_ptr()
|
|
const int base_dtors = Base<int>::n_dtors;
|
|
const int derived_dtors = Derived<int>::n_dtors;
|
|
|
|
std::tr1::weak_ptr<Derived<int> > weak;
|
|
|
|
{
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::shared_ptr<Derived<int> > shared (p);
|
|
|
|
weak = shared;
|
|
}
|
|
rw_assert (base_dtors + 1 == Base<int>::n_dtors, 0, __LINE__, "");
|
|
rw_assert (derived_dtors + 1 == Derived<int>::n_dtors, 0, __LINE__, "");
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_assign ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.assign", 0,
|
|
"weak_ptr assignment operators");
|
|
|
|
#if 0
|
|
|
|
{ // operator=(const weak_ptr&)
|
|
std::tr1::weak_ptr<void> ptr0;
|
|
std::tr1::weak_ptr<void> ptr1;
|
|
|
|
ptr1 = ptr0;
|
|
|
|
rw_assert (ptr1.get () == ptr0.get (), 0, __LINE__, "");
|
|
rw_assert (ptr1.use_count () == ptr0.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // operator=(const weak_ptr&)
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::weak_ptr<int> ptr0 (p);
|
|
std::tr1::weak_ptr<int> ptr1;
|
|
|
|
ptr1 = ptr0;
|
|
|
|
rw_assert (ptr1.get () == ptr0.get (), 0, __LINE__, "");
|
|
rw_assert (ptr1.use_count () == ptr0.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // template <class U> operator=(const weak_ptr<U>&)
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::weak_ptr<int> ptr0 (p);
|
|
std::tr1::weak_ptr<void> ptr1;
|
|
|
|
ptr1 = ptr0;
|
|
|
|
rw_assert (ptr1.get () == ptr0.get (), 0, __LINE__, "");
|
|
rw_assert (ptr1.use_count () == ptr0.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // template <class U> operator=(const weak_ptr<U>&)
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::weak_ptr<Derived<int> > ptr0 (p);
|
|
std::tr1::weak_ptr<Base<int> > ptr1;
|
|
|
|
ptr1 = ptr0;
|
|
|
|
rw_assert (ptr1.get () == ptr0.get (), 0, __LINE__, "");
|
|
rw_assert (ptr1.use_count () == ptr0.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // template <class U> operator=(const weak_ptr<U>&)
|
|
Derived<int>* const p = new Derived<int>;
|
|
std::tr1::weak_ptr<Base<int> > ptr0 (p);
|
|
std::tr1::weak_ptr<void> ptr1;
|
|
|
|
ptr1 = ptr0;
|
|
|
|
rw_assert (ptr1.get () == ptr0.get (), 0, __LINE__, "");
|
|
rw_assert (ptr1.use_count () == ptr0.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
#endif // 0/1
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_modifiers ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.mod", 0,
|
|
"weak_ptr modifiers");
|
|
|
|
rw_warn (0, 0, 0,
|
|
"weak_ptr modifiers not exercised");
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_observers ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.obs", 0,
|
|
"weak_ptr observers");
|
|
|
|
{ // use_count()
|
|
std::tr1::weak_ptr<void> weak;
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // expired()
|
|
std::tr1::weak_ptr<void> weak;
|
|
rw_assert (weak.expired (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // expired()
|
|
std::tr1::shared_ptr<void> shared;
|
|
std::tr1::weak_ptr<void> weak (shared);
|
|
rw_assert (weak.expired (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // expired()
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<void> shared (p);
|
|
std::tr1::weak_ptr<void> weak (shared);
|
|
rw_assert (!weak.expired (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // expired()
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<void> shared (p);
|
|
std::tr1::weak_ptr<void> weak (shared);
|
|
shared.reset ();
|
|
rw_assert (weak.expired (), 0, __LINE__, "");
|
|
}
|
|
|
|
{ // lock()
|
|
std::tr1::weak_ptr<void> weak;
|
|
std::tr1::shared_ptr<void> shared (weak.lock ());
|
|
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__,
|
|
"weak_ptr<void>::use_count() == 1, got %ld",
|
|
weak.use_count ());
|
|
rw_assert (0 == shared.use_count (), 0, __LINE__,
|
|
"shared_ptr<void>::use_count() == 1, got %ld",
|
|
shared.use_count ());
|
|
}
|
|
|
|
{ // lock()
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<void> shared0 (p);
|
|
std::tr1::weak_ptr<void> weak (shared0);
|
|
std::tr1::shared_ptr<void> shared1 (weak.lock ());
|
|
|
|
rw_assert (2 == weak.use_count (), 0, __LINE__,
|
|
"weak_ptr<void>::use_count() == 2, got %ld",
|
|
weak.use_count ());
|
|
rw_assert (2 == shared1.use_count (), 0, __LINE__,
|
|
"shared_ptr<void>::use_count() == 2, got %ld",
|
|
shared1.use_count ());
|
|
}
|
|
|
|
{ // lock()
|
|
int* const p = new int (__LINE__);
|
|
std::tr1::shared_ptr<void> shared0 (p);
|
|
std::tr1::weak_ptr<void> weak (shared0);
|
|
std::tr1::shared_ptr<void> shared1 (weak.lock ());
|
|
std::tr1::shared_ptr<void> shared2 (shared1);
|
|
|
|
rw_assert (3 == weak.use_count (), 0, __LINE__,
|
|
"weak_ptr<void>::use_count() == 3, got %ld",
|
|
weak.use_count ());
|
|
rw_assert (3 == shared0.use_count (), 0, __LINE__,
|
|
"shared_ptr<void>::use_count() == 3, got %ld",
|
|
shared1.use_count ());
|
|
|
|
shared0.reset ();
|
|
|
|
rw_assert (2 == weak.use_count (), 0, __LINE__,
|
|
"weak_ptr<void>::use_count() == 2, got %ld",
|
|
weak.use_count ());
|
|
|
|
shared1.reset ();
|
|
|
|
rw_assert (1 == weak.use_count (), 0, __LINE__,
|
|
"weak_ptr<void>::use_count() == 1, got %ld",
|
|
weak.use_count ());
|
|
|
|
shared2.reset ();
|
|
|
|
rw_assert (0 == weak.use_count (), 0, __LINE__,
|
|
"weak_ptr<void>::use_count() == 0, got %ld",
|
|
weak.use_count ());
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_comparison ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.cmp", 0,
|
|
"weak_ptr comparison");
|
|
|
|
rw_warn (0, 0, 0,
|
|
"weak_ptr comparison not exercised");
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static void
|
|
test_specialized ()
|
|
{
|
|
rw_info (0, "tr.util.smartptr.weak.spec", 0,
|
|
"weak_ptr specialized algorithms");
|
|
|
|
rw_warn (0, 0, 0,
|
|
"weak_ptr specialized algorithms not exercised");
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
static int no_ctor;
|
|
static int no_copy_ctor;
|
|
static int no_dtor;
|
|
static int no_assign;
|
|
static int no_modifiers;
|
|
static int no_observers;
|
|
static int no_comparison;
|
|
static int no_specialized;
|
|
|
|
|
|
static int
|
|
run_test (int, char*[])
|
|
{
|
|
#define TEST(what) \
|
|
if (no_ ## what) { \
|
|
rw_note (0, 0, __LINE__, "%s test disabled", #what); \
|
|
} \
|
|
else { \
|
|
test_ ## what (); \
|
|
} typedef void unused_typedef
|
|
|
|
TEST (ctor);
|
|
TEST (copy_ctor);
|
|
TEST (dtor);
|
|
TEST (assign);
|
|
TEST (modifiers);
|
|
TEST (observers);
|
|
TEST (comparison);
|
|
TEST (specialized);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
int main (int argc, char *argv[])
|
|
{
|
|
return rw_test (argc, argv, __FILE__,
|
|
"tr.util.smartptr.weak",
|
|
0 /* no comment */, run_test,
|
|
"|-no-ctor# "
|
|
"|-no-copy_ctor# "
|
|
"|-no-dtor# "
|
|
"|-no-assign# "
|
|
"|-no-modifiers# "
|
|
"|-no-observers# "
|
|
"|-no-comparison# "
|
|
"|-no-specialized# ",
|
|
&no_ctor,
|
|
&no_copy_ctor,
|
|
&no_dtor,
|
|
&no_assign,
|
|
&no_modifiers,
|
|
&no_observers,
|
|
&no_comparison,
|
|
&no_specialized);
|
|
}
|