diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-06-28 17:17:23 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-06-28 17:17:23 +0200 |
commit | b51965dddbed68f23c5e8c169c23c794313ce5f6 (patch) | |
tree | 37bbdf4e5b1cdd34ea0694a5abd1483d1de2b3af /cutl/details/boost/smart_ptr/detail/shared_ptr_nmt.hpp | |
parent | 5f06e7e30e4f511ce2fb27c5feefa6aeb6f00841 (diff) |
Add boost subset as an implementation detail
Diffstat (limited to 'cutl/details/boost/smart_ptr/detail/shared_ptr_nmt.hpp')
-rw-r--r-- | cutl/details/boost/smart_ptr/detail/shared_ptr_nmt.hpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/cutl/details/boost/smart_ptr/detail/shared_ptr_nmt.hpp b/cutl/details/boost/smart_ptr/detail/shared_ptr_nmt.hpp new file mode 100644 index 0000000..e84e696 --- /dev/null +++ b/cutl/details/boost/smart_ptr/detail/shared_ptr_nmt.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED + +// +// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 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) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include <cutl/details/boost/assert.hpp> +#include <cutl/details/boost/checked_delete.hpp> +#include <cutl/details/boost/throw_exception.hpp> +#include <cutl/details/boost/smart_ptr/detail/atomic_count.hpp> + +#ifndef BOOST_NO_AUTO_PTR +# include <memory> // for std::auto_ptr +#endif + +#include <algorithm> // for std::swap +#include <functional> // for std::less +#include <new> // for std::bad_alloc + +namespace cutl_details_boost +{ + +template<class T> class shared_ptr +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + typedef T value_type; + + explicit shared_ptr(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + cutl_details_boost::checked_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + cutl_details_boost::checked_delete(p); + cutl_details_boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_ptr() + { + if(--*pn == 0) + { + cutl_details_boost::checked_delete(px); + delete pn; + } + } + + shared_ptr(shared_ptr const & r): px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_ptr & operator=(shared_ptr const & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#ifndef BOOST_NO_AUTO_PTR + + explicit shared_ptr(std::auto_ptr<T> & r) + { + pn = new count_type(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } + + shared_ptr & operator=(std::auto_ptr<T> & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#endif + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_ptr(p).swap(*this); + } + + T & operator*() const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator->() const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_ptr<T> & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter +}; + +template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) +{ + return a.get() == b.get(); +} + +template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) +{ + return a.get() != b.get(); +} + +template<class T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b) +{ + return std::less<T*>()(a.get(), b.get()); +} + +template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) +{ + a.swap(b); +} + +// get_pointer() enables cutl_details_boost::mem_fn to recognize shared_ptr + +template<class T> inline T * get_pointer(shared_ptr<T> const & p) +{ + return p.get(); +} + +} // namespace cutl_details_boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED |