blob: 3f5e388dbd79710cb44f9aae7618c601c4de9ff8 [file] [log] [blame]
// -*- C++ -*-
/***************************************************************************
*
* 20.smartptr.weak.cpp - test exercising class template weak_ptr
*
* $Id$
*
***************************************************************************
*
* 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-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
#include <rw_driver.h>
// compile out all test code if extensions disabled
#ifndef _RWSTD_NO_EXT_CXX_0X
#include <rw/_smartptr.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, "util.smartptr.weak.cons", 0,
"weak_ptr constructors");
{ // default ctor
std::weak_ptr<char> weak;
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
}
{ // shared_ptr converting ctor
std::shared_ptr<char> shared;
std::weak_ptr<char> weak (shared);
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
}
{ // shared_ptr converting ctor
std::shared_ptr<char> shared;
std::weak_ptr<void> weak (shared);
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
}
{ // shared_ptr converting ctor
int* const p = new int (__LINE__);
std::shared_ptr<int> shared (p);
std::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::shared_ptr<int> shared0 (p);
std::shared_ptr<int> shared1 (shared0);
std::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::shared_ptr<int> shared (p);
std::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::shared_ptr<Derived<int> > shared (p);
std::weak_ptr<Base<int> > weak (shared);
shared.reset ();
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
}
}
/**************************************************************************/
static void
test_copy_ctor ()
{
rw_info (0, "util.smartptr.weak.copy", 0,
"weak_ptr copy constructors");
{
// weak_ptr (const weak_ptr&)
std::weak_ptr<void> weak;
std::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::shared_ptr<int> shared (p);
std::weak_ptr<int> weak (shared);
std::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::shared_ptr<int> shared0 (p);
std::shared_ptr<int> shared1 (shared0);
std::weak_ptr<int> weak (shared1);
std::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::shared_ptr<int> shared0 (p);
std::shared_ptr<int> shared1 (shared0);
std::weak_ptr<int> weak (shared1);
std::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::shared_ptr<Derived<int> > shared0 (p);
std::shared_ptr<Derived<int> > shared1 (shared0);
std::weak_ptr<Derived<int> > weak (shared1);
std::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, "util.smartptr.weak.dest", 0,
"weak_ptr destructor");
{
// ~weak_ptr()
const int base_dtors = Base<int>::n_dtors;
{
std::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::shared_ptr<Base<int> > shared (p);
{
std::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::shared_ptr<Derived<int> > shared (p);
{
std::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::shared_ptr<Derived<int> > shared (p);
{
std::weak_ptr<Base<int> > weak (shared);
std::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::shared_ptr<Derived<int> > shared (p);
{
std::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::weak_ptr<Derived<int> > weak;
{
Derived<int>* const p = new Derived<int>;
std::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, "util.smartptr.weak.assign", 0,
"weak_ptr assignment operators");
#if 0
{ // operator=(const weak_ptr&)
std::weak_ptr<void> ptr0;
std::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::weak_ptr<int> ptr0 (p);
std::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::weak_ptr<int> ptr0 (p);
std::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::weak_ptr<Derived<int> > ptr0 (p);
std::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::weak_ptr<Base<int> > ptr0 (p);
std::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, "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, "util.smartptr.weak.obs", 0,
"weak_ptr observers");
{ // use_count()
std::weak_ptr<void> weak;
rw_assert (0 == weak.use_count (), 0, __LINE__, "");
}
{ // expired()
std::weak_ptr<void> weak;
rw_assert (weak.expired (), 0, __LINE__, "");
}
{ // expired()
std::shared_ptr<void> shared;
std::weak_ptr<void> weak (shared);
rw_assert (weak.expired (), 0, __LINE__, "");
}
{ // expired()
int* const p = new int (__LINE__);
std::shared_ptr<void> shared (p);
std::weak_ptr<void> weak (shared);
rw_assert (!weak.expired (), 0, __LINE__, "");
}
{ // expired()
int* const p = new int (__LINE__);
std::shared_ptr<void> shared (p);
std::weak_ptr<void> weak (shared);
shared.reset ();
rw_assert (weak.expired (), 0, __LINE__, "");
}
{ // lock()
std::weak_ptr<void> weak;
std::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::shared_ptr<void> shared0 (p);
std::weak_ptr<void> weak (shared0);
std::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::shared_ptr<void> shared0 (p);
std::weak_ptr<void> weak (shared0);
std::shared_ptr<void> shared1 (weak.lock ());
std::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, "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, "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__,
"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);
}
#else // _RWSTD_NO_EXT_CXX_0X
static int
run_test (int, char* [])
{
rw_warn (0, 0, __LINE__,
"test disabled because _RWSTD_NO_EXT_CXX_0X is defined");
return 0;
}
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"util.smartptr.weak",
0 /* no comment */,
run_test,
0);
}
#endif // _RWSTD_NO_EXT_CXX_0X