| // -*- C++ -*- |
| /*************************************************************************** |
| * |
| * 2.smartptr.shared.cpp - test exercising class template shared_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 <tr1/_smartptr.h> |
| |
| #include <rw_driver.h> |
| |
| /**************************************************************************/ |
| |
| int next_id; |
| |
| template <class T> |
| struct Base |
| { |
| static int n_dtors; |
| |
| int id; |
| |
| Base () { } |
| |
| void init () { |
| id = ++next_id; |
| } |
| |
| // Base dtor is not virtual in order to detect |
| // deletions through a pointer to the wrong base |
| /* NOT virtual */ ~Base () { |
| ++n_dtors; |
| } |
| }; |
| |
| template <class T> |
| int Base<T>::n_dtors; |
| |
| |
| template <class T> |
| struct Base_0: virtual Base<T> |
| { |
| static int n_dtors; |
| |
| T dummy; // make body non-empty |
| |
| Base_0 (): Base<T>() { this->init (); } |
| |
| virtual ~Base_0 () { |
| ++n_dtors; |
| } |
| }; |
| |
| template <class T> |
| int Base_0<T>::n_dtors; |
| |
| |
| template <class T> |
| struct Base_1: virtual Base<T> |
| { |
| static int n_dtors; |
| |
| T dummy; // make body non-empty |
| |
| Base_1 (): Base<T>() { this->init (); } |
| |
| virtual ~Base_1 () { |
| ++n_dtors; |
| } |
| }; |
| |
| template <class T> |
| int Base_1<T>::n_dtors; |
| |
| |
| template <class T> |
| struct Derived: Base_0<T>, Base_1<T> |
| { |
| static int n_dtors; |
| |
| T dummy; // make body non-empty |
| |
| Derived (): Base_0<T>(), Base_1<T>() { } |
| |
| virtual ~Derived () { |
| ++n_dtors; |
| } |
| }; |
| |
| template <class T> |
| int Derived<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.shared.cons", 0, |
| "shared_ptr constructors"); |
| |
| { // default ctor |
| std::tr1::shared_ptr<char> ptr; |
| rw_assert (0 == ptr.get (), 0, __LINE__, ""); |
| rw_assert (0 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // default ctor |
| std::tr1::shared_ptr<const short> ptr; |
| rw_assert (0 == ptr.get (), 0, __LINE__, ""); |
| rw_assert (0 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // default ctor |
| std::tr1::shared_ptr<volatile int> ptr; |
| rw_assert (0 == ptr.get (), 0, __LINE__, ""); |
| rw_assert (0 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // default ctor |
| std::tr1::shared_ptr<const volatile long> ptr; |
| rw_assert (0 == ptr.get (), 0, __LINE__, ""); |
| rw_assert (0 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // template <class U> shared_ptr(U*) |
| const char* const p = new char ('A'); |
| std::tr1::shared_ptr<const char> ptr (p); |
| rw_assert (p == ptr.get (), 0, __LINE__, ""); |
| rw_assert (1 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // template <class U> shared_ptr(U*) |
| const char* const p = new char ('A'); |
| std::tr1::shared_ptr<const void> ptr (p); |
| rw_assert (p == ptr.get (), 0, __LINE__, ""); |
| rw_assert (1 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // template <class U> shared_ptr(U*) |
| short* const p = new short (__LINE__); |
| std::tr1::shared_ptr<volatile void> ptr (p); |
| rw_assert (p == ptr.get (), 0, __LINE__, ""); |
| rw_assert (1 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // template <class U> shared_ptr(U*) |
| double* const p = new double (); |
| std::tr1::shared_ptr<const volatile void> ptr (p); |
| rw_assert (p == ptr.get (), 0, __LINE__, ""); |
| rw_assert (1 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| #if ILL_FORMED == -1 || ILL_FORMED == __LINE__ |
| |
| { // template <class U> shared_ptr(U*) |
| char* const p = new char ('A'); |
| std::tr1::shared_ptr<int> ptr (p); |
| } |
| |
| #endif // ILL_FORMED |
| |
| { // template <class U> shared_ptr(U*) |
| Derived<int>* const pd0 = new Derived<int>; |
| Derived<int>* const pd1 = new Derived<int>; |
| Derived<int>* const pd2 = new Derived<int>; |
| Derived<int>* const pd3 = new Derived<int>; |
| |
| std::tr1::shared_ptr<const Derived<int> > ptr_d (pd0); |
| std::tr1::shared_ptr<const Base_0<int> > ptr_0 (pd1); |
| std::tr1::shared_ptr<const Base_1<int> > ptr_1 (pd2); |
| std::tr1::shared_ptr<const Base<int> > ptr_b (pd3); |
| |
| rw_assert (pd0 == ptr_d.get (), 0, __LINE__, |
| "shared_ptr<Derived>(Derived* = %#p).get() == %#p, got %#p", |
| pd0, pd0, ptr_d.get ()); |
| |
| rw_assert (pd1 == ptr_0.get (), 0, __LINE__, |
| "shared_ptr<Base_0>(Derived* = %#p).get() == %#p, got %#p", |
| pd1, (Base_0<int>*)pd1, ptr_0.get ()); |
| |
| rw_assert (pd2 == ptr_1.get (), 0, __LINE__, |
| "shared_ptr<Base_1>(Derived* = %#p).get() == %#p, got %#p", |
| pd2, (Base_1<int>*)pd2, ptr_1.get ()); |
| |
| rw_assert (pd3 == ptr_b.get (), 0, __LINE__, |
| "shared_ptr<Baee>(Derived* = %#p).get() == %#p, got %#p", |
| pd3, (Base<int>*)pd3, ptr_b.get ()); |
| |
| rw_assert (1 == ptr_d.use_count (), 0, __LINE__, ""); |
| rw_assert (1 == ptr_0.use_count (), 0, __LINE__, ""); |
| rw_assert (1 == ptr_1.use_count (), 0, __LINE__, ""); |
| rw_assert (1 == ptr_b.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // template <class U, class D> shared_ptr(U*, D) |
| int* const p = new int (__LINE__); |
| Deleter<int> d; |
| std::tr1::shared_ptr<int> ptr (p, d); |
| rw_assert (p == ptr.get (), 0, __LINE__, ""); |
| rw_assert (1 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_copy_ctor () |
| { |
| rw_info (0, "tr.util.smartptr.shared.copy", 0, |
| "shared_ptr copy constructors"); |
| |
| { |
| // shared_ptr (const shared_ptr&) |
| std::tr1::shared_ptr<void> ptr; |
| std::tr1::shared_ptr<void> cpy (ptr); |
| rw_assert (0 == ptr.get (), 0, __LINE__, ""); |
| rw_assert (0 == cpy.get (), 0, __LINE__, ""); |
| rw_assert (0 == ptr.use_count (), 0, __LINE__, ""); |
| rw_assert (0 == cpy.use_count (), 0, __LINE__, ""); |
| } |
| |
| { |
| // shared_ptr (const shared_ptr&) |
| std::tr1::shared_ptr<double> ptr; |
| std::tr1::shared_ptr<double> cpy (ptr); |
| rw_assert (ptr.get () == cpy.get (), 0, __LINE__, ""); |
| rw_assert (ptr.use_count () == cpy.use_count (), 0, __LINE__, ""); |
| } |
| |
| { |
| // shared_ptr (const shared_ptr&) |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<int> ptr (p); |
| std::tr1::shared_ptr<int> cpy (ptr); |
| rw_assert (ptr.get () == cpy.get (), 0, __LINE__, ""); |
| rw_assert (ptr.use_count () == cpy.use_count (), 0, __LINE__, ""); |
| } |
| |
| { |
| // shared_ptr (const shared_ptr&) |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<int> ptr (p); |
| std::tr1::shared_ptr<void> cpy (ptr); |
| rw_assert (ptr.get () == cpy.get (), 0, __LINE__, ""); |
| rw_assert (ptr.use_count () == cpy.use_count (), 0, __LINE__, ""); |
| } |
| |
| #if ILL_FORMED == -1 || ILL_FORMED == __LINE__ |
| |
| { |
| // shared_ptr (const shared_ptr&) |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<void> ptr (p); |
| std::tr1::shared_ptr<int> cpy (ptr); |
| rw_assert (ptr.get () == cpy.get (), 0, __LINE__, ""); |
| rw_assert (ptr.use_count () == cpy.use_count (), 0, __LINE__, ""); |
| } |
| |
| #endif // ILL_FORMED |
| |
| |
| { // template <class U> shared_ptr(const shared_ptr<U>&) |
| Derived<int>* const pd = new Derived<int>; |
| |
| #if !defined (_RWSTD_HP_aCC_MAJOR) || 6 <= _RWSTD_HP_aCC_MAJOR \ |
| || 3 == _RWSTD_HP_aCC_MAJOR && __hpxstd98 |
| |
| typedef volatile Derived<int> v_Derived_i; |
| typedef volatile Base_0<int> v_Base_0_i; |
| typedef volatile Base_1<int> v_Base_1_i; |
| typedef volatile Base<int> v_Base_i; |
| |
| #else // HP aCC |
| |
| // volatile disabled for HP aCC 3 without the +hpxstd98 |
| // option available starting with aCC 3.74 to work around |
| // a compiler bug (see STDCXX-615) |
| |
| typedef /* volatile */ Derived<int> v_Derived_i; |
| typedef /* volatile */ Base_0<int> v_Base_0_i; |
| typedef /* volatile */ Base_1<int> v_Base_1_i; |
| typedef /* volatile */ Base<int> v_Base_i; |
| |
| #endif // HP aCC |
| |
| std::tr1::shared_ptr<v_Derived_i> ptr_d (pd); |
| std::tr1::shared_ptr<v_Base_0_i> ptr_0 (ptr_d); |
| std::tr1::shared_ptr<v_Base_1_i> ptr_1 (ptr_d); |
| std::tr1::shared_ptr<v_Base_i> ptr_b (ptr_d); |
| |
| rw_assert (pd == ptr_d.get (), 0, __LINE__, |
| "shared_ptr<Derived>(Derived* = %#p).get() == %#p, got %#p", |
| pd, pd, ptr_d.get ()); |
| |
| rw_assert (ptr_d.get () == ptr_0.get (), 0, __LINE__, |
| "shared_ptr<Base_0>(const shared_ptr<Derived>(%#p))" |
| ".get() == %#p, got %#p", |
| ptr_d.get (), |
| (v_Base_0_i*)ptr_d.get (), ptr_0.get ()); |
| |
| rw_assert (ptr_d.get () == ptr_1.get (), 0, __LINE__, |
| "shared_ptr<Base_1>(const shared_ptr<Derived>(%#p))" |
| ".get() == %#p, got %#p", |
| ptr_d.get (), |
| (v_Base_1_i*)ptr_d.get (), ptr_1.get ()); |
| |
| rw_assert (ptr_d.get () == ptr_b.get (), 0, __LINE__, |
| "shared_ptr<Base>(const shared_ptr<Derived>(%#p))" |
| ".get() == %#p, got %#p", |
| ptr_d.get (), |
| (v_Base_i*)ptr_d.get (), ptr_b.get ()); |
| |
| rw_assert (4 == ptr_d.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_d.use_count () == ptr_0.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_d.use_count () == ptr_1.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_d.use_count () == ptr_b.use_count (), 0, __LINE__, ""); |
| } |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_dtor () |
| { |
| rw_info (0, "tr.util.smartptr.shared.dest", 0, |
| "shared_ptr destructor"); |
| |
| { |
| // ~shared_ptr() |
| const int base_dtors = Base<int>::n_dtors; |
| { |
| std::tr1::shared_ptr<Base<int> > ptr; |
| } |
| rw_assert (base_dtors == Base<int>::n_dtors, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| const int base_dtors = Base<int>::n_dtors; |
| { |
| std::tr1::shared_ptr<Base<int> > ptr (new Base<int>); |
| } |
| rw_assert (base_dtors + 1 == Base<int>::n_dtors, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| const int base_dtors = Base<int>::n_dtors; |
| const int derived_dtors = Derived<int>::n_dtors; |
| { |
| std::tr1::shared_ptr<Derived<int> > ptr (new Derived<int>); |
| } |
| rw_assert (base_dtors + 1 == Base<int>::n_dtors, 0, __LINE__, ""); |
| rw_assert (derived_dtors + 1 == Derived<int>::n_dtors, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| const int base_dtors = Base<int>::n_dtors; |
| const int derived_dtors = Derived<int>::n_dtors; |
| { |
| std::tr1::shared_ptr<Base<int> > ptr (new Derived<int>); |
| } |
| rw_assert (base_dtors + 1 == Base<int>::n_dtors, 0, __LINE__, ""); |
| rw_assert (derived_dtors + 1 == Derived<int>::n_dtors, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| const int base_dtors = Base<int>::n_dtors; |
| const int derived_dtors = Derived<int>::n_dtors; |
| { |
| std::tr1::shared_ptr<void> ptr (new Derived<int>); |
| } |
| rw_assert (base_dtors + 1 == Base<int>::n_dtors, 0, __LINE__, ""); |
| rw_assert (derived_dtors + 1 == Derived<int>::n_dtors, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| Deleter<int> d; |
| const int funcalls = Deleter<int>::n_funcalls; |
| { |
| std::tr1::shared_ptr<int> ptr ((int*)0, d); |
| { |
| std::tr1::shared_ptr<int> cpy (ptr); |
| _RWSTD_UNUSED (cpy); |
| } |
| rw_assert (funcalls == Deleter<int>::n_funcalls, 0, __LINE__, ""); |
| } |
| rw_assert (funcalls + 1 == Deleter<int>::n_funcalls, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| Deleter<int> d; |
| const int funcalls = Deleter<int>::n_funcalls; |
| { |
| std::tr1::shared_ptr<int> ptr ((int*)0, d); |
| _RWSTD_UNUSED (ptr); |
| } |
| rw_assert (funcalls + 1 == Deleter<int>::n_funcalls, 0, __LINE__, ""); |
| } |
| |
| { |
| // ~shared_ptr() |
| int* const p = new int (__LINE__); |
| Deleter<int> d; |
| const int funcalls = Deleter<int>::n_funcalls; |
| { |
| std::tr1::shared_ptr<int> ptr (p, d); |
| } |
| rw_assert (funcalls + 1 == Deleter<int>::n_funcalls, 0, __LINE__, ""); |
| } |
| |
| { // ~shared_ptr |
| |
| // verify that the destructor of the referenced object |
| // including all its subobjects get invoked |
| int d_dtors = Derived<int>::n_dtors; |
| int b1_dtors = Base_1<int>::n_dtors; |
| int b0_dtors = Base_0<int>::n_dtors; |
| int b_dtors = Base<int>::n_dtors; |
| |
| { |
| std::tr1::shared_ptr<Derived<int> >(new Derived<int>); |
| } |
| |
| rw_assert (1 == Derived<int>::n_dtors - d_dtors, 0, __LINE__, |
| "shared_ptr<Derived>(Derived*) called ~Derived()"); |
| rw_assert (1 == Base_1<int>::n_dtors - b1_dtors, 0, __LINE__, |
| "shared_ptr<Derived>(Derived*) called ~Base_1()"); |
| rw_assert (1 == Base_0<int>::n_dtors - b0_dtors, 0, __LINE__, |
| "shared_ptr<Derived>(Derived*) called ~Base_0()"); |
| rw_assert (1 == Base<int>::n_dtors - b_dtors, 0, __LINE__, |
| "shared_ptr<Derived>(Derived*) called ~Base()"); |
| |
| d_dtors = Derived<int>::n_dtors; |
| b1_dtors = Base_1<int>::n_dtors; |
| b0_dtors = Base_0<int>::n_dtors; |
| b_dtors = Base<int>::n_dtors; |
| |
| { |
| std::tr1::shared_ptr<Base_1<int> >(new Derived<int>); |
| } |
| |
| rw_assert (1 == Derived<int>::n_dtors - d_dtors, 0, __LINE__, |
| "shared_ptr<Base_1>(Derived*) called ~Derived()"); |
| rw_assert (1 == Base_1<int>::n_dtors - b1_dtors, 0, __LINE__, |
| "shared_ptr<Base_1>(Derived*) called ~Base_1()"); |
| rw_assert (1 == Base_0<int>::n_dtors - b0_dtors, 0, __LINE__, |
| "shared_ptr<Base_1>(Derived*) called ~Base_0()"); |
| rw_assert (1 == Base<int>::n_dtors - b_dtors, 0, __LINE__, |
| "shared_ptr<Base_1>(Derived*) called ~Base()"); |
| |
| d_dtors = Derived<int>::n_dtors; |
| b1_dtors = Base_1<int>::n_dtors; |
| b0_dtors = Base_0<int>::n_dtors; |
| b_dtors = Base<int>::n_dtors; |
| |
| { |
| std::tr1::shared_ptr<Base_0<int> >(new Derived<int>); |
| } |
| |
| rw_assert (1 == Derived<int>::n_dtors - d_dtors, 0, __LINE__, |
| "shared_ptr<Base_0>(Derived*) called ~Derived()"); |
| rw_assert (1 == Base_1<int>::n_dtors - b1_dtors, 0, __LINE__, |
| "shared_ptr<Base_0>(Derived*) called ~Base_1()"); |
| rw_assert (1 == Base_0<int>::n_dtors - b0_dtors, 0, __LINE__, |
| "shared_ptr<Base_0>(Derived*) called ~Base_0()"); |
| rw_assert (1 == Base<int>::n_dtors - b_dtors, 0, __LINE__, |
| "shared_ptr<Base_0>(Derived*) called ~Base()"); |
| |
| d_dtors = Derived<int>::n_dtors; |
| b1_dtors = Base_1<int>::n_dtors; |
| b0_dtors = Base_0<int>::n_dtors; |
| b_dtors = Base<int>::n_dtors; |
| |
| { |
| std::tr1::shared_ptr<Base<int> >(new Derived<int>); |
| } |
| |
| rw_assert (1 == Derived<int>::n_dtors - d_dtors, 0, __LINE__, |
| "shared_ptr<Base>(Derived*) called ~Derived()"); |
| rw_assert (1 == Base_1<int>::n_dtors - b1_dtors, 0, __LINE__, |
| "shared_ptr<Base>(Derived*) called ~Base_1()"); |
| rw_assert (1 == Base_0<int>::n_dtors - b0_dtors, 0, __LINE__, |
| "shared_ptr<Base>(Derived*) called ~Base_0()"); |
| rw_assert (1 == Base<int>::n_dtors - b_dtors, 0, __LINE__, |
| "shared_ptr<Base>(Derived*) called ~Base()"); |
| |
| d_dtors = Derived<int>::n_dtors; |
| b1_dtors = Base_1<int>::n_dtors; |
| b0_dtors = Base_0<int>::n_dtors; |
| b_dtors = Base<int>::n_dtors; |
| |
| { |
| std::tr1::shared_ptr<void>(new Derived<int>); |
| } |
| |
| rw_assert (1 == Derived<int>::n_dtors - d_dtors, 0, __LINE__, |
| "shared_ptr<void>(Derived*) called ~Derived()"); |
| rw_assert (1 == Base_1<int>::n_dtors - b1_dtors, 0, __LINE__, |
| "shared_ptr<void>(Derived*) called ~Base_1()"); |
| rw_assert (1 == Base_0<int>::n_dtors - b0_dtors, 0, __LINE__, |
| "shared_ptr<void>(Derived*) called ~Base_0()"); |
| rw_assert (1 == Base<int>::n_dtors - b_dtors, 0, __LINE__, |
| "shared_ptr<void>(Derived*) called ~Base()"); |
| } |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_assign () |
| { |
| rw_info (0, "tr.util.smartptr.shared.assign", 0, |
| "shared_ptr assignment operators"); |
| |
| { // operator=(const shared_ptr&) |
| std::tr1::shared_ptr<void> ptr0; |
| std::tr1::shared_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 shared_ptr&) |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<int> ptr0 (p); |
| std::tr1::shared_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 shared_ptr<U>&) |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<int> ptr0 (p); |
| std::tr1::shared_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 shared_ptr<U>&) |
| Derived<int>* const p = new Derived<int>; |
| |
| std::tr1::shared_ptr<Derived<int> > ptr0 (p); |
| std::tr1::shared_ptr<Base<int> > ptr1; |
| |
| ptr1 = ptr0; |
| |
| rw_assert (ptr1.get ()->id == ptr0.get ()->id, 0, __LINE__, |
| "%d == %d, got %d", ptr1.get ()->id, ptr1.get ()->id, |
| ptr0.get ()->id); |
| rw_assert (ptr1.use_count () == ptr0.use_count (), 0, __LINE__, ""); |
| } |
| |
| { // template <class U> shared_ptr(U*) |
| Derived<int>* const pd = new Derived<int>; |
| |
| const std::tr1::shared_ptr<Derived<int> > ptr_d (pd); |
| |
| std::tr1::shared_ptr<Base_0<int> > ptr_0; |
| std::tr1::shared_ptr<Base_1<int> > ptr_1; |
| std::tr1::shared_ptr<Base<int> > ptr_b; |
| std::tr1::shared_ptr<void> ptr_v; |
| |
| ptr_0 = ptr_d; |
| ptr_1 = ptr_d; |
| ptr_b = ptr_d; |
| ptr_v = ptr_d; |
| |
| rw_assert (ptr_d.get () == ptr_0.get (), 0, __LINE__, |
| "(shared_ptr<Base_0>() = shared_ptr<Derived>(Derived* " |
| "= %#p)).get() == %#p, got %#p", |
| ptr_d.get (), (Base_0<int>*)ptr_d.get (), ptr_0.get ()); |
| |
| rw_assert (ptr_d.get () == ptr_1.get (), 0, __LINE__, |
| "(shared_ptr<Base_1>() = shared_ptr<Derived>(Derived* " |
| "= %#p)).get() == %#p, got %#p", |
| ptr_d.get (), (Base_1<int>*)ptr_d.get (), ptr_1.get ()); |
| |
| rw_assert (ptr_d.get () == ptr_b.get (), 0, __LINE__, |
| "(shared_ptr<Base>() = shared_ptr<Derived>(Derived* = %#p))" |
| ".get() == %#p, got %#p", |
| ptr_d.get (), (Base<int>*)ptr_d.get (), ptr_b.get ()); |
| |
| rw_assert (ptr_d.get () == ptr_v.get (), 0, __LINE__, |
| "(shared_ptr<void>() = shared_ptr<Derived>(Derived* = %#p))" |
| ".get() == %#p, got %#p", |
| ptr_d.get (), (void*)ptr_d.get (), ptr_v.get ()); |
| |
| rw_assert (5 == ptr_d.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_0.use_count () == ptr_d.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_1.use_count () == ptr_d.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_b.use_count () == ptr_d.use_count (), 0, __LINE__, ""); |
| rw_assert (ptr_v.use_count () == ptr_d.use_count (), 0, __LINE__, ""); |
| } |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_modifiers () |
| { |
| rw_info (0, "tr.util.smartptr.shared.mod", 0, |
| "shared_ptr modifiers"); |
| |
| rw_warn (0, 0, 0, |
| "shared_ptr modifiers not exercised"); |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_observers () |
| { |
| rw_info (0, "tr.util.smartptr.shared.obs", 0, |
| "shared_ptr observers"); |
| |
| { // operator*() |
| std::tr1::shared_ptr<void> ptr; |
| rw_assert (0 == ptr.get (), 0, __LINE__, ""); |
| rw_assert (0 == ptr.use_count (), 0, __LINE__, ""); |
| } |
| |
| rw_warn (0, 0, 0, |
| "shared_ptr observers not exercised"); |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_comparison () |
| { |
| rw_info (0, "tr.util.smartptr.shared.cmp", 0, |
| "shared_ptr comparison"); |
| |
| { // operator== |
| std::tr1::shared_ptr<void> ptr; |
| rw_assert (ptr == ptr, 0, __LINE__, ""); |
| |
| rw_assert (!(ptr != ptr), 0, __LINE__, ""); |
| } |
| |
| { // operator== |
| std::tr1::shared_ptr<void> ptr0; |
| std::tr1::shared_ptr<int> ptr1; |
| rw_assert (ptr0 == ptr1, 0, __LINE__, ""); |
| rw_assert (ptr1 == ptr0, 0, __LINE__, ""); |
| |
| rw_assert (!(ptr0 != ptr1), 0, __LINE__, ""); |
| rw_assert (!(ptr1 != ptr0), 0, __LINE__, ""); |
| } |
| |
| #if ILL_FORMED == -1 || ILL_FORMED == __LINE__ |
| |
| { |
| std::tr1::shared_ptr<char> ptr0; |
| std::tr1::shared_ptr<int> ptr1; |
| |
| rw_assert (ptr0 == ptr1, 0, __LINE__, ""); |
| rw_assert (ptr1 == ptr0, 0, __LINE__, ""); |
| |
| rw_assert (!(ptr0 != ptr1), 0, __LINE__, ""); |
| rw_assert (!(ptr1 != ptr0), 0, __LINE__, ""); |
| } |
| |
| #endif // ILL_FORMED |
| |
| { // operator== |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<int> ptr0 (p); |
| std::tr1::shared_ptr<int> ptr1 (ptr0); |
| |
| rw_assert (ptr0 == ptr1, 0, __LINE__, ""); |
| rw_assert (ptr1 == ptr0, 0, __LINE__, ""); |
| |
| rw_assert (!(ptr0 != ptr1), 0, __LINE__, ""); |
| rw_assert (!(ptr1 != ptr0), 0, __LINE__, ""); |
| } |
| |
| { // operator== |
| int* const p0 = new int (__LINE__); |
| int* const p1 = new int (__LINE__); |
| std::tr1::shared_ptr<int> ptr0 (p0); |
| std::tr1::shared_ptr<int> ptr1 (p1); |
| |
| rw_assert (!(ptr0 == ptr1), 0, __LINE__, ""); |
| rw_assert (!(ptr1 == ptr0), 0, __LINE__, ""); |
| |
| rw_assert (ptr0 != ptr1, 0, __LINE__, ""); |
| rw_assert (ptr1 != ptr0, 0, __LINE__, ""); |
| } |
| |
| { // operator< |
| Derived<int>* const p = new Derived<int>; |
| |
| std::tr1::shared_ptr<Derived<int> > ptr2 (p); |
| std::tr1::shared_ptr<Base_1<int> > ptr1 (ptr2); |
| std::tr1::shared_ptr<Base_0<int> > ptr0 (ptr2); |
| std::tr1::shared_ptr<Base<int> > ptr_b1 (ptr1); |
| std::tr1::shared_ptr<Base<int> > ptr_b0 (ptr0); |
| |
| const bool eq_1_2 = (ptr1.get () == ptr2.get ()) == (ptr1 == ptr2); |
| const bool eq_0_2 = (ptr0.get () == ptr2.get ()) == (ptr0 == ptr2); |
| |
| // rw_assert (eq_0_1, 0, __LINE__, ""); |
| rw_assert (eq_1_2, 0, __LINE__, ""); |
| rw_assert (eq_0_2, 0, __LINE__, ""); |
| } |
| |
| { // operator< |
| std::tr1::shared_ptr<void> ptr; |
| |
| rw_assert (!(ptr < ptr), 0, __LINE__, ""); |
| } |
| |
| { // operator< |
| std::tr1::shared_ptr<void> ptr; |
| std::tr1::shared_ptr<void> cpy (ptr); |
| |
| rw_assert (!(ptr < cpy) && !(cpy < ptr), 0, __LINE__, ""); |
| } |
| |
| { // operator< |
| int* const p = new int (__LINE__); |
| std::tr1::shared_ptr<void> ptr (p); |
| std::tr1::shared_ptr<void> cpy (ptr); |
| |
| rw_assert (!(ptr < cpy) && !(cpy < ptr), 0, __LINE__, ""); |
| } |
| |
| { // operator< |
| Derived<int>* const p = new Derived<int>; |
| |
| std::tr1::shared_ptr<Derived<int> > ptr2 (p); |
| std::tr1::shared_ptr<Base_1<int> > ptr1 (ptr2); |
| std::tr1::shared_ptr<Base_0<int> > ptr0 (ptr2); |
| std::tr1::shared_ptr<void> ptr (ptr0); |
| |
| rw_assert (!(ptr < ptr0) && !(ptr0 < ptr), 0, __LINE__, ""); |
| rw_assert (!(ptr < ptr1) && !(ptr1 < ptr), 0, __LINE__, ""); |
| rw_assert (!(ptr < ptr2) && !(ptr2 < ptr ), 0, __LINE__, ""); |
| rw_assert (!(ptr0 < ptr1) && !(ptr0 < ptr1), 0, __LINE__, ""); |
| rw_assert (!(ptr0 < ptr2) && !(ptr0 < ptr2), 0, __LINE__, ""); |
| rw_assert (!(ptr1 < ptr2) && !(ptr1 < ptr2), 0, __LINE__, ""); |
| } |
| |
| { // operator< |
| short* const p0 = new short (__LINE__); |
| float* const p1 = new float (__LINE__); |
| |
| std::tr1::shared_ptr<short> ptr0 (p0); |
| std::tr1::shared_ptr<float> ptr1 (p1); |
| |
| rw_assert (ptr0 < ptr1 || ptr1 < ptr0, 0, __LINE__, ""); |
| } |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_io () |
| { |
| rw_info (0, "tr.util.smartptr.shared.io", 0, |
| "shared_ptr I/O"); |
| |
| rw_warn (0, 0, 0, |
| "shared_ptr I/O not exercised"); |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_specialized () |
| { |
| rw_info (0, "tr.util.smartptr.shared.spec", 0, |
| "shared_ptr specialized algorithms"); |
| |
| rw_warn (0, 0, 0, |
| "shared_ptr specialized algorithms not exercised"); |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_casts () |
| { |
| rw_info (0, "tr.util.smartptr.shared.cast", 0, |
| "shared_ptr casts"); |
| |
| { |
| // dynamic_pointer_cast |
| |
| } |
| |
| rw_warn (0, 0, 0, |
| "shared_ptr casts not exercised"); |
| } |
| |
| /**************************************************************************/ |
| |
| static void |
| test_deleter () |
| { |
| rw_info (0, "tr.util.smartptr.shared.getdeleter", 0, |
| "shared_ptr get_deleter"); |
| |
| rw_warn (0, 0, 0, |
| "shared_ptr get_deleter 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_io; |
| static int no_specialized; |
| static int no_casts; |
| static int no_deleter; |
| |
| |
| 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 (io); |
| TEST (specialized); |
| TEST (casts); |
| TEST (deleter); |
| |
| return 0; |
| } |
| |
| /**************************************************************************/ |
| |
| int main (int argc, char *argv[]) |
| { |
| return rw_test (argc, argv, __FILE__, |
| "tr.util.smartptr.shared", |
| 0 /* no comment */, run_test, |
| "|-no-ctor# " |
| "|-no-copy_ctor# " |
| "|-no-dtor# " |
| "|-no-assign# " |
| "|-no-modifiers# " |
| "|-no-observers# " |
| "|-no-comparison# " |
| "|-no-io# " |
| "|-no-specialized# " |
| "|-no-casts# " |
| "|-no-deleter# ", |
| &no_ctor, |
| &no_copy_ctor, |
| &no_dtor, |
| &no_assign, |
| &no_modifiers, |
| &no_observers, |
| &no_comparison, |
| &no_io, |
| &no_specialized, |
| &no_casts, |
| &no_deleter); |
| } |