forked from boostorg/smart_ptr
Moved smart_ptr contents to subdirectories, switched to a local test/Jamfile.
[SVN r17042]
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
# Boost.SmartPtr Library test Jamfile
|
||||
|
||||
subproject libs/smart_ptr/test ;
|
||||
|
||||
# bring in rules for testing
|
||||
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
|
||||
include testing.jam ;
|
||||
|
||||
# Make tests run by default.
|
||||
DEPENDS all : test ;
|
||||
|
||||
{
|
||||
# look in BOOST_ROOT for sources first, just in this Jamfile
|
||||
local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ;
|
||||
|
||||
test-suite "smart_ptr"
|
||||
: [ run libs/smart_ptr/test/smart_ptr_test.cpp ]
|
||||
[ run libs/smart_ptr/test/shared_ptr_basic_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
|
||||
[ run libs/smart_ptr/test/shared_ptr_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
|
||||
[ run libs/smart_ptr/test/weak_ptr_test.cpp ]
|
||||
[ run libs/smart_ptr/test/shared_from_this_test.cpp : : : <gcc><*><cxxflags>-Wno-non-virtual-dtor ]
|
||||
[ run libs/smart_ptr/test/get_deleter_test.cpp ]
|
||||
[ compile-fail libs/smart_ptr/test/shared_ptr_assign_fail.cpp ]
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// get_deleter_test.cpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
struct deleter
|
||||
{
|
||||
int data;
|
||||
|
||||
deleter(): data(0)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(void *)
|
||||
{
|
||||
BOOST_TEST(data == 17041);
|
||||
}
|
||||
};
|
||||
|
||||
struct deleter2
|
||||
{
|
||||
};
|
||||
|
||||
struct X
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::shared_ptr<X> p;
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<X> p(new X);
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
}
|
||||
|
||||
{
|
||||
X x;
|
||||
boost::shared_ptr<X> p(&x, deleter());
|
||||
|
||||
BOOST_TEST(boost::get_deleter<void>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<void const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<int const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<X const>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2>(p) == 0);
|
||||
BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0);
|
||||
|
||||
deleter * q = boost::get_deleter<deleter>(p);
|
||||
|
||||
BOOST_TEST(q != 0);
|
||||
BOOST_TEST(q->data == 0);
|
||||
|
||||
q->data = 17041;
|
||||
|
||||
deleter const * r = boost::get_deleter<deleter const>(p);
|
||||
|
||||
BOOST_TEST(r == q);
|
||||
BOOST_TEST(r->data == 17041);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
|
||||
#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
|
||||
#endif
|
||||
|
||||
//
|
||||
// intrusive_ptr_test.cpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
//
|
||||
|
||||
namespace N
|
||||
{
|
||||
|
||||
class base
|
||||
{
|
||||
private:
|
||||
|
||||
long 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_type
|
||||
|
||||
namespace 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_constructors
|
||||
|
||||
namespace 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_destructor
|
||||
|
||||
namespace n_assignment
|
||||
{
|
||||
|
||||
void copy_assignment()
|
||||
{
|
||||
}
|
||||
|
||||
void conversion_assignment()
|
||||
{
|
||||
}
|
||||
|
||||
void pointer_assignment()
|
||||
{
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
copy_assignment();
|
||||
conversion_assignment();
|
||||
pointer_assignment();
|
||||
}
|
||||
|
||||
} // namespace n_assignment
|
||||
|
||||
namespace 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_access
|
||||
|
||||
namespace 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_swap
|
||||
|
||||
namespace 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_comparison
|
||||
|
||||
namespace n_static_cast
|
||||
{
|
||||
|
||||
void test()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace n_static_cast
|
||||
|
||||
namespace n_dynamic_cast
|
||||
{
|
||||
|
||||
void test()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace n_dynamic_cast
|
||||
|
||||
namespace 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_transitive
|
||||
|
||||
namespace 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_1
|
||||
|
||||
int 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();
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
|
||||
#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
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_from_this_test.cpp
|
||||
//
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
class X
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void f() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
~X() {}
|
||||
};
|
||||
|
||||
class Y
|
||||
{
|
||||
public:
|
||||
|
||||
virtual boost::shared_ptr<X> getX() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
~Y() {}
|
||||
};
|
||||
|
||||
boost::shared_ptr<Y> createY();
|
||||
|
||||
void test()
|
||||
{
|
||||
boost::shared_ptr<Y> py = createY();
|
||||
BOOST_TEST(py.get() != 0);
|
||||
BOOST_TEST(py.use_count() == 1);
|
||||
|
||||
boost::shared_ptr<X> px = py->getX();
|
||||
BOOST_TEST(px.get() != 0);
|
||||
BOOST_TEST(py.use_count() == 2);
|
||||
|
||||
px->f();
|
||||
|
||||
boost::shared_ptr<Y> py2 = boost::dynamic_pointer_cast<Y>(px);
|
||||
BOOST_TEST(py.get() == py2.get());
|
||||
BOOST_TEST(!(py < py2 || py2 < py));
|
||||
BOOST_TEST(py.use_count() == 3);
|
||||
}
|
||||
|
||||
void test2();
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
test2();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
// virtual inheritance from Y to stress the implementation
|
||||
// (prevents Y* -> impl* casts)
|
||||
|
||||
class impl: public X, public virtual Y, public boost::enable_shared_from_this<impl>
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void f()
|
||||
{
|
||||
}
|
||||
|
||||
virtual boost::shared_ptr<X> getX()
|
||||
{
|
||||
boost::shared_ptr<impl> pi = shared_from_this();
|
||||
BOOST_TEST(pi.get() == this);
|
||||
return pi;
|
||||
}
|
||||
};
|
||||
|
||||
// intermediate impl2 to stress the implementation
|
||||
|
||||
class impl2: public impl
|
||||
{
|
||||
};
|
||||
|
||||
boost::shared_ptr<Y> createY()
|
||||
{
|
||||
boost::shared_ptr<Y> pi(new impl2);
|
||||
return pi;
|
||||
}
|
||||
|
||||
void test2()
|
||||
{
|
||||
boost::shared_ptr<Y> pi(static_cast<impl2*>(0));
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// shared_ptr_alloc_test.cpp - use to evaluate the impact of count allocations
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
|
||||
int const n = 1024 * 1024;
|
||||
|
||||
template<class T> void test(T * = 0)
|
||||
{
|
||||
std::vector< boost::shared_ptr<T> > v;
|
||||
|
||||
std::clock_t t = std::clock();
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
boost::shared_ptr<T> pi(new T(i));
|
||||
v.push_back(pi);
|
||||
}
|
||||
|
||||
t = std::clock() - t;
|
||||
|
||||
std::cout << static_cast<double>(t) / CLOCKS_PER_SEC << '\n';
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
public:
|
||||
|
||||
explicit X(int n): n_(n)
|
||||
{
|
||||
}
|
||||
|
||||
void * operator new(std::size_t)
|
||||
{
|
||||
return std::allocator<X>().allocate(1, static_cast<X*>(0));
|
||||
}
|
||||
|
||||
void operator delete(void * p)
|
||||
{
|
||||
std::allocator<X>().deallocate(static_cast<X*>(p), 1);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
X(X const &);
|
||||
X & operator=(X const &);
|
||||
|
||||
int n_;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << BOOST_COMPILER "\n";
|
||||
std::cout << BOOST_PLATFORM "\n";
|
||||
std::cout << BOOST_STDLIB "\n";
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
std::cout << "BOOST_HAS_THREADS: (defined)\n";
|
||||
#else
|
||||
std::cout << "BOOST_HAS_THREADS: (not defined)\n";
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
||||
std::cout << "BOOST_SP_USE_STD_ALLOCATOR: (defined)\n";
|
||||
#else
|
||||
std::cout << "BOOST_SP_USE_STD_ALLOCATOR: (not defined)\n";
|
||||
#endif
|
||||
|
||||
std::cout << n << " shared_ptr<int> allocations + deallocations:\n";
|
||||
|
||||
test<int>();
|
||||
test<int>();
|
||||
test<int>();
|
||||
|
||||
std::cout << n << " shared_ptr<X> allocations + deallocations:\n";
|
||||
|
||||
test<X>();
|
||||
test<X>();
|
||||
test<X>();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#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
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_assign_fail.cpp - a negative test for shared_ptr assignment
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
bool boost_error(char const *, char const *, char const *, long)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::shared_ptr<int> p;
|
||||
p = new int(42); // assignment must fail
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
//
|
||||
// shared_ptr_basic_test.cpp
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
struct X
|
||||
{
|
||||
X()
|
||||
{
|
||||
++cnt;
|
||||
}
|
||||
|
||||
~X() // virtual destructor deliberately omitted
|
||||
{
|
||||
--cnt;
|
||||
}
|
||||
|
||||
virtual int id() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
X(X const &);
|
||||
X & operator= (X const &);
|
||||
};
|
||||
|
||||
struct Y: public X
|
||||
{
|
||||
Y()
|
||||
{
|
||||
++cnt;
|
||||
}
|
||||
|
||||
~Y()
|
||||
{
|
||||
--cnt;
|
||||
}
|
||||
|
||||
virtual int id() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Y(Y const &);
|
||||
Y & operator= (Y const &);
|
||||
};
|
||||
|
||||
int * get_object()
|
||||
{
|
||||
++cnt;
|
||||
return &cnt;
|
||||
}
|
||||
|
||||
void release_object(int * p)
|
||||
{
|
||||
BOOST_TEST(p == &cnt);
|
||||
--cnt;
|
||||
}
|
||||
|
||||
template<class T> void test_is_X(boost::shared_ptr<T> const & p)
|
||||
{
|
||||
BOOST_TEST(p->id() == 1);
|
||||
BOOST_TEST((*p).id() == 1);
|
||||
}
|
||||
|
||||
template<class T> void test_is_X(boost::weak_ptr<T> const & p)
|
||||
{
|
||||
BOOST_TEST(p.get() != 0);
|
||||
BOOST_TEST(p.get()->id() == 1);
|
||||
}
|
||||
|
||||
template<class T> void test_is_Y(boost::shared_ptr<T> const & p)
|
||||
{
|
||||
BOOST_TEST(p->id() == 2);
|
||||
BOOST_TEST((*p).id() == 2);
|
||||
}
|
||||
|
||||
template<class T> void test_is_Y(boost::weak_ptr<T> const & p)
|
||||
{
|
||||
boost::shared_ptr<T> q = boost::make_shared(p);
|
||||
BOOST_TEST(q.get() != 0);
|
||||
BOOST_TEST(q->id() == 2);
|
||||
}
|
||||
|
||||
template<class T> void test_eq(T const & a, T const & b)
|
||||
{
|
||||
BOOST_TEST(a == b);
|
||||
BOOST_TEST(!(a != b));
|
||||
BOOST_TEST(!(a < b));
|
||||
BOOST_TEST(!(b < a));
|
||||
}
|
||||
|
||||
template<class T> void test_ne(T const & a, T const & b)
|
||||
{
|
||||
BOOST_TEST(!(a == b));
|
||||
BOOST_TEST(a != b);
|
||||
BOOST_TEST(a < b || b < a);
|
||||
BOOST_TEST(!(a < b && b < a));
|
||||
}
|
||||
|
||||
template<class T, class U> void test_shared(boost::weak_ptr<T> const & a, boost::weak_ptr<U> const & b)
|
||||
{
|
||||
BOOST_TEST(!(a < b));
|
||||
BOOST_TEST(!(b < a));
|
||||
}
|
||||
|
||||
template<class T, class U> void test_nonshared(boost::weak_ptr<T> const & a, boost::weak_ptr<U> const & b)
|
||||
{
|
||||
BOOST_TEST(a < b || b < a);
|
||||
BOOST_TEST(!(a < b && b < a));
|
||||
}
|
||||
|
||||
template<class T, class U> void test_eq2(T const & a, U const & b)
|
||||
{
|
||||
BOOST_TEST(a == b);
|
||||
BOOST_TEST(!(a != b));
|
||||
}
|
||||
|
||||
template<class T, class U> void test_ne2(T const & a, U const & b)
|
||||
{
|
||||
BOOST_TEST(!(a == b));
|
||||
BOOST_TEST(a != b);
|
||||
}
|
||||
|
||||
template<class T> void test_is_zero(boost::shared_ptr<T> const & p)
|
||||
{
|
||||
BOOST_TEST(!p);
|
||||
BOOST_TEST(p.get() == 0);
|
||||
}
|
||||
|
||||
template<class T> void test_is_nonzero(boost::shared_ptr<T> const & p)
|
||||
{
|
||||
// p? true: false is used to test p in a boolean context.
|
||||
// BOOST_TEST(p) is not guaranteed to test the conversion,
|
||||
// as the macro might test !!p instead.
|
||||
BOOST_TEST(p? true: false);
|
||||
BOOST_TEST(p.get() != 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
{
|
||||
shared_ptr<X> p(new Y);
|
||||
shared_ptr<X> p2(new X);
|
||||
|
||||
test_is_nonzero(p);
|
||||
test_is_nonzero(p2);
|
||||
test_is_Y(p);
|
||||
test_is_X(p2);
|
||||
test_ne(p, p2);
|
||||
|
||||
{
|
||||
shared_ptr<X> q(p);
|
||||
test_eq(p, q);
|
||||
}
|
||||
|
||||
shared_ptr<Y> p3 = dynamic_pointer_cast<Y>(p);
|
||||
shared_ptr<Y> p4 = dynamic_pointer_cast<Y>(p2);
|
||||
|
||||
test_is_nonzero(p3);
|
||||
test_is_zero(p4);
|
||||
|
||||
BOOST_TEST(p.use_count() == 2);
|
||||
BOOST_TEST(p2.use_count() == 1);
|
||||
BOOST_TEST(p3.use_count() == 2);
|
||||
|
||||
test_is_Y(p3);
|
||||
test_eq2(p, p3);
|
||||
test_ne2(p2, p4);
|
||||
|
||||
shared_ptr<void> p5(p);
|
||||
|
||||
test_is_nonzero(p5);
|
||||
test_eq2(p, p5);
|
||||
|
||||
weak_ptr<X> wp1(p2);
|
||||
|
||||
BOOST_TEST(!wp1.expired());
|
||||
BOOST_TEST(wp1.use_count() != 0);
|
||||
|
||||
p.reset();
|
||||
p2.reset();
|
||||
p3.reset();
|
||||
p4.reset();
|
||||
|
||||
test_is_zero(p);
|
||||
test_is_zero(p2);
|
||||
test_is_zero(p3);
|
||||
test_is_zero(p4);
|
||||
|
||||
BOOST_TEST(p5.use_count() == 1);
|
||||
|
||||
BOOST_TEST(wp1.expired());
|
||||
BOOST_TEST(wp1.use_count() == 0);
|
||||
|
||||
try
|
||||
{
|
||||
shared_ptr<X> sp1(wp1);
|
||||
BOOST_ERROR("shared_ptr<X> sp1(wp1) failed to throw");
|
||||
}
|
||||
catch(boost::bad_weak_ptr const &)
|
||||
{
|
||||
}
|
||||
|
||||
test_is_zero(boost::make_shared(wp1));
|
||||
|
||||
weak_ptr<X> wp2 = static_pointer_cast<X>(p5);
|
||||
|
||||
BOOST_TEST(wp2.use_count() == 1);
|
||||
test_is_Y(wp2);
|
||||
test_nonshared(wp1, wp2);
|
||||
|
||||
// Scoped to not affect the subsequent use_count() tests.
|
||||
{
|
||||
shared_ptr<X> sp2(wp2);
|
||||
test_is_nonzero(boost::make_shared(wp2));
|
||||
}
|
||||
|
||||
weak_ptr<Y> wp3 = dynamic_pointer_cast<Y>(boost::make_shared(wp2));
|
||||
|
||||
BOOST_TEST(wp3.use_count() == 1);
|
||||
test_shared(wp2, wp3);
|
||||
|
||||
weak_ptr<X> wp4(wp3);
|
||||
|
||||
BOOST_TEST(wp4.use_count() == 1);
|
||||
test_shared(wp2, wp4);
|
||||
|
||||
wp1 = p2;
|
||||
test_is_zero(boost::make_shared(wp1));
|
||||
|
||||
wp1 = p4;
|
||||
wp1 = wp3;
|
||||
wp1 = wp2;
|
||||
|
||||
BOOST_TEST(wp1.use_count() == 1);
|
||||
test_shared(wp1, wp2);
|
||||
|
||||
weak_ptr<X> wp5;
|
||||
|
||||
bool b1 = wp1 < wp5;
|
||||
bool b2 = wp5 < wp1;
|
||||
|
||||
p5.reset();
|
||||
|
||||
BOOST_TEST(wp1.use_count() == 0);
|
||||
BOOST_TEST(wp2.use_count() == 0);
|
||||
BOOST_TEST(wp3.use_count() == 0);
|
||||
|
||||
// Test operator< stability for std::set< weak_ptr<> >
|
||||
// Thanks to Joe Gottman for pointing this out
|
||||
|
||||
BOOST_TEST(b1 == (wp1 < wp5));
|
||||
BOOST_TEST(b2 == (wp5 < wp1));
|
||||
|
||||
{
|
||||
// note that both get_object and release_object deal with int*
|
||||
shared_ptr<void> p6(get_object(), release_object);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST(cnt == 0);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
|
||||
#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
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_mt_test.cpp - tests shared_ptr with multiple threads
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
|
||||
// 'portable' thread framework
|
||||
|
||||
class abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~abstract_thread() {}
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS)
|
||||
|
||||
char const * title = "Using Windows threads";
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
typedef HANDLE pthread_t;
|
||||
|
||||
unsigned __stdcall common_thread_routine(void * pv)
|
||||
{
|
||||
abstract_thread * pt = static_cast<abstract_thread *>(pv);
|
||||
pt->run();
|
||||
delete pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg)
|
||||
{
|
||||
HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0);
|
||||
|
||||
if(h != 0)
|
||||
{
|
||||
*thread = h;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // return errno;
|
||||
}
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void ** /*value_ptr*/)
|
||||
{
|
||||
::WaitForSingleObject(thread, INFINITE);
|
||||
::CloseHandle(thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char const * title = "Using POSIX threads";
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
extern "C" void * common_thread_routine(void * pv)
|
||||
{
|
||||
abstract_thread * pt = static_cast<abstract_thread *>(pv);
|
||||
pt->run();
|
||||
delete pt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
template<class F> class thread: public abstract_thread
|
||||
{
|
||||
public:
|
||||
|
||||
explicit thread(F f): f_(f)
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
f_();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
F f_;
|
||||
};
|
||||
|
||||
template<class F> pthread_t createThread(F f)
|
||||
{
|
||||
std::auto_ptr<abstract_thread> p(new thread<F>(f));
|
||||
|
||||
pthread_t r;
|
||||
|
||||
if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0)
|
||||
{
|
||||
p.release();
|
||||
return r;
|
||||
}
|
||||
|
||||
throw std::runtime_error("createThread failed.");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
int const n = 1024 * 1024;
|
||||
|
||||
void test(boost::shared_ptr<int> const & pi)
|
||||
{
|
||||
std::vector< boost::shared_ptr<int> > v;
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
v.push_back(pi);
|
||||
}
|
||||
}
|
||||
|
||||
int const m = 16; // threads
|
||||
|
||||
#if defined(BOOST_LWM_USE_CRITICAL_SECTION)
|
||||
char const * implementation = "critical section";
|
||||
#elif defined(BOOST_LWM_USE_PTHREADS)
|
||||
char const * implementation = "pthread_mutex";
|
||||
#else
|
||||
char const * implementation = "spinlock";
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
std::printf("%s: %s, %d threads, %d iterations: ", title, implementation, m, n);
|
||||
|
||||
boost::shared_ptr<int> pi(new int(42));
|
||||
|
||||
std::clock_t t = std::clock();
|
||||
|
||||
pthread_t a[m];
|
||||
|
||||
for(int i = 0; i < m; ++i)
|
||||
{
|
||||
a[i] = createThread( boost::bind(test, pi) );
|
||||
}
|
||||
|
||||
for(int i = 0; i < m; ++i)
|
||||
{
|
||||
pthread_join(a[i], 0);
|
||||
}
|
||||
|
||||
t = std::clock() - t;
|
||||
|
||||
std::printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL) && !defined(__COMO__)
|
||||
#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
|
||||
#endif
|
||||
|
||||
//
|
||||
// shared_ptr_timing_test.cpp - use to evaluate the impact of thread safety
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
|
||||
int const n = 8 * 1024 * 1024;
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector< boost::shared_ptr<int> > v;
|
||||
boost::shared_ptr<int> pi(new int);
|
||||
|
||||
std::clock_t t = std::clock();
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
v.push_back(pi);
|
||||
}
|
||||
|
||||
t = std::clock() - t;
|
||||
|
||||
std::cout << static_cast<double>(t) / CLOCKS_PER_SEC << '\n';
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
// smart pointer test program ----------------------------------------------//
|
||||
|
||||
// (C) Copyright Beman Dawes 1998, 1999. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright notice
|
||||
// appears in all copies. This software is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// Revision History
|
||||
// 24 May 01 use Boost test library for error detection, reporting, add tests
|
||||
// for operations on incomplete types (Beman Dawes)
|
||||
// 29 Nov 99 added std::swap and associative container tests (Darin Adler)
|
||||
// 25 Sep 99 added swap tests
|
||||
// 20 Jul 99 header name changed to .hpp
|
||||
// 20 Apr 99 additional error tests added.
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
class Incomplete;
|
||||
|
||||
Incomplete * get_ptr( boost::shared_ptr<Incomplete>& incomplete )
|
||||
{
|
||||
return incomplete.get();
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using boost::scoped_ptr;
|
||||
using boost::scoped_array;
|
||||
using boost::shared_ptr;
|
||||
using boost::shared_array;
|
||||
|
||||
template<class T>
|
||||
void ck( const T* v1, T v2 ) { BOOST_TEST( *v1 == v2 ); }
|
||||
|
||||
namespace {
|
||||
int UDT_use_count; // independent of pointer maintained counts
|
||||
}
|
||||
|
||||
// user defined type -------------------------------------------------------//
|
||||
|
||||
class UDT {
|
||||
long value_;
|
||||
public:
|
||||
explicit UDT( long value=0 ) : value_(value) { ++UDT_use_count; }
|
||||
~UDT() {
|
||||
--UDT_use_count;
|
||||
cout << "UDT with value " << value_ << " being destroyed\n";
|
||||
}
|
||||
long value() const { return value_; }
|
||||
void value( long v ) { value_ = v;; }
|
||||
}; // UDT
|
||||
|
||||
// tests on incomplete types -----------------------------------------------//
|
||||
|
||||
// Certain smart pointer operations are specified to work on incomplete types,
|
||||
// and some uses depend upon this feature. These tests verify compilation
|
||||
// only - the functions aren't actually invoked.
|
||||
|
||||
class Incomplete;
|
||||
|
||||
Incomplete * check_incomplete( scoped_ptr<Incomplete>& incomplete )
|
||||
{
|
||||
return incomplete.get();
|
||||
}
|
||||
|
||||
Incomplete * check_incomplete( shared_ptr<Incomplete>& incomplete,
|
||||
shared_ptr<Incomplete>& i2 )
|
||||
{
|
||||
incomplete.swap(i2);
|
||||
cout << incomplete.use_count() << ' ' << incomplete.unique() << '\n';
|
||||
return incomplete.get();
|
||||
}
|
||||
|
||||
// This isn't a very systematic test; it just hits some of the basics.
|
||||
|
||||
void test()
|
||||
{
|
||||
BOOST_TEST( UDT_use_count == 0 ); // reality check
|
||||
|
||||
// test scoped_ptr with a built-in type
|
||||
long * lp = new long;
|
||||
scoped_ptr<long> sp ( lp );
|
||||
BOOST_TEST( sp.get() == lp );
|
||||
BOOST_TEST( lp == sp.get() );
|
||||
BOOST_TEST( &*sp == lp );
|
||||
|
||||
*sp = 1234568901L;
|
||||
BOOST_TEST( *sp == 1234568901L );
|
||||
BOOST_TEST( *lp == 1234568901L );
|
||||
ck( static_cast<long*>(sp.get()), 1234568901L );
|
||||
ck( lp, *sp );
|
||||
|
||||
sp.reset();
|
||||
BOOST_TEST( sp.get() == 0 );
|
||||
|
||||
// test scoped_ptr with a user defined type
|
||||
scoped_ptr<UDT> udt_sp ( new UDT( 999888777 ) );
|
||||
BOOST_TEST( udt_sp->value() == 999888777 );
|
||||
udt_sp.reset();
|
||||
udt_sp.reset( new UDT( 111222333 ) );
|
||||
BOOST_TEST( udt_sp->value() == 111222333 );
|
||||
udt_sp.reset( new UDT( 333222111 ) );
|
||||
BOOST_TEST( udt_sp->value() == 333222111 );
|
||||
|
||||
// test scoped_array with a build-in type
|
||||
char * sap = new char [ 100 ];
|
||||
scoped_array<char> sa ( sap );
|
||||
BOOST_TEST( sa.get() == sap );
|
||||
BOOST_TEST( sap == sa.get() );
|
||||
|
||||
strcpy( sa.get(), "Hot Dog with mustard and relish" );
|
||||
BOOST_TEST( strcmp( sa.get(), "Hot Dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( strcmp( sap, "Hot Dog with mustard and relish" ) == 0 );
|
||||
|
||||
BOOST_TEST( sa[0] == 'H' );
|
||||
BOOST_TEST( sa[30] == 'h' );
|
||||
|
||||
sa[0] = 'N';
|
||||
sa[4] = 'd';
|
||||
BOOST_TEST( strcmp( sap, "Not dog with mustard and relish" ) == 0 );
|
||||
|
||||
sa.reset();
|
||||
BOOST_TEST( sa.get() == 0 );
|
||||
|
||||
// test shared_ptr with a built-in type
|
||||
int * ip = new int;
|
||||
shared_ptr<int> cp ( ip );
|
||||
BOOST_TEST( ip == cp.get() );
|
||||
BOOST_TEST( cp.use_count() == 1 );
|
||||
|
||||
*cp = 54321;
|
||||
BOOST_TEST( *cp == 54321 );
|
||||
BOOST_TEST( *ip == 54321 );
|
||||
ck( static_cast<int*>(cp.get()), 54321 );
|
||||
ck( static_cast<int*>(ip), *cp );
|
||||
|
||||
shared_ptr<int> cp2 ( cp );
|
||||
BOOST_TEST( ip == cp2.get() );
|
||||
BOOST_TEST( cp.use_count() == 2 );
|
||||
BOOST_TEST( cp2.use_count() == 2 );
|
||||
|
||||
BOOST_TEST( *cp == 54321 );
|
||||
BOOST_TEST( *cp2 == 54321 );
|
||||
ck( static_cast<int*>(cp2.get()), 54321 );
|
||||
ck( static_cast<int*>(ip), *cp2 );
|
||||
|
||||
shared_ptr<int> cp3 ( cp );
|
||||
BOOST_TEST( cp.use_count() == 3 );
|
||||
BOOST_TEST( cp2.use_count() == 3 );
|
||||
BOOST_TEST( cp3.use_count() == 3 );
|
||||
cp.reset();
|
||||
BOOST_TEST( cp2.use_count() == 2 );
|
||||
BOOST_TEST( cp3.use_count() == 2 );
|
||||
cp.reset( new int );
|
||||
*cp = 98765;
|
||||
BOOST_TEST( *cp == 98765 );
|
||||
*cp3 = 87654;
|
||||
BOOST_TEST( *cp3 == 87654 );
|
||||
BOOST_TEST( *cp2 == 87654 );
|
||||
cp.swap( cp3 );
|
||||
BOOST_TEST( *cp == 87654 );
|
||||
BOOST_TEST( *cp2 == 87654 );
|
||||
BOOST_TEST( *cp3 == 98765 );
|
||||
cp.swap( cp3 );
|
||||
BOOST_TEST( *cp == 98765 );
|
||||
BOOST_TEST( *cp2 == 87654 );
|
||||
BOOST_TEST( *cp3 == 87654 );
|
||||
cp2 = cp2;
|
||||
BOOST_TEST( cp2.use_count() == 2 );
|
||||
BOOST_TEST( *cp2 == 87654 );
|
||||
cp = cp2;
|
||||
BOOST_TEST( cp2.use_count() == 3 );
|
||||
BOOST_TEST( *cp2 == 87654 );
|
||||
BOOST_TEST( cp.use_count() == 3 );
|
||||
BOOST_TEST( *cp == 87654 );
|
||||
|
||||
shared_ptr<int> cp4;
|
||||
swap( cp2, cp4 );
|
||||
BOOST_TEST( cp4.use_count() == 3 );
|
||||
BOOST_TEST( *cp4 == 87654 );
|
||||
BOOST_TEST( cp2.get() == 0 );
|
||||
|
||||
set< shared_ptr<int> > scp;
|
||||
scp.insert(cp4);
|
||||
BOOST_TEST( scp.find(cp4) != scp.end() );
|
||||
BOOST_TEST( scp.find(cp4) == scp.find( shared_ptr<int>(cp4) ) );
|
||||
|
||||
// test shared_array with a built-in type
|
||||
char * cap = new char [ 100 ];
|
||||
shared_array<char> ca ( cap );
|
||||
BOOST_TEST( ca.get() == cap );
|
||||
BOOST_TEST( cap == ca.get() );
|
||||
BOOST_TEST( &ca[0] == cap );
|
||||
|
||||
strcpy( ca.get(), "Hot Dog with mustard and relish" );
|
||||
BOOST_TEST( strcmp( ca.get(), "Hot Dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( strcmp( cap, "Hot Dog with mustard and relish" ) == 0 );
|
||||
|
||||
BOOST_TEST( ca[0] == 'H' );
|
||||
BOOST_TEST( ca[30] == 'h' );
|
||||
|
||||
shared_array<char> ca2 ( ca );
|
||||
shared_array<char> ca3 ( ca2 );
|
||||
|
||||
ca[0] = 'N';
|
||||
ca[4] = 'd';
|
||||
BOOST_TEST( strcmp( ca.get(), "Not dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( strcmp( ca2.get(), "Not dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( strcmp( ca3.get(), "Not dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( ca.use_count() == 3 );
|
||||
BOOST_TEST( ca2.use_count() == 3 );
|
||||
BOOST_TEST( ca3.use_count() == 3 );
|
||||
ca2.reset();
|
||||
BOOST_TEST( ca.use_count() == 2 );
|
||||
BOOST_TEST( ca3.use_count() == 2 );
|
||||
BOOST_TEST( ca2.use_count() == 1 );
|
||||
|
||||
ca.reset();
|
||||
BOOST_TEST( ca.get() == 0 );
|
||||
|
||||
shared_array<char> ca4;
|
||||
swap( ca3, ca4 );
|
||||
BOOST_TEST( ca4.use_count() == 1 );
|
||||
BOOST_TEST( strcmp( ca4.get(), "Not dog with mustard and relish" ) == 0 );
|
||||
BOOST_TEST( ca3.get() == 0 );
|
||||
|
||||
set< shared_array<char> > sca;
|
||||
sca.insert(ca4);
|
||||
BOOST_TEST( sca.find(ca4) != sca.end() );
|
||||
BOOST_TEST( sca.find(ca4) == sca.find( shared_array<char>(ca4) ) );
|
||||
|
||||
// test shared_array with user defined type
|
||||
shared_array<UDT> udta ( new UDT[3] );
|
||||
|
||||
udta[0].value( 111 );
|
||||
udta[1].value( 222 );
|
||||
udta[2].value( 333 );
|
||||
shared_array<UDT> udta2 ( udta );
|
||||
|
||||
BOOST_TEST( udta[0].value() == 111 );
|
||||
BOOST_TEST( udta[1].value() == 222 );
|
||||
BOOST_TEST( udta[2].value() == 333 );
|
||||
BOOST_TEST( udta2[0].value() == 111 );
|
||||
BOOST_TEST( udta2[1].value() == 222 );
|
||||
BOOST_TEST( udta2[2].value() == 333 );
|
||||
udta2.reset();
|
||||
BOOST_TEST( udta2.get() == 0 );
|
||||
BOOST_TEST( udta.use_count() == 1 );
|
||||
BOOST_TEST( udta2.use_count() == 1 );
|
||||
|
||||
BOOST_TEST( UDT_use_count == 4 ); // reality check
|
||||
|
||||
// test shared_ptr with a user defined type
|
||||
UDT * up = new UDT;
|
||||
shared_ptr<UDT> sup ( up );
|
||||
BOOST_TEST( up == sup.get() );
|
||||
BOOST_TEST( sup.use_count() == 1 );
|
||||
|
||||
sup->value( 54321 ) ;
|
||||
BOOST_TEST( sup->value() == 54321 );
|
||||
BOOST_TEST( up->value() == 54321 );
|
||||
|
||||
shared_ptr<UDT> sup2;
|
||||
sup2 = sup;
|
||||
BOOST_TEST( sup2->value() == 54321 );
|
||||
BOOST_TEST( sup.use_count() == 2 );
|
||||
BOOST_TEST( sup2.use_count() == 2 );
|
||||
sup2 = sup2;
|
||||
BOOST_TEST( sup2->value() == 54321 );
|
||||
BOOST_TEST( sup.use_count() == 2 );
|
||||
BOOST_TEST( sup2.use_count() == 2 );
|
||||
|
||||
cout << "OK\n";
|
||||
|
||||
new char[12345]; // deliberate memory leak to verify leaks detected
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
return boost::report_errors();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user