/*
Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Nokia Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Description:
*
*/
#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
#if (BOOST_MSVC >= 1310)
#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
#endif
#endif
//
// shared_ptr_test.cpp
//
// Copyright (c) 2002, 2003 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/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <map>
#include <vector>
#ifdef __SYMBIAN32__
#include "std_log_result.h"
#define LOG_FILENAME_LINE __FILE__, __LINE__
#endif
//
namespace n_element_type
{
void f(int &)
{
}
void test()
{
typedef boost::shared_ptr<int>::element_type T;
T t;
f(t);
}
} // namespace n_element_type
namespace n_constructors
{
class incomplete;
void default_constructor()
{
{
boost::shared_ptr<int> pi;
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
}
{
boost::shared_ptr<void> pv;
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
}
{
boost::shared_ptr<incomplete> px;
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
}
}
struct A
{
int dummy;
};
struct X
{
static long instances;
X()
{
++instances;
}
~X()
{
--instances;
}
private:
X(X const &);
X & operator= (X const &);
};
long X::instances = 0;
// virtual inheritance stresses the implementation
struct Y: public A, public virtual X
{
static long instances;
Y()
{
++instances;
}
~Y()
{
--instances;
}
private:
Y(Y const &);
Y & operator= (Y const &);
};
long Y::instances = 0;
template<class T> void pc0_test(T * p)
{
BOOST_TEST(p == 0);
boost::shared_ptr<T> pt(p);
BOOST_TEST(pt? false: true);
BOOST_TEST(!pt);
BOOST_TEST(pt.get() == 0);
BOOST_TEST(pt.use_count() == 1);
BOOST_TEST(pt.unique());
}
void pointer_constructor()
{
pc0_test(static_cast<int*>(0));
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300)
pc0_test(static_cast<int const*>(0));
pc0_test(static_cast<int volatile*>(0));
pc0_test(static_cast<int const volatile*>(0));
#endif
{
boost::shared_ptr<int const> pi(static_cast<int*>(0));
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
}
{
boost::shared_ptr<int volatile> pi(static_cast<int*>(0));
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
}
{
boost::shared_ptr<void> pv(static_cast<int*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
boost::shared_ptr<void const> pv(static_cast<int*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
pc0_test(static_cast<X*>(0));
pc0_test(static_cast<X const*>(0));
pc0_test(static_cast<X volatile*>(0));
pc0_test(static_cast<X const volatile*>(0));
{
boost::shared_ptr<X const> px(static_cast<X*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
}
{
boost::shared_ptr<X> px(static_cast<Y*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
}
{
boost::shared_ptr<X const> px(static_cast<Y*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
}
{
boost::shared_ptr<void> pv(static_cast<X*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
boost::shared_ptr<void const> pv(static_cast<X*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
int * p = new int(7);
boost::shared_ptr<int> pi(p);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == p);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
BOOST_TEST(*pi == 7);
}
{
int * p = new int(7);
boost::shared_ptr<int const> pi(p);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == p);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
BOOST_TEST(*pi == 7);
}
{
int * p = new int(7);
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == p);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
int * p = new int(7);
boost::shared_ptr<void const> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == p);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
BOOST_TEST(X::instances == 0);
{
X * p = new X;
boost::shared_ptr<X> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == p);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
}
BOOST_TEST(X::instances == 0);
{
X * p = new X;
boost::shared_ptr<X const> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == p);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
}
BOOST_TEST(X::instances == 0);
{
X * p = new X;
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == p);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
}
BOOST_TEST(X::instances == 0);
{
X * p = new X;
boost::shared_ptr<void const> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == p);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
{
Y * p = new Y;
boost::shared_ptr<X> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == p);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
{
Y * p = new Y;
boost::shared_ptr<X const> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == p);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
int m = 0;
void deleter(int * p)
{
BOOST_TEST(p == 0);
}
void deleter2(int * p)
{
BOOST_TEST(p == &m);
++*p;
}
struct deleter3
{
void operator()(incomplete * p)
{
BOOST_TEST(p == 0);
}
};
// Borland C++ 5.5.1 fails on static_cast<incomplete*>(0)
incomplete * p0 = 0;
void deleter_constructor()
{
{
boost::shared_ptr<int> pi(static_cast<int*>(0), deleter);
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
}
{
boost::shared_ptr<void> pv(static_cast<int*>(0), &deleter);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
boost::shared_ptr<void const> pv(static_cast<int*>(0), deleter);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
boost::shared_ptr<incomplete> px(p0, deleter3());
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
}
{
boost::shared_ptr<void> pv(p0, deleter3());
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
{
boost::shared_ptr<void const> pv(p0, deleter3());
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
BOOST_TEST(m == 0);
{
boost::shared_ptr<int> pi(&m, deleter2);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == &m);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
}
BOOST_TEST(m == 1);
{
boost::shared_ptr<int const> pi(&m, &deleter2);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == &m);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
}
BOOST_TEST(m == 2);
{
boost::shared_ptr<void> pv(&m, deleter2);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == &m);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
BOOST_TEST(m == 3);
{
boost::shared_ptr<void const> pv(&m, &deleter2);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == &m);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
}
BOOST_TEST(m == 4);
}
void copy_constructor()
{
{
boost::shared_ptr<int> pi;
boost::shared_ptr<int> pi2(pi);
BOOST_TEST(pi2 == pi);
BOOST_TEST(pi2? false: true);
BOOST_TEST(!pi2);
BOOST_TEST(pi2.get() == 0);
BOOST_TEST(pi2.use_count() == pi.use_count());
boost::shared_ptr<void> pi3(pi);
BOOST_TEST(pi3 == pi);
BOOST_TEST(pi3? false: true);
BOOST_TEST(!pi3);
BOOST_TEST(pi3.get() == 0);
BOOST_TEST(pi3.use_count() == pi.use_count());
boost::shared_ptr<void> pi4(pi3);
BOOST_TEST(pi4 == pi3);
BOOST_TEST(pi4? false: true);
BOOST_TEST(!pi4);
BOOST_TEST(pi4.get() == 0);
BOOST_TEST(pi4.use_count() == pi3.use_count());
}
{
boost::shared_ptr<void> pv;
boost::shared_ptr<void> pv2(pv);
BOOST_TEST(pv2 == pv);
BOOST_TEST(pv2? false: true);
BOOST_TEST(!pv2);
BOOST_TEST(pv2.get() == 0);
BOOST_TEST(pv2.use_count() == pv.use_count());
}
{
boost::shared_ptr<incomplete> px;
boost::shared_ptr<incomplete> px2(px);
BOOST_TEST(px2 == px);
BOOST_TEST(px2? false: true);
BOOST_TEST(!px2);
BOOST_TEST(px2.get() == 0);
BOOST_TEST(px2.use_count() == px.use_count());
boost::shared_ptr<void> px3(px);
BOOST_TEST(px3 == px);
BOOST_TEST(px3? false: true);
BOOST_TEST(!px3);
BOOST_TEST(px3.get() == 0);
BOOST_TEST(px3.use_count() == px.use_count());
}
{
boost::shared_ptr<int> pi(static_cast<int*>(0));
boost::shared_ptr<int> pi2(pi);
BOOST_TEST(pi2 == pi);
BOOST_TEST(pi2? false: true);
BOOST_TEST(!pi2);
BOOST_TEST(pi2.get() == 0);
BOOST_TEST(pi2.use_count() == 2);
BOOST_TEST(!pi2.unique());
BOOST_TEST(pi2.use_count() == pi.use_count());
BOOST_TEST(!(pi < pi2 || pi2 < pi)); // shared ownership test
boost::shared_ptr<void> pi3(pi);
BOOST_TEST(pi3 == pi);
BOOST_TEST(pi3? false: true);
BOOST_TEST(!pi3);
BOOST_TEST(pi3.get() == 0);
BOOST_TEST(pi3.use_count() == 3);
BOOST_TEST(!pi3.unique());
BOOST_TEST(pi3.use_count() == pi.use_count());
BOOST_TEST(!(pi < pi3 || pi3 < pi)); // shared ownership test
boost::shared_ptr<void> pi4(pi2);
BOOST_TEST(pi4 == pi2);
BOOST_TEST(pi4? false: true);
BOOST_TEST(!pi4);
BOOST_TEST(pi4.get() == 0);
BOOST_TEST(pi4.use_count() == 4);
BOOST_TEST(!pi4.unique());
BOOST_TEST(pi4.use_count() == pi2.use_count());
BOOST_TEST(!(pi2 < pi4 || pi4 < pi2)); // shared ownership test
BOOST_TEST(pi3.use_count() == pi4.use_count());
BOOST_TEST(!(pi3 < pi4 || pi4 < pi3)); // shared ownership test
}
{
boost::shared_ptr<X> px(static_cast<X*>(0));
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2 == px);
BOOST_TEST(px2? false: true);
BOOST_TEST(!px2);
BOOST_TEST(px2.get() == 0);
BOOST_TEST(px2.use_count() == 2);
BOOST_TEST(!px2.unique());
BOOST_TEST(px2.use_count() == px.use_count());
BOOST_TEST(!(px < px2 || px2 < px)); // shared ownership test
boost::shared_ptr<void> px3(px);
BOOST_TEST(px3 == px);
BOOST_TEST(px3? false: true);
BOOST_TEST(!px3);
BOOST_TEST(px3.get() == 0);
BOOST_TEST(px3.use_count() == 3);
BOOST_TEST(!px3.unique());
BOOST_TEST(px3.use_count() == px.use_count());
BOOST_TEST(!(px < px3 || px3 < px)); // shared ownership test
boost::shared_ptr<void> px4(px2);
BOOST_TEST(px4 == px2);
BOOST_TEST(px4? false: true);
BOOST_TEST(!px4);
BOOST_TEST(px4.get() == 0);
BOOST_TEST(px4.use_count() == 4);
BOOST_TEST(!px4.unique());
BOOST_TEST(px4.use_count() == px2.use_count());
BOOST_TEST(!(px2 < px4 || px4 < px2)); // shared ownership test
BOOST_TEST(px3.use_count() == px4.use_count());
BOOST_TEST(!(px3 < px4 || px4 < px3)); // shared ownership test
}
{
int * p = new int(7);
boost::shared_ptr<int> pi(p);
boost::shared_ptr<int> pi2(pi);
BOOST_TEST(pi2 == pi);
BOOST_TEST(pi2? true: false);
BOOST_TEST(!!pi2);
BOOST_TEST(pi2.get() == p);
BOOST_TEST(pi2.use_count() == 2);
BOOST_TEST(!pi2.unique());
BOOST_TEST(*pi2 == 7);
BOOST_TEST(pi2.use_count() == pi.use_count());
BOOST_TEST(!(pi < pi2 || pi2 < pi)); // shared ownership test
}
{
int * p = new int(7);
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv.get() == p);
boost::shared_ptr<void> pv2(pv);
BOOST_TEST(pv2 == pv);
BOOST_TEST(pv2? true: false);
BOOST_TEST(!!pv2);
BOOST_TEST(pv2.get() == p);
BOOST_TEST(pv2.use_count() == 2);
BOOST_TEST(!pv2.unique());
BOOST_TEST(pv2.use_count() == pv.use_count());
BOOST_TEST(!(pv < pv2 || pv2 < pv)); // shared ownership test
}
BOOST_TEST(X::instances == 0);
{
X * p = new X;
boost::shared_ptr<X> px(p);
BOOST_TEST(px.get() == p);
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2 == px);
BOOST_TEST(px2? true: false);
BOOST_TEST(!!px2);
BOOST_TEST(px2.get() == p);
BOOST_TEST(px2.use_count() == 2);
BOOST_TEST(!px2.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(px2.use_count() == px.use_count());
BOOST_TEST(!(px < px2 || px2 < px)); // shared ownership test
boost::shared_ptr<void> px3(px);
BOOST_TEST(px3 == px);
BOOST_TEST(px3? true: false);
BOOST_TEST(!!px3);
BOOST_TEST(px3.get() == p);
BOOST_TEST(px3.use_count() == 3);
BOOST_TEST(!px3.unique());
BOOST_TEST(px3.use_count() == px.use_count());
BOOST_TEST(!(px < px3 || px3 < px)); // shared ownership test
boost::shared_ptr<void> px4(px2);
BOOST_TEST(px4 == px2);
BOOST_TEST(px4? true: false);
BOOST_TEST(!!px4);
BOOST_TEST(px4.get() == p);
BOOST_TEST(px4.use_count() == 4);
BOOST_TEST(!px4.unique());
BOOST_TEST(px4.use_count() == px2.use_count());
BOOST_TEST(!(px2 < px4 || px4 < px2)); // shared ownership test
BOOST_TEST(px3.use_count() == px4.use_count());
BOOST_TEST(!(px3 < px4 || px4 < px3)); // shared ownership test
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
{
Y * p = new Y;
boost::shared_ptr<Y> py(p);
BOOST_TEST(py.get() == p);
boost::shared_ptr<X> px(py);
BOOST_TEST(px == py);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == p);
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(!px.unique());
BOOST_TEST(px.use_count() == py.use_count());
BOOST_TEST(!(px < py || py < px)); // shared ownership test
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
boost::shared_ptr<void const> pv(px);
BOOST_TEST(pv == px);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == px.get());
BOOST_TEST(pv.use_count() == 3);
BOOST_TEST(!pv.unique());
BOOST_TEST(pv.use_count() == px.use_count());
BOOST_TEST(!(px < pv || pv < px)); // shared ownership test
boost::shared_ptr<void const> pv2(py);
BOOST_TEST(pv2 == py);
BOOST_TEST(pv2? true: false);
BOOST_TEST(!!pv2);
BOOST_TEST(pv2.get() == py.get());
BOOST_TEST(pv2.use_count() == 4);
BOOST_TEST(!pv2.unique());
BOOST_TEST(pv2.use_count() == py.use_count());
BOOST_TEST(!(py < pv2 || pv2 < py)); // shared ownership test
BOOST_TEST(pv.use_count() == pv2.use_count());
BOOST_TEST(!(pv < pv2 || pv2 < pv)); // shared ownership test
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
void weak_ptr_constructor()
{
{
boost::weak_ptr<Y> wp;
BOOST_TEST(wp.use_count() == 0);
try
{
boost::shared_ptr<Y> p2(wp);
BOOST_ERROR("shared_ptr<Y> p2(wp) failed to throw");
}
catch(boost::bad_weak_ptr)
{
}
try
{
boost::shared_ptr<X> p3(wp);
BOOST_ERROR("shared_ptr<X> p3(wp) failed to throw");
}
catch(boost::bad_weak_ptr)
{
}
}
{
boost::shared_ptr<Y> p;
boost::weak_ptr<Y> wp(p);
if(wp.use_count() != 0) // 0 allowed but not required
{
boost::shared_ptr<Y> p2(wp);
BOOST_TEST(p2.use_count() == wp.use_count());
BOOST_TEST(p2.get() == 0);
boost::shared_ptr<X> p3(wp);
BOOST_TEST(p3.use_count() == wp.use_count());
BOOST_TEST(p3.get() == 0);
}
}
{
boost::shared_ptr<Y> p(new Y);
boost::weak_ptr<Y> wp(p);
{
boost::shared_ptr<Y> p2(wp);
BOOST_TEST(p2? true: false);
BOOST_TEST(!!p2);
BOOST_TEST(p2.get() == p.get());
BOOST_TEST(p2.use_count() == 2);
BOOST_TEST(!p2.unique());
BOOST_TEST(p2.use_count() == wp.use_count());
BOOST_TEST(p.use_count() == p2.use_count());
BOOST_TEST(!(p < p2 || p2 < p)); // shared ownership test
boost::shared_ptr<X> p3(wp);
BOOST_TEST(p3? true: false);
BOOST_TEST(!!p3);
BOOST_TEST(p3.get() == p.get());
BOOST_TEST(p3.use_count() == 3);
BOOST_TEST(!p3.unique());
BOOST_TEST(p3.use_count() == wp.use_count());
BOOST_TEST(p.use_count() == p3.use_count());
}
p.reset();
BOOST_TEST(wp.use_count() == 0);
try
{
boost::shared_ptr<Y> p2(wp);
BOOST_ERROR("shared_ptr<Y> p2(wp) failed to throw");
}
catch(boost::bad_weak_ptr)
{
}
try
{
boost::shared_ptr<X> p3(wp);
BOOST_ERROR("shared_ptr<X> p3(wp) failed to throw");
}
catch(boost::bad_weak_ptr)
{
}
}
}
#if defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB < 306)
# define BOOST_OLD_AUTO_PTR
#endif
void auto_ptr_constructor()
{
{
std::auto_ptr<int> p;
boost::shared_ptr<int> pi(p);
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<int> p;
boost::shared_ptr<int const> pi(p);
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<int> p;
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<int> p;
boost::shared_ptr<void const> pv(p);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<X> p;
boost::shared_ptr<X> px(p);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<X> p;
boost::shared_ptr<X const> px(p);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<Y> p;
boost::shared_ptr<X> px(p);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<Y> p;
boost::shared_ptr<X const> px(p);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<Y> p;
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<Y> p;
boost::shared_ptr<void const> pv(p);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(p.get() == 0);
}
{
std::auto_ptr<int> p(new int(7));
int * q = p.get();
boost::shared_ptr<int> pi(p);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == q);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
BOOST_TEST(*pi == 7);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
{
std::auto_ptr<int> p(new int(7));
int * q = p.get();
boost::shared_ptr<int const> pi(p);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == q);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
BOOST_TEST(*pi == 7);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
{
std::auto_ptr<int> p(new int(7));
int * q = p.get();
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == q);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
{
std::auto_ptr<int> p(new int(7));
int * q = p.get();
boost::shared_ptr<void const> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == q);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
{
std::auto_ptr<X> p(new X);
X * q = p.get();
boost::shared_ptr<X> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == q);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
{
std::auto_ptr<X> p(new X);
X * q = p.get();
boost::shared_ptr<X const> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == q);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
{
std::auto_ptr<X> p(new X);
X * q = p.get();
boost::shared_ptr<void> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == q);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
{
std::auto_ptr<X> p(new X);
X * q = p.get();
boost::shared_ptr<void const> pv(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == q);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
{
std::auto_ptr<Y> p(new Y);
Y * q = p.get();
boost::shared_ptr<X> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == q);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
{
std::auto_ptr<Y> p(new Y);
Y * q = p.get();
boost::shared_ptr<X const> px(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == q);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p.get() == 0);
#endif
}
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
void test()
{
default_constructor();
pointer_constructor();
deleter_constructor();
copy_constructor();
weak_ptr_constructor();
auto_ptr_constructor();
}
} // namespace n_constructors
namespace n_assignment
{
class incomplete;
struct A
{
int dummy;
};
struct X
{
static long instances;
X()
{
++instances;
}
~X()
{
--instances;
}
private:
X(X const &);
X & operator= (X const &);
};
long X::instances = 0;
struct Y: public A, public virtual X
{
static long instances;
Y()
{
++instances;
}
~Y()
{
--instances;
}
private:
Y(Y const &);
Y & operator= (Y const &);
};
long Y::instances = 0;
void copy_assignment()
{
{
boost::shared_ptr<incomplete> p1;
p1 = p1;
BOOST_TEST(p1 == p1);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<incomplete> p2;
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<incomplete> p3(p1);
p1 = p3;
BOOST_TEST(p1 == p3);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
}
{
boost::shared_ptr<void> p1;
p1 = p1;
BOOST_TEST(p1 == p1);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<void> p2;
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<void> p3(p1);
p1 = p3;
BOOST_TEST(p1 == p3);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<void> p4(new int);
BOOST_TEST(p4.use_count() == 1);
p1 = p4;
BOOST_TEST(p1 == p4);
BOOST_TEST(!(p1 < p4 || p4 < p1));
BOOST_TEST(p1.use_count() == 2);
BOOST_TEST(p4.use_count() == 2);
p1 = p3;
BOOST_TEST(p1 == p3);
BOOST_TEST(p4.use_count() == 1);
}
{
boost::shared_ptr<X> p1;
p1 = p1;
BOOST_TEST(p1 == p1);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<X> p2;
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<X> p3(p1);
p1 = p3;
BOOST_TEST(p1 == p3);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(X::instances == 0);
boost::shared_ptr<X> p4(new X);
BOOST_TEST(X::instances == 1);
p1 = p4;
BOOST_TEST(X::instances == 1);
BOOST_TEST(p1 == p4);
BOOST_TEST(!(p1 < p4 || p4 < p1));
BOOST_TEST(p1.use_count() == 2);
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(X::instances == 1);
p4 = p3;
BOOST_TEST(p4 == p3);
BOOST_TEST(X::instances == 0);
}
}
void conversion_assignment()
{
{
boost::shared_ptr<void> p1;
boost::shared_ptr<incomplete> p2;
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
boost::shared_ptr<int> p4(new int);
BOOST_TEST(p4.use_count() == 1);
boost::shared_ptr<void> p5(p4);
BOOST_TEST(p4.use_count() == 2);
p1 = p4;
BOOST_TEST(p1 == p4);
BOOST_TEST(!(p1 < p5 || p5 < p1));
BOOST_TEST(p1.use_count() == 3);
BOOST_TEST(p4.use_count() == 3);
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(p4.use_count() == 2);
}
{
boost::shared_ptr<X> p1;
boost::shared_ptr<Y> p2;
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
boost::shared_ptr<Y> p4(new Y);
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
BOOST_TEST(p4.use_count() == 1);
boost::shared_ptr<X> p5(p4);
BOOST_TEST(p4.use_count() == 2);
p1 = p4;
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
BOOST_TEST(p1 == p4);
BOOST_TEST(!(p1 < p5 || p5 < p1));
BOOST_TEST(p1.use_count() == 3);
BOOST_TEST(p4.use_count() == 3);
p1 = p2;
BOOST_TEST(p1 == p2);
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
BOOST_TEST(p4.use_count() == 2);
p4 = p2;
p5 = p2;
BOOST_TEST(p4 == p2);
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
}
void auto_ptr_assignment()
{
{
boost::shared_ptr<int> p1;
std::auto_ptr<int> p2;
p1 = p2;
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(p1.use_count() == 1);
int * p = new int;
std::auto_ptr<int> p3(p);
p1 = p3;
BOOST_TEST(p1.get() == p);
BOOST_TEST(p1.use_count() == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p3.get() == 0);
#endif
p1 = p2;
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(p1.use_count() == 1);
}
{
boost::shared_ptr<void> p1;
std::auto_ptr<int> p2;
p1 = p2;
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(p1.use_count() == 1);
int * p = new int;
std::auto_ptr<int> p3(p);
p1 = p3;
BOOST_TEST(p1.get() == p);
BOOST_TEST(p1.use_count() == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p3.get() == 0);
#endif
p1 = p2;
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(p1.use_count() == 1);
}
{
boost::shared_ptr<X> p1;
std::auto_ptr<Y> p2;
p1 = p2;
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(p1.use_count() == 1);
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
Y * p = new Y;
std::auto_ptr<Y> p3(p);
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
p1 = p3;
BOOST_TEST(p1.get() == p);
BOOST_TEST(p1.use_count() == 1);
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
#if !defined(BOOST_OLD_AUTO_PTR)
BOOST_TEST(p3.get() == 0);
#endif
p1 = p2;
BOOST_TEST(p1? false: true);
BOOST_TEST(!p1);
BOOST_TEST(p1.get() == 0);
BOOST_TEST(p1.use_count() == 1);
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
}
void test()
{
copy_assignment();
conversion_assignment();
auto_ptr_assignment();
}
} // namespace n_assignment
namespace n_reset
{
class incomplete;
incomplete * p0 = 0;
void deleter(incomplete *)
{
}
struct X
{
static long instances;
X()
{
++instances;
}
~X()
{
--instances;
}
private:
X(X const &);
X & operator= (X const &);
};
long X::instances = 0;
void plain_reset()
{
{
boost::shared_ptr<int> pi;
pi.reset();
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
}
{
boost::shared_ptr<int> pi(static_cast<int*>(0));
pi.reset();
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
}
{
boost::shared_ptr<int> pi(new int);
pi.reset();
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
}
{
boost::shared_ptr<incomplete> px;
px.reset();
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
}
{
boost::shared_ptr<incomplete> px(p0, deleter);
px.reset();
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
}
{
boost::shared_ptr<X> px;
px.reset();
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
}
{
BOOST_TEST(X::instances == 0);
boost::shared_ptr<X> px(new X);
BOOST_TEST(X::instances == 1);
px.reset();
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(X::instances == 0);
}
{
boost::shared_ptr<void> pv;
pv.reset();
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
}
{
BOOST_TEST(X::instances == 0);
boost::shared_ptr<void> pv(new X);
BOOST_TEST(X::instances == 1);
pv.reset();
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(X::instances == 0);
}
}
struct A
{
int dummy;
};
struct Y: public A, public virtual X
{
static long instances;
Y()
{
++instances;
}
~Y()
{
--instances;
}
private:
Y(Y const &);
Y & operator= (Y const &);
};
long Y::instances = 0;
void pointer_reset()
{
{
boost::shared_ptr<int> pi;
pi.reset(static_cast<int*>(0));
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
int * p = new int;
pi.reset(p);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == p);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
pi.reset(static_cast<int*>(0));
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
}
{
boost::shared_ptr<X> px;
px.reset(static_cast<X*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 0);
X * p = new X;
px.reset(p);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == p);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
px.reset(static_cast<X*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
Y * q = new Y;
px.reset(q);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == q);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
px.reset(static_cast<Y*>(0));
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
{
boost::shared_ptr<void> pv;
pv.reset(static_cast<X*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 0);
X * p = new X;
pv.reset(p);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == p);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
pv.reset(static_cast<X*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
Y * q = new Y;
pv.reset(q);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == q);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 1);
BOOST_TEST(Y::instances == 1);
pv.reset(static_cast<Y*>(0));
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
BOOST_TEST(X::instances == 0);
BOOST_TEST(Y::instances == 0);
}
}
void * deleted = 0;
void deleter2(void * p)
{
deleted = p;
}
void deleter_reset()
{
{
boost::shared_ptr<int> pi;
pi.reset(static_cast<int*>(0), deleter2);
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
deleted = π
int m = 0;
pi.reset(&m, deleter2);
BOOST_TEST(deleted == 0);
BOOST_TEST(pi? true: false);
BOOST_TEST(!!pi);
BOOST_TEST(pi.get() == &m);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
pi.reset(static_cast<int*>(0), deleter2);
BOOST_TEST(deleted == &m);
BOOST_TEST(pi? false: true);
BOOST_TEST(!pi);
BOOST_TEST(pi.get() == 0);
BOOST_TEST(pi.use_count() == 1);
BOOST_TEST(pi.unique());
pi.reset();
BOOST_TEST(deleted == 0);
}
{
boost::shared_ptr<X> px;
px.reset(static_cast<X*>(0), deleter2);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
deleted = &px;
X x;
px.reset(&x, deleter2);
BOOST_TEST(deleted == 0);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == &x);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
px.reset(static_cast<X*>(0), deleter2);
BOOST_TEST(deleted == &x);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
Y y;
px.reset(&y, deleter2);
BOOST_TEST(deleted == 0);
BOOST_TEST(px? true: false);
BOOST_TEST(!!px);
BOOST_TEST(px.get() == &y);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
px.reset(static_cast<Y*>(0), deleter2);
BOOST_TEST(deleted == &y);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
px.reset();
BOOST_TEST(deleted == 0);
}
{
boost::shared_ptr<void> pv;
pv.reset(static_cast<X*>(0), deleter2);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
deleted = &pv;
X x;
pv.reset(&x, deleter2);
BOOST_TEST(deleted == 0);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == &x);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
pv.reset(static_cast<X*>(0), deleter2);
BOOST_TEST(deleted == &x);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
Y y;
pv.reset(&y, deleter2);
BOOST_TEST(deleted == 0);
BOOST_TEST(pv? true: false);
BOOST_TEST(!!pv);
BOOST_TEST(pv.get() == &y);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
pv.reset(static_cast<Y*>(0), deleter2);
BOOST_TEST(deleted == &y);
BOOST_TEST(pv? false: true);
BOOST_TEST(!pv);
BOOST_TEST(pv.get() == 0);
BOOST_TEST(pv.use_count() == 1);
BOOST_TEST(pv.unique());
pv.reset();
BOOST_TEST(deleted == 0);
}
{
boost::shared_ptr<incomplete> px;
px.reset(p0, deleter2);
BOOST_TEST(px? false: true);
BOOST_TEST(!px);
BOOST_TEST(px.get() == 0);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
deleted = &px;
px.reset(p0, deleter2);
BOOST_TEST(deleted == 0);
}
}
void test()
{
plain_reset();
pointer_reset();
deleter_reset();
}
} // namespace n_reset
namespace n_access
{
struct X
{
};
void test()
{
{
boost::shared_ptr<X> px;
BOOST_TEST(px.get() == 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::shared_ptr<X> px(static_cast<X*>(0));
BOOST_TEST(px.get() == 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::shared_ptr<X> px(static_cast<X*>(0), boost::checked_deleter<X>());
BOOST_TEST(px.get() == 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());
}
{
X * p = new X;
boost::shared_ptr<X> px(p);
BOOST_TEST(px.get() == p);
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());
}
{
X * p = new X;
boost::shared_ptr<X> px(p, boost::checked_deleter<X>());
BOOST_TEST(px.get() == p);
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_use_count
{
struct X
{
};
void test()
{
{
boost::shared_ptr<X> px(static_cast<X*>(0));
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2.use_count() == 2);
BOOST_TEST(!px2.unique());
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(!px.unique());
}
{
boost::shared_ptr<X> px(new X);
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2.use_count() == 2);
BOOST_TEST(!px2.unique());
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(!px.unique());
}
{
boost::shared_ptr<X> px(new X, boost::checked_deleter<X>());
BOOST_TEST(px.use_count() == 1);
BOOST_TEST(px.unique());
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2.use_count() == 2);
BOOST_TEST(!px2.unique());
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(!px.unique());
}
}
} // namespace n_use_count
namespace n_swap
{
struct X
{
};
void test()
{
{
boost::shared_ptr<X> px;
boost::shared_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::shared_ptr<X> px;
boost::shared_ptr<X> px2(p);
boost::shared_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::shared_ptr<X> px(p1);
boost::shared_ptr<X> px2(p2);
boost::shared_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
{
struct X
{
int dummy;
};
struct Y
{
int dummy2;
};
struct Z: public X, public virtual Y
{
};
void test()
{
{
boost::shared_ptr<X> px;
BOOST_TEST(px == px);
BOOST_TEST(!(px != px));
BOOST_TEST(!(px < px));
boost::shared_ptr<X> px2;
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(px == px2);
BOOST_TEST(!(px != px2));
BOOST_TEST(!(px < px2 && px2 < px));
}
{
boost::shared_ptr<X> px;
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2 == px2);
BOOST_TEST(!(px2 != px2));
BOOST_TEST(!(px2 < px2));
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(px == px2);
BOOST_TEST(!(px != px2));
BOOST_TEST(!(px < px2 && px2 < px));
}
{
boost::shared_ptr<X> px;
boost::shared_ptr<X> px2(new X);
BOOST_TEST(px2 == px2);
BOOST_TEST(!(px2 != px2));
BOOST_TEST(!(px2 < px2));
BOOST_TEST(px.get() != px2.get());
BOOST_TEST(px != px2);
BOOST_TEST(!(px == px2));
BOOST_TEST(px < px2 || px2 < px);
BOOST_TEST(!(px < px2 && px2 < px));
}
{
boost::shared_ptr<X> px(new X);
boost::shared_ptr<X> px2(new X);
BOOST_TEST(px.get() != px2.get());
BOOST_TEST(px != px2);
BOOST_TEST(!(px == px2));
BOOST_TEST(px < px2 || px2 < px);
BOOST_TEST(!(px < px2 && px2 < px));
}
{
boost::shared_ptr<X> px(new X);
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2 == px2);
BOOST_TEST(!(px2 != px2));
BOOST_TEST(!(px2 < px2));
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(px == px2);
BOOST_TEST(!(px != px2));
BOOST_TEST(!(px < px2 || px2 < px));
}
{
boost::shared_ptr<X> px(new X);
boost::shared_ptr<Y> py(new Y);
boost::shared_ptr<Z> pz(new Z);
BOOST_TEST(px.get() != pz.get());
BOOST_TEST(px != pz);
BOOST_TEST(!(px == pz));
BOOST_TEST(py.get() != pz.get());
BOOST_TEST(py != pz);
BOOST_TEST(!(py == pz));
BOOST_TEST(px < py || py < px);
BOOST_TEST(px < pz || pz < px);
BOOST_TEST(py < pz || pz < py);
BOOST_TEST(!(px < py && py < px));
BOOST_TEST(!(px < pz && pz < px));
BOOST_TEST(!(py < pz && pz < py));
boost::shared_ptr<void> pvx(px);
BOOST_TEST(pvx == pvx);
BOOST_TEST(!(pvx != pvx));
BOOST_TEST(!(pvx < pvx));
boost::shared_ptr<void> pvy(py);
boost::shared_ptr<void> pvz(pz);
BOOST_TEST(pvx < pvy || pvy < pvx);
BOOST_TEST(pvx < pvz || pvz < pvx);
BOOST_TEST(pvy < pvz || pvz < pvy);
BOOST_TEST(!(pvx < pvy && pvy < pvx));
BOOST_TEST(!(pvx < pvz && pvz < pvx));
BOOST_TEST(!(pvy < pvz && pvz < pvy));
}
{
boost::shared_ptr<Z> pz(new Z);
boost::shared_ptr<X> px(pz);
BOOST_TEST(px == px);
BOOST_TEST(!(px != px));
BOOST_TEST(!(px < px));
boost::shared_ptr<Y> py(pz);
BOOST_TEST(px.get() == pz.get());
BOOST_TEST(px == pz);
BOOST_TEST(!(px != pz));
BOOST_TEST(py.get() == pz.get());
BOOST_TEST(py == pz);
BOOST_TEST(!(py != pz));
BOOST_TEST(!(px < py || py < px));
BOOST_TEST(!(px < pz || pz < px));
BOOST_TEST(!(py < pz || pz < py));
boost::shared_ptr<void> pvx(px);
boost::shared_ptr<void> pvy(py);
boost::shared_ptr<void> pvz(pz);
// pvx and pvy aren't equal...
BOOST_TEST(pvx.get() != pvy.get());
BOOST_TEST(pvx != pvy);
BOOST_TEST(!(pvx == pvy));
// ... but they share ownership ...
BOOST_TEST(!(pvx < pvy || pvy < pvx));
// ... with pvz
BOOST_TEST(!(pvx < pvz || pvz < pvx));
BOOST_TEST(!(pvy < pvz || pvz < pvy));
}
}
} // namespace n_comparison
namespace n_static_cast
{
struct X
{
};
struct Y: public X
{
};
void test()
{
{
boost::shared_ptr<void> pv;
boost::shared_ptr<int> pi = boost::static_pointer_cast<int>(pv);
BOOST_TEST(pi.get() == 0);
boost::shared_ptr<X> px = boost::static_pointer_cast<X>(pv);
BOOST_TEST(px.get() == 0);
}
{
boost::shared_ptr<int> pi(new int);
boost::shared_ptr<void> pv(pi);
boost::shared_ptr<int> pi2 = boost::static_pointer_cast<int>(pv);
BOOST_TEST(pi.get() == pi2.get());
BOOST_TEST(!(pi < pi2 || pi2 < pi));
BOOST_TEST(pi.use_count() == 3);
BOOST_TEST(pv.use_count() == 3);
BOOST_TEST(pi2.use_count() == 3);
}
{
boost::shared_ptr<X> px(new X);
boost::shared_ptr<void> pv(px);
boost::shared_ptr<X> px2 = boost::static_pointer_cast<X>(pv);
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(!(px < px2 || px2 < px));
BOOST_TEST(px.use_count() == 3);
BOOST_TEST(pv.use_count() == 3);
BOOST_TEST(px2.use_count() == 3);
}
{
boost::shared_ptr<X> px(new Y);
boost::shared_ptr<Y> py = boost::static_pointer_cast<Y>(px);
BOOST_TEST(px.get() == py.get());
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(py.use_count() == 2);
boost::shared_ptr<X> px2(py);
BOOST_TEST(!(px < px2 || px2 < px));
}
}
} // namespace n_static_cast
namespace n_const_cast
{
struct X;
void test()
{
{
boost::shared_ptr<void const volatile> px;
boost::shared_ptr<void> px2 = boost::const_pointer_cast<void>(px);
BOOST_TEST(px2.get() == 0);
}
{
boost::shared_ptr<int const volatile> px;
boost::shared_ptr<int> px2 = boost::const_pointer_cast<int>(px);
BOOST_TEST(px2.get() == 0);
}
{
boost::shared_ptr<X const volatile> px;
boost::shared_ptr<X> px2 = boost::const_pointer_cast<X>(px);
BOOST_TEST(px2.get() == 0);
}
{
boost::shared_ptr<void const volatile> px(new int);
boost::shared_ptr<void> px2 = boost::const_pointer_cast<void>(px);
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(!(px < px2 || px2 < px));
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(px2.use_count() == 2);
}
{
boost::shared_ptr<int const volatile> px(new int);
boost::shared_ptr<int> px2 = boost::const_pointer_cast<int>(px);
BOOST_TEST(px.get() == px2.get());
BOOST_TEST(!(px < px2 || px2 < px));
BOOST_TEST(px.use_count() == 2);
BOOST_TEST(px2.use_count() == 2);
}
}
} // namespace n_const_cast
namespace n_dynamic_cast
{
struct V
{
virtual ~V() {}
};
struct W: public V
{
};
void test()
{
{
boost::shared_ptr<V> pv;
boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
BOOST_TEST(pw.get() == 0);
}
{
boost::shared_ptr<V> pv(static_cast<V*>(0));
boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
BOOST_TEST(pw.get() == 0);
boost::shared_ptr<V> pv2(pw);
BOOST_TEST(pv < pv2 || pv2 < pv);
}
{
boost::shared_ptr<V> pv(static_cast<W*>(0));
boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
BOOST_TEST(pw.get() == 0);
boost::shared_ptr<V> pv2(pw);
BOOST_TEST(pv < pv2 || pv2 < pv);
}
{
boost::shared_ptr<V> pv(new V);
boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
BOOST_TEST(pw.get() == 0);
boost::shared_ptr<V> pv2(pw);
BOOST_TEST(pv < pv2 || pv2 < pv);
}
{
boost::shared_ptr<V> pv(new W);
boost::shared_ptr<W> pw = boost::dynamic_pointer_cast<W>(pv);
BOOST_TEST(pw.get() == pv.get());
BOOST_TEST(pv.use_count() == 2);
BOOST_TEST(pw.use_count() == 2);
boost::shared_ptr<V> pv2(pw);
BOOST_TEST(!(pv < pv2 || pv2 < pv));
}
}
} // namespace n_dynamic_cast
namespace n_map
{
struct X
{
};
void test()
{
std::vector< boost::shared_ptr<int> > vi;
{
boost::shared_ptr<int> pi1(new int);
boost::shared_ptr<int> pi2(new int);
boost::shared_ptr<int> pi3(new int);
vi.push_back(pi1);
vi.push_back(pi1);
vi.push_back(pi1);
vi.push_back(pi2);
vi.push_back(pi1);
vi.push_back(pi2);
vi.push_back(pi1);
vi.push_back(pi3);
vi.push_back(pi3);
vi.push_back(pi2);
vi.push_back(pi1);
}
std::vector< boost::shared_ptr<X> > vx;
{
boost::shared_ptr<X> px1(new X);
boost::shared_ptr<X> px2(new X);
boost::shared_ptr<X> px3(new X);
vx.push_back(px2);
vx.push_back(px2);
vx.push_back(px1);
vx.push_back(px2);
vx.push_back(px1);
vx.push_back(px1);
vx.push_back(px1);
vx.push_back(px2);
vx.push_back(px1);
vx.push_back(px3);
vx.push_back(px2);
}
std::map< boost::shared_ptr<void>, long > m;
{
for(std::vector< boost::shared_ptr<int> >::iterator i = vi.begin(); i != vi.end(); ++i)
{
++m[*i];
}
}
{
for(std::vector< boost::shared_ptr<X> >::iterator i = vx.begin(); i != vx.end(); ++i)
{
++m[*i];
}
}
{
for(std::map< boost::shared_ptr<void>, long >::iterator i = m.begin(); i != m.end(); ++i)
{
BOOST_TEST(i->first.use_count() == i->second + 1);
}
}
}
} // namespace n_map
namespace n_transitive
{
struct X
{
X(): next() {}
boost::shared_ptr<X> next;
};
void test()
{
boost::shared_ptr<X> p(new X);
p->next = boost::shared_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:
foo(): m_self(this)
{
}
void suicide()
{
m_self.reset();
}
private:
boost::shared_ptr<foo> m_self;
};
void test()
{
foo * foo_ptr = new foo;
foo_ptr->suicide();
}
} // namespace n_report_1
// Test case by Per Kristensen
namespace n_report_2
{
class foo
{
public:
void setWeak(boost::shared_ptr<foo> s)
{
w = s;
}
private:
boost::weak_ptr<foo> w;
};
class deleter
{
public:
deleter(): lock(0)
{
}
~deleter()
{
BOOST_TEST(lock == 0);
}
void operator() (foo * p)
{
++lock;
delete p;
--lock;
}
private:
int lock;
};
void test()
{
boost::shared_ptr<foo> s(new foo, deleter());
s->setWeak(s);
s.reset();
}
} // namespace n_report_2
namespace n_spt_incomplete
{
class file;
boost::shared_ptr<file> fopen(char const * name, char const * mode);
void fread(boost::shared_ptr<file> f, void * data, long size);
int file_instances = 0;
void test()
{
BOOST_TEST(file_instances == 0);
{
boost::shared_ptr<file> pf = fopen("name", "mode");
BOOST_TEST(file_instances == 1);
fread(pf, 0, 17041);
}
BOOST_TEST(file_instances == 0);
}
} // namespace n_spt_incomplete
namespace n_spt_pimpl
{
class file
{
private:
class impl;
boost::shared_ptr<impl> pimpl_;
public:
file(char const * name, char const * mode);
// compiler generated members are fine and useful
void read(void * data, long size);
long total_size() const;
};
int file_instances = 0;
void test()
{
BOOST_TEST(file_instances == 0);
{
file f("name", "mode");
BOOST_TEST(file_instances == 1);
f.read(0, 152);
file f2(f);
BOOST_TEST(file_instances == 1);
f2.read(0, 894);
BOOST_TEST(f.total_size() == 152+894);
{
file f3("name2", "mode2");
BOOST_TEST(file_instances == 2);
}
BOOST_TEST(file_instances == 1);
}
BOOST_TEST(file_instances == 0);
}
} // namespace n_spt_pimpl
namespace n_spt_abstract
{
class X
{
public:
virtual void f(int) = 0;
virtual int g() = 0;
protected:
~X() {}
};
boost::shared_ptr<X> createX();
int X_instances = 0;
void test()
{
BOOST_TEST(X_instances == 0);
{
boost::shared_ptr<X> px = createX();
BOOST_TEST(X_instances == 1);
px->f(18);
px->f(152);
BOOST_TEST(px->g() == 170);
}
BOOST_TEST(X_instances == 0);
}
} // namespace n_spt_abstract
namespace n_spt_preventing_delete
{
int X_instances = 0;
class X
{
private:
X()
{
++X_instances;
}
~X()
{
--X_instances;
}
class deleter;
friend class deleter;
class deleter
{
public:
void operator()(X * p) { delete p; }
};
public:
static boost::shared_ptr<X> create()
{
boost::shared_ptr<X> px(new X, X::deleter());
return px;
}
};
void test()
{
BOOST_TEST(X_instances == 0);
{
boost::shared_ptr<X> px = X::create();
BOOST_TEST(X_instances == 1);
}
BOOST_TEST(X_instances == 0);
}
} // namespace n_spt_preventing_delete
namespace n_spt_array
{
int X_instances = 0;
struct X
{
X()
{
++X_instances;
}
~X()
{
--X_instances;
}
};
void test()
{
BOOST_TEST(X_instances == 0);
{
boost::shared_ptr<X> px(new X[4], boost::checked_array_deleter<X>());
BOOST_TEST(X_instances == 4);
}
BOOST_TEST(X_instances == 0);
}
} // namespace n_spt_array
namespace n_spt_static
{
class X
{
public:
X()
{
}
private:
void operator delete(void *)
{
// Comeau 4.3.0.1 wants a definition
BOOST_ERROR("n_spt_static::X::operator delete() called.");
}
};
struct null_deleter
{
void operator()(void const *) const
{
}
};
static X x;
void test()
{
boost::shared_ptr<X> px(&x, null_deleter());
}
} // namespace n_spt_static
namespace n_spt_intrusive
{
int X_instances = 0;
struct X
{
long count;
X(): count(0)
{
++X_instances;
}
~X()
{
--X_instances;
}
};
void intrusive_ptr_add_ref(X * p)
{
++p->count;
}
void intrusive_ptr_release(X * p)
{
if(--p->count == 0) delete p;
}
template<class T> struct intrusive_deleter
{
void operator()(T * p)
{
if(p != 0) intrusive_ptr_release(p);
}
};
boost::shared_ptr<X> make_shared_from_intrusive(X * p)
{
if(p != 0) intrusive_ptr_add_ref(p);
boost::shared_ptr<X> px(p, intrusive_deleter<X>());
return px;
}
void test()
{
BOOST_TEST(X_instances == 0);
{
X * p = new X;
BOOST_TEST(X_instances == 1);
BOOST_TEST(p->count == 0);
boost::shared_ptr<X> px = make_shared_from_intrusive(p);
BOOST_TEST(px.get() == p);
BOOST_TEST(p->count == 1);
boost::shared_ptr<X> px2(px);
BOOST_TEST(px2.get() == p);
BOOST_TEST(p->count == 1);
}
BOOST_TEST(X_instances == 0);
}
} // namespace n_spt_intrusive
namespace n_spt_another_sp
{
template<class T> class another_ptr: private boost::shared_ptr<T>
{
private:
typedef boost::shared_ptr<T> base_type;
public:
explicit another_ptr(T * p = 0): base_type(p)
{
}
void reset()
{
base_type::reset();
}
T * get() const
{
return base_type::get();
}
};
class event_handler
{
public:
virtual ~event_handler() {}
virtual void begin() = 0;
virtual void handle(int event) = 0;
virtual void end() = 0;
};
int begin_called = 0;
int handle_called = 0;
int end_called = 0;
class event_handler_impl: public event_handler
{
public:
virtual void begin()
{
++begin_called;
}
virtual void handle(int event)
{
handle_called = event;
}
virtual void end()
{
++end_called;
}
};
another_ptr<event_handler> get_event_handler()
{
another_ptr<event_handler> p(new event_handler_impl);
return p;
}
boost::shared_ptr<event_handler> current_handler;
void install_event_handler(boost::shared_ptr<event_handler> p)
{
p->begin();
current_handler = p;
}
void handle_event(int event)
{
current_handler->handle(event);
}
void remove_event_handler()
{
current_handler->end();
current_handler.reset();
}
template<class P> class smart_pointer_deleter
{
private:
P p_;
public:
smart_pointer_deleter(P const & p): p_(p)
{
}
void operator()(void const *)
{
p_.reset();
}
};
void test()
{
another_ptr<event_handler> p = get_event_handler();
boost::shared_ptr<event_handler> q(p.get(), smart_pointer_deleter< another_ptr<event_handler> >(p));
p.reset();
BOOST_TEST(begin_called == 0);
install_event_handler(q);
BOOST_TEST(begin_called == 1);
BOOST_TEST(handle_called == 0);
handle_event(17041);
BOOST_TEST(handle_called == 17041);
BOOST_TEST(end_called == 0);
remove_event_handler();
BOOST_TEST(end_called == 1);
}
} // namespace n_spt_another_sp
namespace n_spt_shared_from_this
{
class X
{
public:
virtual void f() = 0;
protected:
~X() {}
};
class Y
{
public:
virtual boost::shared_ptr<X> getX() = 0;
protected:
~Y() {}
};
class impl: public X, public Y
{
private:
boost::weak_ptr<impl> weak_this;
impl(impl const &);
impl & operator=(impl const &);
impl() {}
public:
static boost::shared_ptr<impl> create()
{
boost::shared_ptr<impl> pi(new impl);
pi->weak_this = pi;
return pi;
}
virtual void f() {}
virtual boost::shared_ptr<X> getX()
{
boost::shared_ptr<X> px = weak_this.lock();
return px;
}
};
void test()
{
boost::shared_ptr<Y> py = impl::create();
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);
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);
}
} // namespace n_spt_shared_from_this
namespace n_spt_wrap
{
void test()
{
}
} // namespace n_spt_wrap
int main()
{
std_log(LOG_FILENAME_LINE,"[Test Case for shared_ptr_test]");
n_element_type::test();
n_constructors::test();
n_assignment::test();
n_reset::test();
n_access::test();
n_use_count::test();
n_swap::test();
n_comparison::test();
n_static_cast::test();
n_const_cast::test();
n_dynamic_cast::test();
n_map::test();
n_transitive::test();
n_report_1::test();
n_report_2::test();
n_spt_incomplete::test();
n_spt_pimpl::test();
n_spt_abstract::test();
n_spt_preventing_delete::test();
n_spt_array::test();
n_spt_static::test();
n_spt_intrusive::test();
n_spt_another_sp::test();
n_spt_shared_from_this::test();
n_spt_wrap::test();
#ifdef __SYMBIAN32__
int failures = boost::report_errors();
if(failures)
{
std_log(LOG_FILENAME_LINE,"Result : Failed");
assert_failed = true;
}
else
{
std_log(LOG_FILENAME_LINE,"Result : Passed");
}
std_log(LOG_FILENAME_LINE,"[End Test Case ]");
#endif
testResultXml("shared_ptr_test");
close_log_file();
return failures;
}
namespace n_spt_incomplete
{
class file
{
public:
file(): fread_called(false)
{
++file_instances;
}
~file()
{
BOOST_TEST(fread_called);
--file_instances;
}
bool fread_called;
};
boost::shared_ptr<file> fopen(char const *, char const *)
{
boost::shared_ptr<file> pf(new file);
return pf;
}
void fread(boost::shared_ptr<file> pf, void *, long)
{
pf->fread_called = true;
}
} // namespace n_spt_incomplete
namespace n_spt_pimpl
{
class file::impl
{
private:
impl(impl const &);
impl & operator=(impl const &);
long total_size_;
public:
impl(char const *, char const *): total_size_(0)
{
++file_instances;
}
~impl()
{
--file_instances;
}
void read(void *, long size)
{
total_size_ += size;
}
long total_size() const
{
return total_size_;
}
};
file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
{
}
void file::read(void * data, long size)
{
pimpl_->read(data, size);
}
long file::total_size() const
{
return pimpl_->total_size();
}
} // namespace n_spt_pimpl
namespace n_spt_abstract
{
class X_impl: public X
{
private:
X_impl(X_impl const &);
X_impl & operator=(X_impl const &);
int n_;
public:
X_impl(): n_(0)
{
++X_instances;
}
~X_impl()
{
--X_instances;
}
virtual void f(int n)
{
n_ += n;
}
virtual int g()
{
return n_;
}
};
boost::shared_ptr<X> createX()
{
boost::shared_ptr<X> px(new X_impl);
return px;
}
} // namespace n_spt_abstract