intrusive_ptr_test.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 519 行

CPP
519
字号
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Peter Dimov 2002-2005.// (C) Copyright Ion Gaztanaga 2006. 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)//// See http://www.boost.org/libs/interprocess for documentation.////////////////////////////////////////////////////////////////////////////////#include <boost/interprocess/detail/config_begin.hpp>#include <boost/interprocess/offset_ptr.hpp>#include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/detail/lightweight_test.hpp>#include <boost/config.hpp>#include <algorithm>#include <functional>typedef boost::interprocess::offset_ptr<void> VP;namespace N{class base{   private:   int use_count_;   base(base const &);   base & operator=(base const &);   protected:   base(): use_count_(0)   {   }   virtual ~base()   {   }   public:   long use_count() const   {      return use_count_;   }   void add_ref()   {      ++use_count_;   }   void release()   {      if(--use_count_ == 0) delete this;   }};inline void intrusive_ptr_add_ref(N::base *p){  p->add_ref();  }inline void intrusive_ptr_release(N::base *p){  p->release();  }} // namespace Nstruct X: public virtual N::base{};struct Y: public X{};//namespace n_element_type{void f(X &){}void test(){   typedef boost::interprocess::intrusive_ptr<X, VP>::element_type T;   T t;   f(t);}} // namespace n_element_typenamespace n_constructors{void default_constructor(){   boost::interprocess::intrusive_ptr<X, VP> px;   BOOST_TEST(px.get() == 0);}void pointer_constructor(){   {      boost::interprocess::intrusive_ptr<X, VP> px(0);      BOOST_TEST(px.get() == 0);   }   {      boost::interprocess::intrusive_ptr<X, VP> px(0, false);      BOOST_TEST(px.get() == 0);   }   {      boost::interprocess::offset_ptr<X> p = new X;      BOOST_TEST(p->use_count() == 0);      boost::interprocess::intrusive_ptr<X, VP> px(p);      BOOST_TEST(px.get() == p);      BOOST_TEST(px->use_count() == 1);   }   {      boost::interprocess::offset_ptr<X> p = new X;      BOOST_TEST(p->use_count() == 0);      intrusive_ptr_add_ref(get_pointer(p));      BOOST_TEST(p->use_count() == 1);      boost::interprocess::intrusive_ptr<X, VP> px(p, false);      BOOST_TEST(px.get() == p);      BOOST_TEST(px->use_count() == 1);   }}void copy_constructor(){   {      boost::interprocess::intrusive_ptr<X, VP> px;      boost::interprocess::intrusive_ptr<X, VP> px2(px);      BOOST_TEST(px2.get() == px.get());   }   {      boost::interprocess::intrusive_ptr<Y, VP> py;      boost::interprocess::intrusive_ptr<X, VP> px(py);      BOOST_TEST(px.get() == py.get());   }   {      boost::interprocess::intrusive_ptr<X, VP> px(0);      boost::interprocess::intrusive_ptr<X, VP> px2(px);      BOOST_TEST(px2.get() == px.get());   }   {      boost::interprocess::intrusive_ptr<Y, VP> py(0);      boost::interprocess::intrusive_ptr<X, VP> px(py);      BOOST_TEST(px.get() == py.get());   }   {      boost::interprocess::intrusive_ptr<X, VP> px(0, false);      boost::interprocess::intrusive_ptr<X, VP> px2(px);      BOOST_TEST(px2.get() == px.get());   }   {      boost::interprocess::intrusive_ptr<Y, VP> py(0, false);      boost::interprocess::intrusive_ptr<X, VP> px(py);      BOOST_TEST(px.get() == py.get());   }   {      boost::interprocess::intrusive_ptr<X, VP> px(new X);      boost::interprocess::intrusive_ptr<X, VP> px2(px);      BOOST_TEST(px2.get() == px.get());   }   {      boost::interprocess::intrusive_ptr<Y, VP> py(new Y);      boost::interprocess::intrusive_ptr<X, VP> px(py);      BOOST_TEST(px.get() == py.get());   }}void test(){   default_constructor();   pointer_constructor();   copy_constructor();}} // namespace n_constructorsnamespace n_destructor{void test(){   boost::interprocess::intrusive_ptr<X, VP> px(new X);   BOOST_TEST(px->use_count() == 1);   {      boost::interprocess::intrusive_ptr<X, VP> 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::interprocess::intrusive_ptr<X, VP> 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::interprocess::intrusive_ptr<X, VP> 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());   }   {#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)      using boost::get_pointer;#endif      boost::interprocess::intrusive_ptr<X, VP> px         (boost::interprocess::offset_ptr<X>(new X));      BOOST_TEST(px? true: false);      BOOST_TEST(!!px);      BOOST_TEST(&*px == get_pointer(px.get()));      BOOST_TEST(px.operator ->() == px.get());      BOOST_TEST(get_pointer(px) == px.get());   }}} // namespace n_accessnamespace n_swap{void test(){   {      boost::interprocess::intrusive_ptr<X, VP> px;      boost::interprocess::intrusive_ptr<X, VP> 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);   }   {      boost::interprocess::offset_ptr<X> p = new X;      boost::interprocess::intrusive_ptr<X, VP> px;      boost::interprocess::intrusive_ptr<X, VP> px2(p);      boost::interprocess::intrusive_ptr<X, VP> 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);   }   {      boost::interprocess::offset_ptr<X> p1 = new X;      boost::interprocess::offset_ptr<X> p2 = new X;      boost::interprocess::intrusive_ptr<X, VP> px(p1);      boost::interprocess::intrusive_ptr<X, VP> px2(p2);      boost::interprocess::intrusive_ptr<X, VP> 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, class VP>void test2(boost::interprocess::intrusive_ptr<T, VP> const & p,           boost::interprocess::intrusive_ptr<U, VP> const & q){   BOOST_TEST((p == q) == (p.get() == q.get()));   BOOST_TEST((p != q) == (p.get() != q.get()));}template<class T, class VP>void test3(boost::interprocess::intrusive_ptr<T, VP> const & p,           boost::interprocess::intrusive_ptr<T, VP> 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<boost::interprocess::offset_ptr<T> > less;   BOOST_TEST((p < q) == less(p.get(), q.get()));}void test(){   {      boost::interprocess::intrusive_ptr<X, VP> px;      test3(px, px);      boost::interprocess::intrusive_ptr<X, VP> px2;      test3(px, px2);      boost::interprocess::intrusive_ptr<X, VP> px3(px);      test3(px3, px3);      test3(px, px3);   }   {      boost::interprocess::intrusive_ptr<X, VP> px;      boost::interprocess::intrusive_ptr<X, VP> px2(new X);      test3(px, px2);      test3(px2, px2);      boost::interprocess::intrusive_ptr<X, VP> px3(new X);      test3(px2, px3);      boost::interprocess::intrusive_ptr<X, VP> px4(px2);      test3(px2, px4);      test3(px4, px4);   }   {      boost::interprocess::intrusive_ptr<X, VP> px(new X);      boost::interprocess::intrusive_ptr<Y, VP> py(new Y);      test2(px, py);      boost::interprocess::intrusive_ptr<X, VP> 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::interprocess::intrusive_ptr<X, VP> next;};void test(){   boost::interprocess::intrusive_ptr<X, VP> p(new X);   p->next = boost::interprocess::intrusive_ptr<X, VP>(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::interprocess::intrusive_ptr<foo, VP> m_self;}; void test(){   boost::interprocess::offset_ptr<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();}#include <boost/interprocess/detail/config_end.hpp>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?