williamr@2: #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED williamr@2: #define BOOST_SCOPED_PTR_HPP_INCLUDED williamr@2: williamr@2: // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. williamr@2: // Copyright (c) 2001, 2002 Peter Dimov williamr@2: // williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // williamr@2: // http://www.boost.org/libs/smart_ptr/scoped_ptr.htm williamr@2: // williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #ifndef BOOST_NO_AUTO_PTR williamr@2: # include // for std::auto_ptr williamr@2: #endif williamr@2: williamr@2: namespace boost williamr@2: { williamr@2: williamr@2: // Debug hooks williamr@2: williamr@2: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) williamr@2: williamr@2: void sp_scalar_constructor_hook(void * p); williamr@2: void sp_scalar_destructor_hook(void * p); williamr@2: williamr@2: #endif williamr@2: williamr@2: // scoped_ptr mimics a built-in pointer except that it guarantees deletion williamr@2: // of the object pointed to, either on destruction of the scoped_ptr or via williamr@2: // an explicit reset(). scoped_ptr is a simple solution for simple needs; williamr@2: // use shared_ptr or std::auto_ptr if your needs are more complex. williamr@2: williamr@2: template class scoped_ptr // noncopyable williamr@2: { williamr@2: private: williamr@2: williamr@2: T * ptr; williamr@2: williamr@2: scoped_ptr(scoped_ptr const &); williamr@2: scoped_ptr & operator=(scoped_ptr const &); williamr@2: williamr@2: typedef scoped_ptr this_type; williamr@2: williamr@2: public: williamr@2: williamr@2: typedef T element_type; williamr@2: williamr@2: explicit scoped_ptr(T * p = 0): ptr(p) // never throws williamr@2: { williamr@2: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) williamr@2: boost::sp_scalar_constructor_hook(ptr); williamr@2: #endif williamr@2: } williamr@2: williamr@2: #ifndef BOOST_NO_AUTO_PTR williamr@2: williamr@2: explicit scoped_ptr(std::auto_ptr p): ptr(p.release()) // never throws williamr@2: { williamr@2: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) williamr@2: boost::sp_scalar_constructor_hook(ptr); williamr@2: #endif williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: ~scoped_ptr() // never throws williamr@2: { williamr@2: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) williamr@2: boost::sp_scalar_destructor_hook(ptr); williamr@2: #endif williamr@2: boost::checked_delete(ptr); williamr@2: } williamr@2: williamr@2: void reset(T * p = 0) // never throws williamr@2: { williamr@2: BOOST_ASSERT(p == 0 || p != ptr); // catch self-reset errors williamr@2: this_type(p).swap(*this); williamr@2: } williamr@2: williamr@2: T & operator*() const // never throws williamr@2: { williamr@2: BOOST_ASSERT(ptr != 0); williamr@2: return *ptr; williamr@2: } williamr@2: williamr@2: T * operator->() const // never throws williamr@2: { williamr@2: BOOST_ASSERT(ptr != 0); williamr@2: return ptr; williamr@2: } williamr@2: williamr@2: T * get() const // never throws williamr@2: { williamr@2: return ptr; williamr@2: } williamr@2: williamr@2: // implicit conversion to "bool" williamr@2: williamr@2: #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) williamr@2: williamr@2: operator bool () const williamr@2: { williamr@2: return ptr != 0; williamr@2: } williamr@2: williamr@2: #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) williamr@2: typedef T * (this_type::*unspecified_bool_type)() const; williamr@2: williamr@2: operator unspecified_bool_type() const // never throws williamr@2: { williamr@2: return ptr == 0? 0: &this_type::get; williamr@2: } williamr@2: williamr@2: #else williamr@2: typedef T * this_type::*unspecified_bool_type; williamr@2: williamr@2: operator unspecified_bool_type() const // never throws williamr@2: { williamr@2: return ptr == 0? 0: &this_type::ptr; williamr@2: } williamr@2: williamr@2: #endif williamr@2: williamr@2: bool operator! () const // never throws williamr@2: { williamr@2: return ptr == 0; williamr@2: } williamr@2: williamr@2: void swap(scoped_ptr & b) // never throws williamr@2: { williamr@2: T * tmp = b.ptr; williamr@2: b.ptr = ptr; williamr@2: ptr = tmp; williamr@2: } williamr@2: }; williamr@2: williamr@2: template inline void swap(scoped_ptr & a, scoped_ptr & b) // never throws williamr@2: { williamr@2: a.swap(b); williamr@2: } williamr@2: williamr@2: // get_pointer(p) is a generic way to say p.get() williamr@2: williamr@2: template inline T * get_pointer(scoped_ptr const & p) williamr@2: { williamr@2: return p.get(); williamr@2: } williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED