stdcpp/tsrc/Boost_test/smart_ptr/src/intrusive_ptr_test.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2 Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     3 
       
     4 Redistribution and use in source and binary forms, with or without 
       
     5 modification, are permitted provided that the following conditions are met:
       
     6 
       
     7 * Redistributions of source code must retain the above copyright notice, this 
       
     8   list of conditions and the following disclaimer.
       
     9 * Redistributions in binary form must reproduce the above copyright notice, 
       
    10   this list of conditions and the following disclaimer in the documentation 
       
    11   and/or other materials provided with the distribution.
       
    12 * Neither the name of Nokia Corporation nor the names of its contributors 
       
    13   may be used to endorse or promote products derived from this software 
       
    14   without specific prior written permission.
       
    15 
       
    16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
       
    17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
       
    18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
       
    19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 
       
    20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
       
    21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
       
    22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
       
    23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
       
    24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
       
    25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    26 
       
    27 * Description:
       
    28 *
       
    29 */
       
    30 
       
    31 
       
    32 
       
    33 #include <boost/config.hpp>
       
    34 
       
    35 #ifdef __SYMBIAN32__
       
    36 #include "std_log_result.h"
       
    37 #define LOG_FILENAME_LINE __FILE__, __LINE__
       
    38 #endif
       
    39 
       
    40 #if defined(BOOST_MSVC)
       
    41 
       
    42 #pragma warning(disable: 4786)  // identifier truncated in debug info
       
    43 #pragma warning(disable: 4710)  // function not inlined
       
    44 #pragma warning(disable: 4711)  // function selected for automatic inline expansion
       
    45 #pragma warning(disable: 4514)  // unreferenced inline removed
       
    46 #pragma warning(disable: 4355)  // 'this' : used in base member initializer list
       
    47 #pragma warning(disable: 4511)  // copy constructor could not be generated
       
    48 #pragma warning(disable: 4512)  // assignment operator could not be generated
       
    49 
       
    50 #if (BOOST_MSVC >= 1310)
       
    51 #pragma warning(disable: 4675)  // resolved overload found with Koenig lookup
       
    52 #endif
       
    53 
       
    54 #endif
       
    55 
       
    56 //
       
    57 //  intrusive_ptr_test.cpp
       
    58 //
       
    59 //  Copyright (c) 2002-2005 Peter Dimov
       
    60 //
       
    61 // Distributed under the Boost Software License, Version 1.0. (See
       
    62 // accompanying file LICENSE_1_0.txt or copy at
       
    63 // http://www.boost.org/LICENSE_1_0.txt)
       
    64 //
       
    65 
       
    66 #include <boost/detail/lightweight_test.hpp>
       
    67 #include <boost/intrusive_ptr.hpp>
       
    68 #include <boost/detail/atomic_count.hpp>
       
    69 #include <boost/config.hpp>
       
    70 #include <algorithm>
       
    71 #include <functional>
       
    72 
       
    73 //
       
    74 
       
    75 namespace N
       
    76 {
       
    77 
       
    78 class base
       
    79 {
       
    80 private:
       
    81 
       
    82     boost::detail::atomic_count use_count_;
       
    83 
       
    84     base(base const &);
       
    85     base & operator=(base const &);
       
    86 
       
    87 protected:
       
    88 
       
    89     base(): use_count_(0)
       
    90     {
       
    91     }
       
    92 
       
    93     virtual ~base()
       
    94     {
       
    95     }
       
    96 
       
    97 public:
       
    98 
       
    99     long use_count() const
       
   100     {
       
   101         return use_count_;
       
   102     }
       
   103 
       
   104 #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
       
   105 
       
   106     inline friend void intrusive_ptr_add_ref(base * p)
       
   107     {
       
   108         ++p->use_count_;
       
   109     }
       
   110 
       
   111     inline friend void intrusive_ptr_release(base * p)
       
   112     {
       
   113         if(--p->use_count_ == 0) delete p;
       
   114     }
       
   115 
       
   116 #else
       
   117 
       
   118     void add_ref()
       
   119     {
       
   120         ++use_count_;
       
   121     }
       
   122 
       
   123     void release()
       
   124     {
       
   125         if(--use_count_ == 0) delete this;
       
   126     }
       
   127 
       
   128 #endif
       
   129 };
       
   130 
       
   131 } // namespace N
       
   132 
       
   133 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
       
   134 
       
   135 namespace boost
       
   136 {
       
   137 
       
   138 inline void intrusive_ptr_add_ref(N::base * p)
       
   139 {
       
   140     p->add_ref();
       
   141 }
       
   142 
       
   143 inline void intrusive_ptr_release(N::base * p)
       
   144 {
       
   145     p->release();
       
   146 }
       
   147 
       
   148 } // namespace boost
       
   149 
       
   150 #endif
       
   151 
       
   152 //
       
   153 
       
   154 struct X: public virtual N::base
       
   155 {
       
   156 };
       
   157 
       
   158 struct Y: public X
       
   159 {
       
   160 };
       
   161 
       
   162 //
       
   163 
       
   164 namespace n_element_type
       
   165 {
       
   166 
       
   167 void f(X &)
       
   168 {
       
   169 }
       
   170 
       
   171 void test()
       
   172 {
       
   173     typedef boost::intrusive_ptr<X>::element_type T;
       
   174     T t;
       
   175     f(t);
       
   176 }
       
   177 
       
   178 } // namespace n_element_type
       
   179 
       
   180 namespace n_constructors
       
   181 {
       
   182 
       
   183 void default_constructor()
       
   184 {
       
   185     boost::intrusive_ptr<X> px;
       
   186     BOOST_TEST(px.get() == 0);
       
   187 }
       
   188 
       
   189 void pointer_constructor()
       
   190 {
       
   191     {
       
   192         boost::intrusive_ptr<X> px(0);
       
   193         BOOST_TEST(px.get() == 0);
       
   194     }
       
   195 
       
   196     {
       
   197         boost::intrusive_ptr<X> px(0, false);
       
   198         BOOST_TEST(px.get() == 0);
       
   199     }
       
   200 
       
   201     {
       
   202         X * p = new X;
       
   203         BOOST_TEST(p->use_count() == 0);
       
   204 
       
   205         boost::intrusive_ptr<X> px(p);
       
   206         BOOST_TEST(px.get() == p);
       
   207         BOOST_TEST(px->use_count() == 1);
       
   208     }
       
   209 
       
   210     {
       
   211         X * p = new X;
       
   212         BOOST_TEST(p->use_count() == 0);
       
   213 
       
   214 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
       
   215         using boost::intrusive_ptr_add_ref;
       
   216 #endif
       
   217         intrusive_ptr_add_ref(p);
       
   218         BOOST_TEST(p->use_count() == 1);
       
   219 
       
   220         boost::intrusive_ptr<X> px(p, false);
       
   221         BOOST_TEST(px.get() == p);
       
   222         BOOST_TEST(px->use_count() == 1);
       
   223     }
       
   224 }
       
   225 
       
   226 void copy_constructor()
       
   227 {
       
   228     {
       
   229         boost::intrusive_ptr<X> px;
       
   230         boost::intrusive_ptr<X> px2(px);
       
   231         BOOST_TEST(px2.get() == px.get());
       
   232     }
       
   233 
       
   234     {
       
   235         boost::intrusive_ptr<Y> py;
       
   236         boost::intrusive_ptr<X> px(py);
       
   237         BOOST_TEST(px.get() == py.get());
       
   238     }
       
   239 
       
   240     {
       
   241         boost::intrusive_ptr<X> px(0);
       
   242         boost::intrusive_ptr<X> px2(px);
       
   243         BOOST_TEST(px2.get() == px.get());
       
   244     }
       
   245 
       
   246     {
       
   247         boost::intrusive_ptr<Y> py(0);
       
   248         boost::intrusive_ptr<X> px(py);
       
   249         BOOST_TEST(px.get() == py.get());
       
   250     }
       
   251 
       
   252     {
       
   253         boost::intrusive_ptr<X> px(0, false);
       
   254         boost::intrusive_ptr<X> px2(px);
       
   255         BOOST_TEST(px2.get() == px.get());
       
   256     }
       
   257 
       
   258     {
       
   259         boost::intrusive_ptr<Y> py(0, false);
       
   260         boost::intrusive_ptr<X> px(py);
       
   261         BOOST_TEST(px.get() == py.get());
       
   262     }
       
   263 
       
   264     {
       
   265         boost::intrusive_ptr<X> px(new X);
       
   266         boost::intrusive_ptr<X> px2(px);
       
   267         BOOST_TEST(px2.get() == px.get());
       
   268     }
       
   269 
       
   270     {
       
   271         boost::intrusive_ptr<Y> py(new Y);
       
   272         boost::intrusive_ptr<X> px(py);
       
   273         BOOST_TEST(px.get() == py.get());
       
   274     }
       
   275 }
       
   276 
       
   277 void test()
       
   278 {
       
   279     default_constructor();
       
   280     pointer_constructor();
       
   281     copy_constructor();
       
   282 }
       
   283 
       
   284 } // namespace n_constructors
       
   285 
       
   286 namespace n_destructor
       
   287 {
       
   288 
       
   289 void test()
       
   290 {
       
   291     boost::intrusive_ptr<X> px(new X);
       
   292     BOOST_TEST(px->use_count() == 1);
       
   293 
       
   294     {
       
   295         boost::intrusive_ptr<X> px2(px);
       
   296         BOOST_TEST(px->use_count() == 2);
       
   297     }
       
   298 
       
   299     BOOST_TEST(px->use_count() == 1);
       
   300 }
       
   301 
       
   302 } // namespace n_destructor
       
   303 
       
   304 namespace n_assignment
       
   305 {
       
   306 
       
   307 void copy_assignment()
       
   308 {
       
   309 }
       
   310 
       
   311 void conversion_assignment()
       
   312 {
       
   313 }
       
   314 
       
   315 void pointer_assignment()
       
   316 {
       
   317 }
       
   318 
       
   319 void test()
       
   320 {
       
   321     copy_assignment();
       
   322     conversion_assignment();
       
   323     pointer_assignment();
       
   324 }
       
   325 
       
   326 } // namespace n_assignment
       
   327 
       
   328 namespace n_access
       
   329 {
       
   330 
       
   331 void test()
       
   332 {
       
   333     {
       
   334         boost::intrusive_ptr<X> px;
       
   335         BOOST_TEST(px? false: true);
       
   336         BOOST_TEST(!px);
       
   337 
       
   338 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
       
   339         using boost::get_pointer;
       
   340 #endif
       
   341 
       
   342         BOOST_TEST(get_pointer(px) == px.get());
       
   343     }
       
   344 
       
   345     {
       
   346         boost::intrusive_ptr<X> px(0);
       
   347         BOOST_TEST(px? false: true);
       
   348         BOOST_TEST(!px);
       
   349 
       
   350 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
       
   351         using boost::get_pointer;
       
   352 #endif
       
   353 
       
   354         BOOST_TEST(get_pointer(px) == px.get());
       
   355     }
       
   356 
       
   357     {
       
   358         boost::intrusive_ptr<X> px(new X);
       
   359         BOOST_TEST(px? true: false);
       
   360         BOOST_TEST(!!px);
       
   361         BOOST_TEST(&*px == px.get());
       
   362         BOOST_TEST(px.operator ->() == px.get());
       
   363 
       
   364 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
       
   365         using boost::get_pointer;
       
   366 #endif
       
   367 
       
   368         BOOST_TEST(get_pointer(px) == px.get());
       
   369     }
       
   370 }
       
   371 
       
   372 } // namespace n_access
       
   373 
       
   374 namespace n_swap
       
   375 {
       
   376 
       
   377 void test()
       
   378 {
       
   379     {
       
   380         boost::intrusive_ptr<X> px;
       
   381         boost::intrusive_ptr<X> px2;
       
   382 
       
   383         px.swap(px2);
       
   384 
       
   385         BOOST_TEST(px.get() == 0);
       
   386         BOOST_TEST(px2.get() == 0);
       
   387 
       
   388         using std::swap;
       
   389         swap(px, px2);
       
   390 
       
   391         BOOST_TEST(px.get() == 0);
       
   392         BOOST_TEST(px2.get() == 0);
       
   393     }
       
   394 
       
   395     {
       
   396         X * p = new X;
       
   397         boost::intrusive_ptr<X> px;
       
   398         boost::intrusive_ptr<X> px2(p);
       
   399         boost::intrusive_ptr<X> px3(px2);
       
   400 
       
   401         px.swap(px2);
       
   402 
       
   403         BOOST_TEST(px.get() == p);
       
   404         BOOST_TEST(px->use_count() == 2);
       
   405         BOOST_TEST(px2.get() == 0);
       
   406         BOOST_TEST(px3.get() == p);
       
   407         BOOST_TEST(px3->use_count() == 2);
       
   408 
       
   409         using std::swap;
       
   410         swap(px, px2);
       
   411 
       
   412         BOOST_TEST(px.get() == 0);
       
   413         BOOST_TEST(px2.get() == p);
       
   414         BOOST_TEST(px2->use_count() == 2);
       
   415         BOOST_TEST(px3.get() == p);
       
   416         BOOST_TEST(px3->use_count() == 2);
       
   417     }
       
   418 
       
   419     {
       
   420         X * p1 = new X;
       
   421         X * p2 = new X;
       
   422         boost::intrusive_ptr<X> px(p1);
       
   423         boost::intrusive_ptr<X> px2(p2);
       
   424         boost::intrusive_ptr<X> px3(px2);
       
   425 
       
   426         px.swap(px2);
       
   427 
       
   428         BOOST_TEST(px.get() == p2);
       
   429         BOOST_TEST(px->use_count() == 2);
       
   430         BOOST_TEST(px2.get() == p1);
       
   431         BOOST_TEST(px2->use_count() == 1);
       
   432         BOOST_TEST(px3.get() == p2);
       
   433         BOOST_TEST(px3->use_count() == 2);
       
   434 
       
   435         using std::swap;
       
   436         swap(px, px2);
       
   437 
       
   438         BOOST_TEST(px.get() == p1);
       
   439         BOOST_TEST(px->use_count() == 1);
       
   440         BOOST_TEST(px2.get() == p2);
       
   441         BOOST_TEST(px2->use_count() == 2);
       
   442         BOOST_TEST(px3.get() == p2);
       
   443         BOOST_TEST(px3->use_count() == 2);
       
   444     }
       
   445 }
       
   446 
       
   447 } // namespace n_swap
       
   448 
       
   449 namespace n_comparison
       
   450 {
       
   451 
       
   452 template<class T, class U> void test2(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<U> const & q)
       
   453 {
       
   454     BOOST_TEST((p == q) == (p.get() == q.get()));
       
   455     BOOST_TEST((p != q) == (p.get() != q.get()));
       
   456 }
       
   457 
       
   458 template<class T> void test3(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<T> const & q)
       
   459 {
       
   460     BOOST_TEST((p == q) == (p.get() == q.get()));
       
   461     BOOST_TEST((p.get() == q) == (p.get() == q.get()));
       
   462     BOOST_TEST((p == q.get()) == (p.get() == q.get()));
       
   463     BOOST_TEST((p != q) == (p.get() != q.get()));
       
   464     BOOST_TEST((p.get() != q) == (p.get() != q.get()));
       
   465     BOOST_TEST((p != q.get()) == (p.get() != q.get()));
       
   466 
       
   467     // 'less' moved here as a g++ 2.9x parse error workaround
       
   468     std::less<T*> less;
       
   469     BOOST_TEST((p < q) == less(p.get(), q.get()));
       
   470 }
       
   471 
       
   472 void test()
       
   473 {
       
   474     {
       
   475         boost::intrusive_ptr<X> px;
       
   476         test3(px, px);
       
   477 
       
   478         boost::intrusive_ptr<X> px2;
       
   479         test3(px, px2);
       
   480 
       
   481         boost::intrusive_ptr<X> px3(px);
       
   482         test3(px3, px3);
       
   483         test3(px, px3);
       
   484     }
       
   485 
       
   486     {
       
   487         boost::intrusive_ptr<X> px;
       
   488 
       
   489         boost::intrusive_ptr<X> px2(new X);
       
   490         test3(px, px2);
       
   491         test3(px2, px2);
       
   492 
       
   493         boost::intrusive_ptr<X> px3(new X);
       
   494         test3(px2, px3);
       
   495 
       
   496         boost::intrusive_ptr<X> px4(px2);
       
   497         test3(px2, px4);
       
   498         test3(px4, px4);
       
   499     }
       
   500 
       
   501     {
       
   502         boost::intrusive_ptr<X> px(new X);
       
   503 
       
   504         boost::intrusive_ptr<Y> py(new Y);
       
   505         test2(px, py);
       
   506 
       
   507         boost::intrusive_ptr<X> px2(py);
       
   508         test2(px2, py);
       
   509         test3(px, px2);
       
   510         test3(px2, px2);
       
   511     }
       
   512 }
       
   513 
       
   514 } // namespace n_comparison
       
   515 
       
   516 namespace n_static_cast
       
   517 {
       
   518 
       
   519 void test()
       
   520 {
       
   521 }
       
   522 
       
   523 } // namespace n_static_cast
       
   524 
       
   525 namespace n_dynamic_cast
       
   526 {
       
   527 
       
   528 void test()
       
   529 {
       
   530 }
       
   531 
       
   532 } // namespace n_dynamic_cast
       
   533 
       
   534 namespace n_transitive
       
   535 {
       
   536 
       
   537 struct X: public N::base
       
   538 {
       
   539     boost::intrusive_ptr<X> next;
       
   540 };
       
   541 
       
   542 void test()
       
   543 {
       
   544     boost::intrusive_ptr<X> p(new X);
       
   545     p->next = boost::intrusive_ptr<X>(new X);
       
   546     BOOST_TEST(!p->next->next);
       
   547     p = p->next;
       
   548     BOOST_TEST(!p->next);
       
   549 }
       
   550 
       
   551 } // namespace n_transitive
       
   552 
       
   553 namespace n_report_1
       
   554 {
       
   555 
       
   556 class foo: public N::base
       
   557 {
       
   558 public:
       
   559 
       
   560     foo(): m_self(this)
       
   561     {
       
   562     }
       
   563 
       
   564     void suicide()
       
   565     {
       
   566         m_self = 0;
       
   567     }
       
   568 
       
   569 private:
       
   570 
       
   571     boost::intrusive_ptr<foo> m_self;
       
   572 };
       
   573 
       
   574 void test()
       
   575 {
       
   576     foo * foo_ptr = new foo;
       
   577     foo_ptr->suicide();
       
   578 }
       
   579 
       
   580 } // namespace n_report_1
       
   581 
       
   582 int main()
       
   583 {
       
   584 	std_log(LOG_FILENAME_LINE,"[Test Case for intrusive_ptr_test]");
       
   585     n_element_type::test();
       
   586     n_constructors::test();
       
   587     n_destructor::test();
       
   588     n_assignment::test();
       
   589     n_access::test();
       
   590     n_swap::test();
       
   591     n_comparison::test();
       
   592     n_static_cast::test();
       
   593     n_dynamic_cast::test();
       
   594 
       
   595     n_transitive::test();
       
   596     n_report_1::test();
       
   597 
       
   598 #ifdef __SYMBIAN32__
       
   599     int failures = boost::report_errors();
       
   600 	if(failures)
       
   601 	{
       
   602 		std_log(LOG_FILENAME_LINE,"Result : Failed");
       
   603 		assert_failed = true;
       
   604 	}
       
   605 	else
       
   606 	{
       
   607 		std_log(LOG_FILENAME_LINE,"Result : Passed");
       
   608 	}
       
   609 	std_log(LOG_FILENAME_LINE,"[End Test Case ]");
       
   610 #endif
       
   611 	testResultXml("intrusive_ptr_test");
       
   612 	close_log_file();
       
   613 	return failures;
       
   614 }