File indexing completed on 2025-12-16 10:07:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_PTR_CONTAINER_PTR_CIRCULAR_BUFFER_HPP
0013 #define BOOST_PTR_CONTAINER_PTR_CIRCULAR_BUFFER_HPP
0014
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018
0019 #include <boost/circular_buffer.hpp>
0020 #include <boost/ptr_container/ptr_sequence_adapter.hpp>
0021 #include <boost/next_prior.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 template
0033 <
0034 class T,
0035 class CloneAllocator = heap_clone_allocator,
0036 class Allocator = std::allocator<void*>
0037 >
0038 class ptr_circular_buffer : public
0039 ptr_sequence_adapter< T, boost::circular_buffer<
0040 typename ptr_container_detail::void_ptr<T>::type,Allocator>,
0041 CloneAllocator >
0042 {
0043 typedef ptr_sequence_adapter< T, boost::circular_buffer<
0044 typename ptr_container_detail::void_ptr<T>::type,Allocator>,
0045 CloneAllocator >
0046 base_type;
0047
0048 typedef boost::circular_buffer<typename
0049 ptr_container_detail::void_ptr<T>::type,Allocator> circular_buffer_type;
0050 typedef ptr_circular_buffer<T,CloneAllocator,Allocator> this_type;
0051
0052 public:
0053 typedef typename base_type::value_type value_type;
0054 typedef value_type* pointer;
0055 typedef const value_type* const_pointer;
0056 typedef typename base_type::size_type size_type;
0057 typedef typename base_type::allocator_type allocator_type;
0058 typedef typename base_type::iterator iterator;
0059 typedef typename base_type::const_iterator const_iterator;
0060 typedef typename base_type::auto_type auto_type;
0061
0062 typedef std::pair<pointer,size_type> array_range;
0063 typedef std::pair<const_pointer,size_type> const_array_range;
0064 typedef typename circular_buffer_type::capacity_type capacity_type;
0065
0066 public:
0067 ptr_circular_buffer()
0068 { }
0069
0070 explicit ptr_circular_buffer( capacity_type n )
0071 : base_type( n, ptr_container_detail::fixed_length_sequence_tag() )
0072 { }
0073
0074 ptr_circular_buffer( capacity_type n,
0075 const allocator_type& alloc )
0076 : base_type( n, alloc, ptr_container_detail::fixed_length_sequence_tag() )
0077 { }
0078
0079 template< class ForwardIterator >
0080 ptr_circular_buffer( ForwardIterator first, ForwardIterator last )
0081 : base_type( first, last, ptr_container_detail::fixed_length_sequence_tag() )
0082 { }
0083
0084 template< class InputIterator >
0085 ptr_circular_buffer( capacity_type n, InputIterator first, InputIterator last )
0086 : base_type( n, first, last, ptr_container_detail::fixed_length_sequence_tag() )
0087 { }
0088
0089 ptr_circular_buffer( const ptr_circular_buffer& r )
0090 : base_type( r.size(), r.begin(), r.end(),
0091 ptr_container_detail::fixed_length_sequence_tag() )
0092 { }
0093
0094 template< class U >
0095 ptr_circular_buffer( const ptr_circular_buffer<U>& r )
0096 : base_type( r.size(), r.begin(), r.end(),
0097 ptr_container_detail::fixed_length_sequence_tag() )
0098 { }
0099
0100 ptr_circular_buffer& operator=( ptr_circular_buffer r )
0101 {
0102 this->swap( r );
0103 return *this;
0104 }
0105
0106 BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( ptr_circular_buffer,
0107 base_type, this_type )
0108
0109 public:
0110 allocator_type& get_allocator()
0111 {
0112 return this->base().get_allocator();
0113 }
0114
0115 allocator_type get_allocator() const
0116 {
0117 return this->base().get_allocator();
0118 }
0119
0120 public:
0121 array_range array_one()
0122 {
0123 typename circular_buffer_type::array_range r = this->base().array_one();
0124 return array_range( reinterpret_cast<pointer>(r.first), r.second );
0125 }
0126
0127 const_array_range array_one() const
0128 {
0129 typename circular_buffer_type::const_array_range r = this->base().array_one();
0130 return const_array_range( reinterpret_cast<const_pointer>(r.first), r.second );
0131 }
0132
0133 array_range array_two()
0134 {
0135 typename circular_buffer_type::array_range r = this->base().array_two();
0136 return array_range( reinterpret_cast<pointer>(r.first), r.second );
0137 }
0138
0139 const_array_range array_two() const
0140 {
0141 typename circular_buffer_type::const_array_range r = this->base().array_two();
0142 return const_array_range( reinterpret_cast<const_pointer>(r.first), r.second );
0143 }
0144
0145 pointer linearize()
0146 {
0147 return reinterpret_cast<pointer>(this->base().linearize());
0148 }
0149
0150 bool full() const
0151 {
0152 return this->base().full();
0153 }
0154
0155 size_type reserve() const
0156 {
0157 return this->base().reserve();
0158 }
0159
0160 void reserve( size_type n )
0161 {
0162 if( capacity() < n )
0163 set_capacity( n );
0164 }
0165
0166 capacity_type capacity() const
0167 {
0168 return this->base().capacity();
0169 }
0170
0171 void set_capacity( capacity_type new_capacity )
0172 {
0173 if( this->size() > new_capacity )
0174 {
0175 this->erase( this->begin() + new_capacity, this->end() );
0176 }
0177 this->base().set_capacity( new_capacity );
0178 }
0179
0180 void rset_capacity( capacity_type new_capacity )
0181 {
0182 if( this->size() > new_capacity )
0183 {
0184 this->erase( this->begin(),
0185 this->begin() + (this->size()-new_capacity) );
0186 }
0187 this->base().rset_capacity( new_capacity );
0188 }
0189
0190 void resize( size_type size )
0191 {
0192 size_type old_size = this->size();
0193 if( old_size > size )
0194 {
0195 this->erase( boost::next( this->begin(), size ), this->end() );
0196 }
0197 else if( size > old_size )
0198 {
0199 for( ; old_size != size; ++old_size )
0200 this->push_back( new BOOST_DEDUCED_TYPENAME
0201 boost::remove_pointer<value_type>::type() );
0202 }
0203
0204 BOOST_ASSERT( this->size() == size );
0205 }
0206
0207 void resize( size_type size, value_type to_clone )
0208 {
0209 size_type old_size = this->size();
0210 if( old_size > size )
0211 {
0212 this->erase( boost::next( this->begin(), size ), this->end() );
0213 }
0214 else if( size > old_size )
0215 {
0216 for( ; old_size != size; ++old_size )
0217 this->push_back( this->null_policy_allocate_clone( to_clone ) );
0218 }
0219
0220 BOOST_ASSERT( this->size() == size );
0221 }
0222
0223 void rresize( size_type size )
0224 {
0225 size_type old_size = this->size();
0226 if( old_size > size )
0227 {
0228 this->erase( this->begin(),
0229 boost::next( this->begin(), old_size - size ) );
0230 }
0231 else if( size > old_size )
0232 {
0233 for( ; old_size != size; ++old_size )
0234 this->push_front( new BOOST_DEDUCED_TYPENAME
0235 boost::remove_pointer<value_type>::type() );
0236 }
0237
0238 BOOST_ASSERT( this->size() == size );
0239 }
0240
0241 void rresize( size_type size, value_type to_clone )
0242 {
0243 size_type old_size = this->size();
0244 if( old_size > size )
0245 {
0246 this->erase( this->begin(),
0247 boost::next( this->begin(), old_size - size ) );
0248 }
0249 else if( size > old_size )
0250 {
0251 for( ; old_size != size; ++old_size )
0252 this->push_front( this->null_policy_allocate_clone( to_clone ) );
0253 }
0254
0255 BOOST_ASSERT( this->size() == size );
0256 }
0257
0258 template< class InputIterator >
0259 void assign( InputIterator first, InputIterator last )
0260 {
0261 ptr_circular_buffer temp( first, last );
0262 this->swap( temp );
0263 }
0264
0265 template< class Range >
0266 void assign( const Range& r )
0267 {
0268 assign( boost::begin(r), boost::end(r ) );
0269 }
0270
0271 void assign( size_type n, value_type to_clone )
0272 {
0273 ptr_circular_buffer temp( n );
0274 for( size_type i = 0u; i != n; ++i )
0275 temp.push_back( temp.null_policy_allocate_clone( to_clone ) );
0276 this->swap( temp );
0277 }
0278
0279 void assign( capacity_type capacity, size_type n,
0280 value_type to_clone )
0281 {
0282 this->assign( (std::min)(n,capacity), to_clone );
0283 }
0284
0285 template< class InputIterator >
0286 void assign( capacity_type capacity,
0287 InputIterator first, InputIterator last )
0288 {
0289 this->assign( first, last );
0290 this->set_capacity( capacity );
0291 }
0292
0293 void push_back( value_type ptr )
0294 {
0295 BOOST_ASSERT( capacity() > 0 );
0296 this->enforce_null_policy( ptr, "Null pointer in 'push_back()'" );
0297
0298 auto_type old_ptr( value_type(), *this );
0299 if( full() )
0300 old_ptr.reset( &*this->begin(), *this );
0301 this->base().push_back( ptr );
0302 }
0303
0304 #ifndef BOOST_NO_AUTO_PTR
0305 template< class U >
0306 void push_back( std::auto_ptr<U> ptr )
0307 {
0308 push_back( ptr.release() );
0309 }
0310 #endif
0311 #ifndef BOOST_NO_CXX11_SMART_PTR
0312 template< class U >
0313 void push_back( std::unique_ptr<U> ptr )
0314 {
0315 push_back( ptr.release() );
0316 }
0317 #endif
0318
0319 void push_front( value_type ptr )
0320 {
0321 BOOST_ASSERT( capacity() > 0 );
0322 this->enforce_null_policy( ptr, "Null pointer in 'push_front()'" );
0323
0324 auto_type old_ptr( value_type(), *this );
0325 if( full() )
0326 old_ptr.reset( &*(--this->end()), *this );
0327 this->base().push_front( ptr );
0328 }
0329
0330 #ifndef BOOST_NO_AUTO_PTR
0331 template< class U >
0332 void push_front( std::auto_ptr<U> ptr )
0333 {
0334 push_front( ptr.release() );
0335 }
0336 #endif
0337 #ifndef BOOST_NO_CXX11_SMART_PTR
0338 template< class U >
0339 void push_front( std::unique_ptr<U> ptr )
0340 {
0341 push_front( ptr.release() );
0342 }
0343 #endif
0344
0345 iterator insert( iterator pos, value_type ptr )
0346 {
0347 BOOST_ASSERT( capacity() > 0 );
0348 this->enforce_null_policy( ptr, "Null pointer in 'insert()'" );
0349
0350 auto_type new_ptr( ptr, *this );
0351 iterator b = this->begin();
0352 if( full() && pos == b )
0353 return b;
0354
0355 new_ptr.release();
0356 auto_type old_ptr( value_type(), *this );
0357 if( full() )
0358 old_ptr.reset( &*this->begin(), *this );
0359
0360 return this->base().insert( pos.base(), ptr );
0361 }
0362
0363 #ifndef BOOST_NO_AUTO_PTR
0364 template< class U >
0365 iterator insert( iterator pos, std::auto_ptr<U> ptr )
0366 {
0367 return insert( pos, ptr.release() );
0368 }
0369 #endif
0370 #ifndef BOOST_NO_CXX11_SMART_PTR
0371 template< class U >
0372 iterator insert( iterator pos, std::unique_ptr<U> ptr )
0373 {
0374 return insert( pos, ptr.release() );
0375 }
0376 #endif
0377
0378 template< class InputIterator >
0379 void insert( iterator pos, InputIterator first, InputIterator last )
0380 {
0381 for( ; first != last; ++first, ++pos )
0382 pos = insert( pos, this->null_policy_allocate_clone( &*first ) );
0383 }
0384
0385 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0386 #else
0387 template< class Range >
0388 BOOST_DEDUCED_TYPENAME
0389 boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
0390 insert( iterator before, const Range& r )
0391 {
0392 insert( before, boost::begin(r), boost::end(r) );
0393 }
0394
0395 #endif
0396
0397 iterator rinsert( iterator pos, value_type ptr )
0398 {
0399 BOOST_ASSERT( capacity() > 0 );
0400 this->enforce_null_policy( ptr, "Null pointer in 'rinsert()'" );
0401
0402 auto_type new_ptr( ptr, *this );
0403 iterator b = this->end();
0404 if (full() && pos == b)
0405 return b;
0406
0407 new_ptr.release();
0408 auto_type old_ptr( value_type(), *this );
0409 if( full() )
0410 old_ptr.reset( &this->back(), *this );
0411
0412 return this->base().rinsert( pos.base(), ptr );
0413 }
0414
0415 #ifndef BOOST_NO_AUTO_PTR
0416 template< class U >
0417 iterator rinsert( iterator pos, std::auto_ptr<U> ptr )
0418 {
0419 return rinsert( pos, ptr.release() );
0420 }
0421 #endif
0422 #ifndef BOOST_NO_CXX11_SMART_PTR
0423 template< class U >
0424 iterator rinsert( iterator pos, std::unique_ptr<U> ptr )
0425 {
0426 return rinsert( pos, ptr.release() );
0427 }
0428 #endif
0429
0430
0431 template< class InputIterator >
0432 void rinsert( iterator pos, InputIterator first, InputIterator last )
0433 {
0434 for( ; first != last; ++first, ++pos )
0435 pos = rinsert( pos, this->null_policy_allocate_clone( &*first ) );
0436 }
0437
0438 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0439 #else
0440 template< class Range >
0441 BOOST_DEDUCED_TYPENAME
0442 boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
0443 rinsert( iterator before, const Range& r )
0444 {
0445 rinsert( before, boost::begin(r), boost::end(r) );
0446 }
0447
0448 #endif
0449
0450 iterator rerase( iterator pos )
0451 {
0452 BOOST_ASSERT( !this->empty() );
0453 BOOST_ASSERT( pos != this->end() );
0454
0455 this->remove( pos );
0456 return iterator( this->base().rerase( pos.base() ) );
0457 }
0458
0459 iterator rerase( iterator first, iterator last )
0460 {
0461 this->remove( first, last );
0462 return iterator( this->base().rerase( first.base(),
0463 last.base() ) );
0464 }
0465
0466 template< class Range >
0467 iterator rerase( const Range& r )
0468 {
0469 return rerase( boost::begin(r), boost::end(r) );
0470 }
0471
0472 void rotate( const_iterator new_begin )
0473 {
0474 this->base().rotate( new_begin.base() );
0475 }
0476
0477 public:
0478 template< class PtrSeqAdapter >
0479 void transfer( iterator before,
0480 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator first,
0481 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator last,
0482 PtrSeqAdapter& from )
0483 {
0484 BOOST_ASSERT( (void*)&from != (void*)this );
0485 if( from.empty() )
0486 return;
0487 for( BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator begin = first;
0488 begin != last; ++begin, ++before )
0489 before = insert( before, &*begin );
0490 from.base().erase( first.base(), last.base() );
0491 }
0492
0493 template< class PtrSeqAdapter >
0494 void transfer( iterator before,
0495 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object,
0496 PtrSeqAdapter& from )
0497 {
0498 BOOST_ASSERT( (void*)&from != (void*)this );
0499 if( from.empty() )
0500 return;
0501 insert( before, &*object );
0502 from.base().erase( object.base() );
0503 }
0504
0505 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
0506 #else
0507
0508 template< class PtrSeqAdapter, class Range >
0509 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
0510 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator > >::type
0511 transfer( iterator before, const Range& r, PtrSeqAdapter& from )
0512 {
0513 transfer( before, boost::begin(r), boost::end(r), from );
0514 }
0515
0516 #endif
0517 template< class PtrSeqAdapter >
0518 void transfer( iterator before, PtrSeqAdapter& from )
0519 {
0520 transfer( before, from.begin(), from.end(), from );
0521 }
0522
0523 public:
0524
0525 void transfer( iterator before, value_type* from,
0526 size_type size, bool delete_from = true )
0527 {
0528 BOOST_ASSERT( from != 0 );
0529 if( delete_from )
0530 {
0531 BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
0532 deleter( *this, from, size );
0533 for( size_type i = 0u; i != size; ++i, ++before )
0534 before = insert( before, *(from+i) );
0535 deleter.release();
0536 }
0537 else
0538 {
0539 for( size_type i = 0u; i != size; ++i, ++before )
0540 before = insert( before, *(from+i) );
0541 }
0542 }
0543
0544 value_type* c_array()
0545 {
0546 if( this->empty() )
0547 return 0;
0548 this->linearize();
0549 T** res = reinterpret_cast<T**>( &this->begin().base()[0] );
0550 return res;
0551 }
0552
0553 };
0554
0555
0556
0557
0558 template< typename T, typename CA, typename A >
0559 inline ptr_circular_buffer<T,CA,A>* new_clone( const ptr_circular_buffer<T,CA,A>& r )
0560 {
0561 return r.clone().release();
0562 }
0563
0564
0565
0566
0567 template< typename T, typename CA, typename A >
0568 inline void swap( ptr_circular_buffer<T,CA,A>& l, ptr_circular_buffer<T,CA,A>& r )
0569 {
0570 l.swap(r);
0571 }
0572
0573 }
0574
0575 #if defined(BOOST_PTR_CONTAINER_DISABLE_DEPRECATED)
0576 #pragma GCC diagnostic pop
0577 #endif
0578
0579 #endif