williamr@2: #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED williamr@2: #define BOOST_SCOPED_ARRAY_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_array.htm williamr@2: // williamr@2: williamr@2: #include <boost/assert.hpp> williamr@2: #include <boost/checked_delete.hpp> williamr@2: #include <boost/config.hpp> // in case ptrdiff_t not in std williamr@2: williamr@2: #include <boost/detail/workaround.hpp> williamr@2: williamr@2: #include <cstddef> // for std::ptrdiff_t 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_array_constructor_hook(void * p); williamr@2: void sp_array_destructor_hook(void * p); williamr@2: williamr@2: #endif williamr@2: williamr@2: // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to williamr@2: // is guaranteed, either on destruction of the scoped_array or via an explicit williamr@2: // reset(). Use shared_array or std::vector if your needs are more complex. williamr@2: williamr@2: template<class T> class scoped_array // noncopyable williamr@2: { williamr@2: private: williamr@2: williamr@2: T * ptr; williamr@2: williamr@2: scoped_array(scoped_array const &); williamr@2: scoped_array & operator=(scoped_array const &); williamr@2: williamr@2: typedef scoped_array<T> this_type; williamr@2: williamr@2: public: williamr@2: williamr@2: typedef T element_type; williamr@2: williamr@2: explicit scoped_array(T * p = 0) : ptr(p) // never throws williamr@2: { williamr@2: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) williamr@2: boost::sp_array_constructor_hook(ptr); williamr@2: #endif williamr@2: } williamr@2: williamr@2: ~scoped_array() // never throws williamr@2: { williamr@2: #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) williamr@2: boost::sp_array_destructor_hook(ptr); williamr@2: #endif williamr@2: boost::checked_array_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[](std::ptrdiff_t i) const // never throws williamr@2: { williamr@2: BOOST_ASSERT(ptr != 0); williamr@2: BOOST_ASSERT(i >= 0); williamr@2: return ptr[i]; 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: 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_array & 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: williamr@2: template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws williamr@2: { williamr@2: a.swap(b); williamr@2: } williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: #endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED