Chris@16: // Chris@16: // Boost.Pointer Container Chris@16: // Chris@16: // Copyright Thorsten Ottosen 2003-2005. Use, modification and Chris@16: // distribution is subject to the Boost Software License, Version Chris@16: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // For more information, see http://www.boost.org/libs/ptr_container/ Chris@16: // Chris@16: Chris@16: #ifndef BOOST_PTR_CONTAINER_PTR_ARRAY_HPP Chris@16: #define BOOST_PTR_CONTAINER_PTR_ARRAY_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: namespace ptr_container_detail Chris@16: { Chris@16: template Chris@16: < Chris@16: class T, Chris@16: size_t N, Chris@16: class Allocator = int // dummy Chris@16: > Chris@16: class ptr_array_impl : public boost::array Chris@16: { Chris@16: public: Chris@16: typedef Allocator allocator_type; Chris@16: Chris@16: ptr_array_impl( Allocator /*a*/ = Allocator() ) Chris@16: { Chris@16: this->assign( 0 ); Chris@16: } Chris@16: Chris@16: ptr_array_impl( size_t, T*, Allocator /*a*/ = Allocator() ) Chris@16: { Chris@16: this->assign( 0 ); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: < Chris@16: class T, Chris@16: size_t N, Chris@16: class CloneAllocator = heap_clone_allocator Chris@16: > Chris@16: class ptr_array : public Chris@16: ptr_sequence_adapter< T, Chris@16: ptr_container_detail::ptr_array_impl, Chris@16: CloneAllocator > Chris@16: { Chris@16: private: Chris@16: typedef ptr_sequence_adapter< T, Chris@16: ptr_container_detail::ptr_array_impl, Chris@16: CloneAllocator > Chris@16: base_class; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME remove_nullable::type U; Chris@16: Chris@16: typedef ptr_array Chris@16: this_type; Chris@16: Chris@16: public: Chris@16: typedef std::size_t size_type; Chris@16: typedef U* value_type; Chris@16: typedef U* pointer; Chris@16: typedef U& reference; Chris@16: typedef const U& const_reference; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_class::auto_type Chris@16: auto_type; Chris@16: Chris@16: public: // constructors Chris@16: ptr_array() : base_class() Chris@16: { } Chris@16: Chris@16: ptr_array( const ptr_array& r ) Chris@16: { Chris@16: size_t i = 0; Chris@16: for( ; i != N; ++i ) Chris@16: this->base()[i] = this->null_policy_allocate_clone( Chris@16: static_cast( &r[i] ) ); Chris@16: } Chris@16: Chris@16: template< class U > Chris@16: ptr_array( const ptr_array& r ) Chris@16: { Chris@16: size_t i = 0; Chris@16: for( ; i != N; ++i ) Chris@16: this->base()[i] = this->null_policy_allocate_clone( Chris@16: static_cast( &r[i] ) ); Chris@16: } Chris@16: Chris@16: explicit ptr_array( std::auto_ptr r ) Chris@16: : base_class( r ) { } Chris@16: Chris@16: ptr_array& operator=( ptr_array r ) Chris@16: { Chris@16: this->swap( r ); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: ptr_array& operator=( std::auto_ptr r ) Chris@16: { Chris@16: base_class::operator=(r); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: std::auto_ptr release() Chris@16: { Chris@16: std::auto_ptr ptr( new this_type ); Chris@16: this->swap( *ptr ); Chris@16: return ptr; Chris@16: } Chris@16: Chris@16: std::auto_ptr clone() const Chris@16: { Chris@16: std::auto_ptr pa( new this_type ); Chris@16: for( size_t i = 0; i != N; ++i ) Chris@16: { Chris@16: if( ! is_null(i) ) Chris@16: pa->replace( i, this->null_policy_allocate_clone( &(*this)[i] ) ); Chris@16: } Chris@16: return pa; Chris@16: } Chris@16: Chris@16: private: // hide some members Chris@16: using base_class::insert; Chris@16: using base_class::erase; Chris@16: using base_class::push_back; Chris@16: using base_class::push_front; Chris@16: using base_class::pop_front; Chris@16: using base_class::pop_back; Chris@16: using base_class::transfer; Chris@16: using base_class::get_allocator; Chris@16: Chris@16: public: // compile-time interface Chris@16: Chris@16: template< size_t idx > Chris@16: auto_type replace( U* r ) // strong Chris@16: { Chris@16: BOOST_STATIC_ASSERT( idx < N ); Chris@16: Chris@16: this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" ); Chris@16: Chris@16: auto_type res( static_cast( this->base()[idx] ) ); // nothrow Chris@16: this->base()[idx] = r; // nothrow Chris@16: return boost::ptr_container::move(res); // nothrow Chris@16: } Chris@16: Chris@16: template< size_t idx, class V > Chris@16: auto_type replace( std::auto_ptr r ) Chris@16: { Chris@16: return replace( r.release() ); Chris@16: } Chris@16: Chris@16: auto_type replace( size_t idx, U* r ) // strong Chris@16: { Chris@16: this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" ); Chris@16: Chris@16: auto_type ptr( r ); Chris@16: Chris@16: BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= N, bad_index, Chris@16: "'replace()' aout of bounds" ); Chris@16: Chris@16: auto_type res( static_cast( this->base()[idx] ) ); // nothrow Chris@16: this->base()[idx] = ptr.release(); // nothrow Chris@16: return boost::ptr_container::move(res); // nothrow Chris@16: } Chris@16: Chris@16: template< class V > Chris@16: auto_type replace( size_t idx, std::auto_ptr r ) Chris@16: { Chris@16: return replace( idx, r.release() ); Chris@16: } Chris@16: Chris@16: using base_class::at; Chris@16: Chris@16: template< size_t idx > Chris@16: T& at() Chris@16: { Chris@16: BOOST_STATIC_ASSERT( idx < N ); Chris@16: return (*this)[idx]; Chris@16: } Chris@16: Chris@16: template< size_t idx > Chris@16: const T& at() const Chris@16: { Chris@16: BOOST_STATIC_ASSERT( idx < N ); Chris@16: return (*this)[idx]; Chris@16: } Chris@16: Chris@16: bool is_null( size_t idx ) const Chris@16: { Chris@16: return base_class::is_null(idx); Chris@16: } Chris@16: Chris@16: template< size_t idx > Chris@16: bool is_null() const Chris@16: { Chris@16: BOOST_STATIC_ASSERT( idx < N ); Chris@16: return this->base()[idx] == 0; Chris@16: } Chris@16: }; Chris@16: Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // clonability Chris@16: Chris@16: template< typename T, size_t size, typename CA > Chris@16: inline ptr_array* new_clone( const ptr_array& r ) Chris@16: { Chris@16: return r.clone().release(); Chris@16: } Chris@16: Chris@16: ///////////////////////////////////////////////////////////////////////// Chris@16: // swap Chris@16: Chris@16: template< typename T, size_t size, typename CA > Chris@16: inline void swap( ptr_array& l, ptr_array& r ) Chris@16: { Chris@16: l.swap(r); Chris@16: } Chris@16: } Chris@16: Chris@16: #endif