intrusive_ptr_test.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 562 行
CPP
562 行
#include <boost/config.hpp>#if defined(BOOST_MSVC)#pragma warning(disable: 4786) // identifier truncated in debug info#pragma warning(disable: 4710) // function not inlined#pragma warning(disable: 4711) // function selected for automatic inline expansion#pragma warning(disable: 4514) // unreferenced inline removed#pragma warning(disable: 4355) // 'this' : used in base member initializer list#pragma warning(disable: 4511) // copy constructor could not be generated#pragma warning(disable: 4512) // assignment operator could not be generated#if (BOOST_MSVC >= 1310)#pragma warning(disable: 4675) // resolved overload found with Koenig lookup#endif#endif//// intrusive_ptr_test.cpp//// Copyright (c) 2002-2005 Peter Dimov//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//#include <boost/detail/lightweight_test.hpp>#include <boost/intrusive_ptr.hpp>#include <boost/detail/atomic_count.hpp>#include <boost/config.hpp>#include <algorithm>#include <functional>//namespace N{class base{private: boost::detail::atomic_count use_count_; base(base const &); base & operator=(base const &);protected: base(): use_count_(0) { } virtual ~base() { }public: long use_count() const { return use_count_; }#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) inline friend void intrusive_ptr_add_ref(base * p) { ++p->use_count_; } inline friend void intrusive_ptr_release(base * p) { if(--p->use_count_ == 0) delete p; }#else void add_ref() { ++use_count_; } void release() { if(--use_count_ == 0) delete this; }#endif};} // namespace N#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)namespace boost{inline void intrusive_ptr_add_ref(N::base * p){ p->add_ref();}inline void intrusive_ptr_release(N::base * p){ p->release();}} // namespace boost#endif//struct X: public virtual N::base{};struct Y: public X{};//namespace n_element_type{void f(X &){}void test(){ typedef boost::intrusive_ptr<X>::element_type T; T t; f(t);}} // namespace n_element_typenamespace n_constructors{void default_constructor(){ boost::intrusive_ptr<X> px; BOOST_TEST(px.get() == 0);}void pointer_constructor(){ { boost::intrusive_ptr<X> px(0); BOOST_TEST(px.get() == 0); } { boost::intrusive_ptr<X> px(0, false); BOOST_TEST(px.get() == 0); } { X * p = new X; BOOST_TEST(p->use_count() == 0); boost::intrusive_ptr<X> px(p); BOOST_TEST(px.get() == p); BOOST_TEST(px->use_count() == 1); } { X * p = new X; BOOST_TEST(p->use_count() == 0);#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) using boost::intrusive_ptr_add_ref;#endif intrusive_ptr_add_ref(p); BOOST_TEST(p->use_count() == 1); boost::intrusive_ptr<X> px(p, false); BOOST_TEST(px.get() == p); BOOST_TEST(px->use_count() == 1); }}void copy_constructor(){ { boost::intrusive_ptr<X> px; boost::intrusive_ptr<X> px2(px); BOOST_TEST(px2.get() == px.get()); } { boost::intrusive_ptr<Y> py; boost::intrusive_ptr<X> px(py); BOOST_TEST(px.get() == py.get()); } { boost::intrusive_ptr<X> px(0); boost::intrusive_ptr<X> px2(px); BOOST_TEST(px2.get() == px.get()); } { boost::intrusive_ptr<Y> py(0); boost::intrusive_ptr<X> px(py); BOOST_TEST(px.get() == py.get()); } { boost::intrusive_ptr<X> px(0, false); boost::intrusive_ptr<X> px2(px); BOOST_TEST(px2.get() == px.get()); } { boost::intrusive_ptr<Y> py(0, false); boost::intrusive_ptr<X> px(py); BOOST_TEST(px.get() == py.get()); } { boost::intrusive_ptr<X> px(new X); boost::intrusive_ptr<X> px2(px); BOOST_TEST(px2.get() == px.get()); } { boost::intrusive_ptr<Y> py(new Y); boost::intrusive_ptr<X> px(py); BOOST_TEST(px.get() == py.get()); }}void test(){ default_constructor(); pointer_constructor(); copy_constructor();}} // namespace n_constructorsnamespace n_destructor{void test(){ boost::intrusive_ptr<X> px(new X); BOOST_TEST(px->use_count() == 1); { boost::intrusive_ptr<X> px2(px); BOOST_TEST(px->use_count() == 2); } BOOST_TEST(px->use_count() == 1);}} // namespace n_destructornamespace n_assignment{void copy_assignment(){}void conversion_assignment(){}void pointer_assignment(){}void test(){ copy_assignment(); conversion_assignment(); pointer_assignment();}} // namespace n_assignmentnamespace n_access{void test(){ { boost::intrusive_ptr<X> px; BOOST_TEST(px? false: true); BOOST_TEST(!px);#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) using boost::get_pointer;#endif BOOST_TEST(get_pointer(px) == px.get()); } { boost::intrusive_ptr<X> px(0); BOOST_TEST(px? false: true); BOOST_TEST(!px);#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) using boost::get_pointer;#endif BOOST_TEST(get_pointer(px) == px.get()); } { boost::intrusive_ptr<X> px(new X); BOOST_TEST(px? true: false); BOOST_TEST(!!px); BOOST_TEST(&*px == px.get()); BOOST_TEST(px.operator ->() == px.get());#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) using boost::get_pointer;#endif BOOST_TEST(get_pointer(px) == px.get()); }}} // namespace n_accessnamespace n_swap{void test(){ { boost::intrusive_ptr<X> px; boost::intrusive_ptr<X> px2; px.swap(px2); BOOST_TEST(px.get() == 0); BOOST_TEST(px2.get() == 0); using std::swap; swap(px, px2); BOOST_TEST(px.get() == 0); BOOST_TEST(px2.get() == 0); } { X * p = new X; boost::intrusive_ptr<X> px; boost::intrusive_ptr<X> px2(p); boost::intrusive_ptr<X> px3(px2); px.swap(px2); BOOST_TEST(px.get() == p); BOOST_TEST(px->use_count() == 2); BOOST_TEST(px2.get() == 0); BOOST_TEST(px3.get() == p); BOOST_TEST(px3->use_count() == 2); using std::swap; swap(px, px2); BOOST_TEST(px.get() == 0); BOOST_TEST(px2.get() == p); BOOST_TEST(px2->use_count() == 2); BOOST_TEST(px3.get() == p); BOOST_TEST(px3->use_count() == 2); } { X * p1 = new X; X * p2 = new X; boost::intrusive_ptr<X> px(p1); boost::intrusive_ptr<X> px2(p2); boost::intrusive_ptr<X> px3(px2); px.swap(px2); BOOST_TEST(px.get() == p2); BOOST_TEST(px->use_count() == 2); BOOST_TEST(px2.get() == p1); BOOST_TEST(px2->use_count() == 1); BOOST_TEST(px3.get() == p2); BOOST_TEST(px3->use_count() == 2); using std::swap; swap(px, px2); BOOST_TEST(px.get() == p1); BOOST_TEST(px->use_count() == 1); BOOST_TEST(px2.get() == p2); BOOST_TEST(px2->use_count() == 2); BOOST_TEST(px3.get() == p2); BOOST_TEST(px3->use_count() == 2); }}} // namespace n_swapnamespace n_comparison{template<class T, class U> void test2(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<U> const & q){ BOOST_TEST((p == q) == (p.get() == q.get())); BOOST_TEST((p != q) == (p.get() != q.get()));}template<class T> void test3(boost::intrusive_ptr<T> const & p, boost::intrusive_ptr<T> const & q){ BOOST_TEST((p == q) == (p.get() == q.get())); BOOST_TEST((p.get() == q) == (p.get() == q.get())); BOOST_TEST((p == q.get()) == (p.get() == q.get())); BOOST_TEST((p != q) == (p.get() != q.get())); BOOST_TEST((p.get() != q) == (p.get() != q.get())); BOOST_TEST((p != q.get()) == (p.get() != q.get())); // 'less' moved here as a g++ 2.9x parse error workaround std::less<T*> less; BOOST_TEST((p < q) == less(p.get(), q.get()));}void test(){ { boost::intrusive_ptr<X> px; test3(px, px); boost::intrusive_ptr<X> px2; test3(px, px2); boost::intrusive_ptr<X> px3(px); test3(px3, px3); test3(px, px3); } { boost::intrusive_ptr<X> px; boost::intrusive_ptr<X> px2(new X); test3(px, px2); test3(px2, px2); boost::intrusive_ptr<X> px3(new X); test3(px2, px3); boost::intrusive_ptr<X> px4(px2); test3(px2, px4); test3(px4, px4); } { boost::intrusive_ptr<X> px(new X); boost::intrusive_ptr<Y> py(new Y); test2(px, py); boost::intrusive_ptr<X> px2(py); test2(px2, py); test3(px, px2); test3(px2, px2); }}} // namespace n_comparisonnamespace n_static_cast{void test(){}} // namespace n_static_castnamespace n_dynamic_cast{void test(){}} // namespace n_dynamic_castnamespace n_transitive{struct X: public N::base{ boost::intrusive_ptr<X> next;};void test(){ boost::intrusive_ptr<X> p(new X); p->next = boost::intrusive_ptr<X>(new X); BOOST_TEST(!p->next->next); p = p->next; BOOST_TEST(!p->next);}} // namespace n_transitivenamespace n_report_1{class foo: public N::base{ public: foo(): m_self(this) { } void suicide() { m_self = 0; }private: boost::intrusive_ptr<foo> m_self;}; void test(){ foo * foo_ptr = new foo; foo_ptr->suicide();} } // namespace n_report_1int main(){ n_element_type::test(); n_constructors::test(); n_destructor::test(); n_assignment::test(); n_access::test(); n_swap::test(); n_comparison::test(); n_static_cast::test(); n_dynamic_cast::test(); n_transitive::test(); n_report_1::test(); return boost::report_errors();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?