2 // Boost.Pointer Container
4 // Copyright Thorsten Ottosen 2003-2005. Use, modification and
5 // distribution is subject to the Boost Software License, Version
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // For more information, see http://www.boost.org/libs/ptr_container/
12 #ifndef BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
13 #define BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
19 #include <boost/array.hpp>
20 #include <boost/static_assert.hpp>
21 #include <boost/ptr_container/ptr_sequence_adapter.hpp>
26 namespace ptr_container_detail
32 class Allocator = int // dummy
34 class ptr_array_impl : public boost::array<T,N>
37 typedef Allocator allocator_type;
39 ptr_array_impl( Allocator a = Allocator() )
44 ptr_array_impl( size_t, T*, Allocator a = Allocator() )
55 class CloneAllocator = heap_clone_allocator
57 class ptr_array : public
58 ptr_sequence_adapter< T,
59 ptr_container_detail::ptr_array_impl<void*,N>,
63 typedef ptr_sequence_adapter< T,
64 ptr_container_detail::ptr_array_impl<void*,N>,
68 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type U;
70 typedef ptr_array<T,N,CloneAllocator>
73 ptr_array( const this_type& );
74 void operator=( const this_type& );
77 typedef std::size_t size_type;
78 typedef U* value_type;
81 typedef const U& const_reference;
82 typedef BOOST_DEDUCED_TYPENAME base_class::auto_type
85 public: // constructors
86 ptr_array() : base_class()
89 ptr_array( std::auto_ptr<this_type> r )
92 void operator=( std::auto_ptr<this_type> r )
94 base_class::operator=(r);
97 std::auto_ptr<this_type> release()
99 std::auto_ptr<this_type> ptr( new this_type );
104 std::auto_ptr<this_type> clone() const
106 std::auto_ptr<this_type> pa( new this_type );
107 for( size_t i = 0; i != N; ++i )
110 pa->replace( i, CloneAllocator::allocate_clone( (*this)[i] ) );
115 private: // hide some members
116 using base_class::insert;
117 using base_class::erase;
118 using base_class::push_back;
119 using base_class::push_front;
120 using base_class::pop_front;
121 using base_class::pop_back;
122 using base_class::transfer;
123 using base_class::get_allocator;
125 public: // compile-time interface
127 template< size_t idx >
128 auto_type replace( U* r ) // strong
130 BOOST_STATIC_ASSERT( idx < N );
132 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
134 auto_type res( static_cast<U*>( this->c_private()[idx] ) ); // nothrow
135 this->c_private()[idx] = r; // nothrow
136 return move(res); // nothrow
139 template< size_t idx, class V >
140 auto_type replace( std::auto_ptr<V> r )
142 return replace<idx>( r.release() );
145 auto_type replace( size_t idx, U* r ) // strong
147 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
151 BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= N, bad_index,
152 "'replace()' aout of bounds" );
154 auto_type res( static_cast<U*>( this->c_private()[idx] ) ); // nothrow
155 this->c_private()[idx] = ptr.release(); // nothrow
156 return move(res); // nothrow
160 auto_type replace( size_t idx, std::auto_ptr<V> r )
162 return replace( idx, r.release() );
165 using base_class::at;
167 template< size_t idx >
170 BOOST_STATIC_ASSERT( idx < N );
174 template< size_t idx >
177 BOOST_STATIC_ASSERT( idx < N );
181 bool is_null( size_t idx ) const
183 return base_class::is_null(idx);
186 template< size_t idx >
189 BOOST_STATIC_ASSERT( idx < N );
190 return this->c_private()[idx] == 0;
193 public: // serialization
195 template< class Archive >
196 void save( Archive& ar, const unsigned ) const
198 this->save_helper( ar );
201 template< class Archive >
202 void load( Archive& ar, const unsigned ) // basic
204 for( size_type i = 0u; i != N; ++i )
207 // Remark: pointers are not tracked,
208 // so we need not call ar.reset_object_address(v, u)
212 this->replace( i, p );
216 BOOST_SERIALIZATION_SPLIT_MEMBER()
220 //////////////////////////////////////////////////////////////////////////////
223 template< typename T, size_t size, typename CA >
224 inline ptr_array<T,size,CA>* new_clone( const ptr_array<T,size,CA>& r )
226 return r.clone().release();
229 /////////////////////////////////////////////////////////////////////////
232 template< typename T, size_t size, typename CA >
233 inline void swap( ptr_array<T,size,CA>& l, ptr_array<T,size,CA>& r )