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 + -
显示快捷键?