1 /* 2 * Copyright Andrey Semashev 2013. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 /*! 8 * \file intrusive_ref_counter_test.cpp 9 * \author Andrey Semashev 10 * \date 31.08.2013 11 * 12 * This file contains tests for the \c intrusive_ref_counter base class. 13 */ 14 15 #include <boost/config.hpp> 16 17 #if defined(BOOST_MSVC) 18 19 #pragma warning(disable: 4786) // identifier truncated in debug info 20 #pragma warning(disable: 4710) // function not inlined 21 #pragma warning(disable: 4711) // function selected for automatic inline expansion 22 #pragma warning(disable: 4514) // unreferenced inline removed 23 #pragma warning(disable: 4355) // 'this' : used in base member initializer list 24 #pragma warning(disable: 4511) // copy constructor could not be generated 25 #pragma warning(disable: 4512) // assignment operator could not be generated 26 27 #if (BOOST_MSVC >= 1310) 28 #pragma warning(disable: 4675) // resolved overload found with Koenig lookup 29 #endif 30 31 #endif 32 33 #include <cstddef> 34 #include <boost/smart_ptr/intrusive_ref_counter.hpp> 35 #include <boost/intrusive_ptr.hpp> 36 #include <boost/core/lightweight_test.hpp> 37 38 namespace N1 { 39 40 class my_class : 41 public boost::intrusive_ref_counter< my_class > 42 { 43 public: 44 static unsigned int destructor_count; 45 ~my_class()46 ~my_class() 47 { 48 ++destructor_count; 49 } 50 }; 51 52 unsigned int my_class::destructor_count = 0; 53 54 } // namespace N1 55 56 namespace N2 { 57 58 class my_class : 59 public boost::intrusive_ref_counter< my_class, boost::thread_unsafe_counter > 60 { 61 public: 62 static unsigned int destructor_count; 63 ~my_class()64 ~my_class() 65 { 66 ++destructor_count; 67 } 68 }; 69 70 unsigned int my_class::destructor_count = 0; 71 72 } // namespace N2 73 74 namespace N3 { 75 76 struct root : 77 public boost::intrusive_ref_counter< root > 78 { ~rootN3::root79 virtual ~root() {} 80 }; 81 82 } // namespace N3 83 84 namespace N4 { 85 86 struct X : 87 public virtual N3::root 88 { 89 }; 90 91 } // namespace N4 92 93 namespace N5 { 94 95 struct Y : 96 public virtual N3::root 97 { 98 }; 99 100 } // namespace N5 101 102 namespace N6 { 103 104 struct Z : 105 public N4::X, 106 public N5::Y 107 { 108 static unsigned int destructor_count; 109 ~ZN6::Z110 ~Z() 111 { 112 ++destructor_count; 113 } 114 }; 115 116 unsigned int Z::destructor_count = 0; 117 118 } // namespace N6 119 120 main()121int main() 122 { 123 // The test check that ADL works 124 { 125 boost::intrusive_ptr< N1::my_class > p = new N1::my_class(); 126 p = NULL; 127 BOOST_TEST(N1::my_class::destructor_count == 1); 128 } 129 { 130 boost::intrusive_ptr< N2::my_class > p = new N2::my_class(); 131 p = NULL; 132 BOOST_TEST(N2::my_class::destructor_count == 1); 133 } 134 { 135 N1::my_class* p = new N1::my_class(); 136 intrusive_ptr_add_ref(p); 137 intrusive_ptr_release(p); 138 BOOST_TEST(N1::my_class::destructor_count == 2); 139 } 140 141 // The test checks that destroying through the base class works 142 { 143 boost::intrusive_ptr< N6::Z > p1 = new N6::Z(); 144 BOOST_TEST(p1->use_count() == 1); 145 BOOST_TEST(N6::Z::destructor_count == 0); 146 boost::intrusive_ptr< N3::root > p2 = p1; 147 BOOST_TEST(p1->use_count() == 2); 148 BOOST_TEST(N6::Z::destructor_count == 0); 149 p1 = NULL; 150 BOOST_TEST(N6::Z::destructor_count == 0); 151 p2 = NULL; 152 BOOST_TEST(N6::Z::destructor_count == 1); 153 } 154 155 return boost::report_errors(); 156 } 157