File indexing completed on 2025-01-30 09:58:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
0013 #define BOOST_PTR_CONTAINER_PTR_ARRAY_HPP
0014
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018
0019 #include <boost/array.hpp>
0020 #include <boost/static_assert.hpp>
0021 #include <boost/ptr_container/ptr_sequence_adapter.hpp>
0022 #include <boost/ptr_container/detail/ptr_container_disable_deprecated.hpp>
0023
0024 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0025 #pragma GCC diagnostic push
0026 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0027 #endif
0028
0029 namespace boost
0030 {
0031
0032 namespace ptr_container_detail
0033 {
0034 template
0035 <
0036 class T,
0037 size_t N,
0038 class Allocator = int
0039 >
0040 class ptr_array_impl : public boost::array<T,N>
0041 {
0042 public:
0043 typedef Allocator allocator_type;
0044
0045 ptr_array_impl( Allocator = Allocator() )
0046 {
0047 this->assign( 0 );
0048 }
0049
0050 ptr_array_impl( size_t, T*, Allocator = Allocator() )
0051 {
0052 this->assign( 0 );
0053 }
0054 };
0055 }
0056
0057 template
0058 <
0059 class T,
0060 size_t N,
0061 class CloneAllocator = heap_clone_allocator
0062 >
0063 class ptr_array : public
0064 ptr_sequence_adapter< T,
0065 ptr_container_detail::ptr_array_impl<
0066 typename ptr_container_detail::void_ptr<T>::type,N>,
0067 CloneAllocator >
0068 {
0069 private:
0070 typedef ptr_sequence_adapter< T,
0071 ptr_container_detail::ptr_array_impl<
0072 typename ptr_container_detail::void_ptr<T>::type,N>,
0073 CloneAllocator >
0074 base_class;
0075
0076 typedef BOOST_DEDUCED_TYPENAME remove_nullable<T>::type U;
0077
0078 typedef ptr_array<T,N,CloneAllocator>
0079 this_type;
0080
0081 public:
0082 typedef std::size_t size_type;
0083 typedef U* value_type;
0084 typedef U* pointer;
0085 typedef U& reference;
0086 typedef const U& const_reference;
0087 typedef BOOST_DEDUCED_TYPENAME base_class::auto_type
0088 auto_type;
0089
0090 public:
0091 ptr_array() : base_class()
0092 { }
0093
0094 ptr_array( const ptr_array& r )
0095 {
0096 size_t i = 0;
0097 for( ; i != N; ++i )
0098 this->base()[i] = this->null_policy_allocate_clone(
0099 static_cast<const U*>( &r[i] ) );
0100 }
0101
0102 template< class U >
0103 ptr_array( const ptr_array<U,N>& r )
0104 {
0105 size_t i = 0;
0106 for( ; i != N; ++i )
0107 this->base()[i] = this->null_policy_allocate_clone(
0108 static_cast<const T*>( &r[i] ) );
0109 }
0110
0111 #ifndef BOOST_NO_AUTO_PTR
0112 explicit ptr_array( std::auto_ptr<this_type> r )
0113 : base_class( r ) { }
0114 #endif
0115 #ifndef BOOST_NO_CXX11_SMART_PTR
0116 explicit ptr_array( std::unique_ptr<this_type> r )
0117 : base_class( std::move( r ) ) { }
0118 #endif
0119
0120 ptr_array& operator=( ptr_array r )
0121 {
0122 this->swap( r );
0123 return *this;
0124 }
0125
0126 #ifndef BOOST_NO_AUTO_PTR
0127 ptr_array& operator=( std::auto_ptr<this_type> r )
0128 {
0129 base_class::operator=(r);
0130 return *this;
0131 }
0132 #endif
0133 #ifndef BOOST_NO_CXX11_SMART_PTR
0134 ptr_array& operator=( std::unique_ptr<this_type> r )
0135 {
0136 base_class::operator=(std::move(r));
0137 return *this;
0138 }
0139 #endif
0140
0141 #ifndef BOOST_NO_AUTO_PTR
0142 std::auto_ptr<this_type> release()
0143 {
0144 std::auto_ptr<this_type> ptr( new this_type );
0145 this->swap( *ptr );
0146 return ptr;
0147 }
0148
0149 std::auto_ptr<this_type> clone() const
0150 {
0151 std::auto_ptr<this_type> pa( new this_type );
0152 clone_array_elements( *pa );
0153 return pa;
0154 }
0155 #else
0156 std::unique_ptr<this_type> release()
0157 {
0158 std::unique_ptr<this_type> ptr( new this_type );
0159 this->swap( *ptr );
0160 return ptr;
0161 }
0162
0163 std::unique_ptr<this_type> clone() const
0164 {
0165 std::unique_ptr<this_type> pa( new this_type );
0166 clone_array_elements( *pa );
0167 return pa;
0168 }
0169 #endif
0170 private:
0171 void clone_array_elements( this_type &pa ) const
0172 {
0173 for( size_t i = 0; i != N; ++i )
0174 {
0175 if( !this->is_null(i) )
0176 pa.replace( i, pa.null_policy_allocate_clone( &(*this)[i] ) );
0177 }
0178 }
0179
0180 private:
0181 using base_class::insert;
0182 using base_class::erase;
0183 using base_class::push_back;
0184 using base_class::push_front;
0185 using base_class::pop_front;
0186 using base_class::pop_back;
0187 using base_class::transfer;
0188 using base_class::get_allocator;
0189
0190 public:
0191
0192 template< size_t idx >
0193 auto_type replace( U* r )
0194 {
0195 BOOST_STATIC_ASSERT( idx < N );
0196
0197 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
0198 auto_type res( static_cast<U*>(this->base()[idx]), *this );
0199 this->base()[idx] = r;
0200 return boost::ptr_container::move(res);
0201 }
0202
0203 #ifndef BOOST_NO_AUTO_PTR
0204 template< size_t idx, class V >
0205 auto_type replace( std::auto_ptr<V> r )
0206 {
0207 return replace<idx>( r.release() );
0208 }
0209 #endif
0210 #ifndef BOOST_NO_CXX11_SMART_PTR
0211 template< size_t idx, class V >
0212 auto_type replace( std::unique_ptr<V> r )
0213 {
0214 return replace<idx>( r.release() );
0215 }
0216 #endif
0217
0218 auto_type replace( size_t idx, U* r )
0219 {
0220 this->enforce_null_policy( r, "Null pointer in 'ptr_array::replace()'" );
0221
0222 auto_type ptr( r, *this );
0223 BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= N, bad_index,
0224 "'replace()' aout of bounds" );
0225
0226 auto_type res( static_cast<U*>(this->base()[idx]), *this );
0227 this->base()[idx] = ptr.release();
0228 return boost::ptr_container::move(res);
0229 }
0230
0231 #ifndef BOOST_NO_AUTO_PTR
0232 template< class V >
0233 auto_type replace( size_t idx, std::auto_ptr<V> r )
0234 {
0235 return replace( idx, r.release() );
0236 }
0237 #endif
0238 #ifndef BOOST_NO_CXX11_SMART_PTR
0239 template< class V >
0240 auto_type replace( size_t idx, std::unique_ptr<V> r )
0241 {
0242 return replace( idx, r.release() );
0243 }
0244 #endif
0245
0246 using base_class::at;
0247
0248 template< size_t idx >
0249 T& at()
0250 {
0251 BOOST_STATIC_ASSERT( idx < N );
0252 return (*this)[idx];
0253 }
0254
0255 template< size_t idx >
0256 const T& at() const
0257 {
0258 BOOST_STATIC_ASSERT( idx < N );
0259 return (*this)[idx];
0260 }
0261
0262 bool is_null( size_t idx ) const
0263 {
0264 return base_class::is_null(idx);
0265 }
0266
0267 template< size_t idx >
0268 bool is_null() const
0269 {
0270 BOOST_STATIC_ASSERT( idx < N );
0271 return this->base()[idx] == 0;
0272 }
0273 };
0274
0275
0276
0277
0278 template< typename T, size_t size, typename CA >
0279 inline ptr_array<T,size,CA>* new_clone( const ptr_array<T,size,CA>& r )
0280 {
0281 return r.clone().release();
0282 }
0283
0284
0285
0286
0287 template< typename T, size_t size, typename CA >
0288 inline void swap( ptr_array<T,size,CA>& l, ptr_array<T,size,CA>& r )
0289 {
0290 l.swap(r);
0291 }
0292 }
0293
0294 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0295 #pragma GCC diagnostic pop
0296 #endif
0297
0298 #endif