Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:07:38

0001 //
0002 // Boost.Pointer Container
0003 //
0004 //  Copyright Thorsten Ottosen 2008. Use, modification and
0005 //  distribution is subject to the Boost Software License, Version
0006 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // For more information, see http://www.boost.org/libs/ptr_container/
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: // typedefs
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: // constructors
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: // allocators
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: // circular buffer functions
0121         array_range array_one() // nothrow
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 // nothrow
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() // nothrow
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 // nothrow
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() // nothrow
0146         {
0147             return reinterpret_cast<pointer>(this->base().linearize());
0148         }
0149 
0150         bool full() const // nothrow
0151         {
0152             return this->base().full();
0153         }
0154 
0155         size_type reserve() const // nothrow
0156         {
0157             return this->base().reserve();
0158         }
0159 
0160         void reserve( size_type n ) // strong
0161         {
0162             if( capacity() < n )
0163                 set_capacity( n );
0164         }
0165 
0166         capacity_type capacity() const // nothrow
0167         {
0168             return this->base().capacity();
0169         }
0170 
0171         void set_capacity( capacity_type new_capacity ) // strong
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 ) // strong
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 ) // basic
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 ) // basic
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 ) // basic
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 ) // basic
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 ) // strong
0260         {
0261             ptr_circular_buffer temp( first, last );
0262             this->swap( temp );
0263         }
0264 
0265         template< class Range >
0266         void assign( const Range& r ) // strong
0267         {
0268             assign( boost::begin(r), boost::end(r ) );
0269         }
0270 
0271         void assign( size_type n, value_type to_clone ) // strong
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 ) // basic
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 ) // basic
0288         {
0289             this->assign( first, last );
0290             this->set_capacity( capacity );
0291         }
0292 
0293         void push_back( value_type ptr ) // nothrow
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 ) // nothrow
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 ) // nothrow
0314         {
0315             push_back( ptr.release() );
0316         }
0317 #endif
0318 
0319         void push_front( value_type ptr ) // nothrow
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 ) // nothrow
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 ) // nothrow
0340         {
0341             push_front( ptr.release() );
0342         }
0343 #endif
0344 
0345         iterator insert( iterator pos, value_type ptr ) // nothrow
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 ) // nothrow
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 ) // nothrow
0373         {
0374             return insert( pos, ptr.release() );
0375         }
0376 #endif
0377 
0378         template< class InputIterator >
0379         void insert( iterator pos, InputIterator first, InputIterator last ) // basic
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 ) // nothrow
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 ) // nothrow
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 ) // nothrow
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 ) // basic
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 ) // nothrow
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 ) // nothrow
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 ) // nothrow
0468         {
0469             return rerase( boost::begin(r), boost::end(r) );
0470         }
0471 
0472         void rotate( const_iterator new_begin ) // nothrow
0473         {
0474             this->base().rotate( new_begin.base() );
0475         }
0476 
0477     public: // transfer
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 ) // nothrow
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 );          // nothrow
0490             from.base().erase( first.base(), last.base() );  // nothrow
0491         }
0492 
0493         template< class PtrSeqAdapter >
0494         void transfer( iterator before,
0495                        BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object,
0496                        PtrSeqAdapter& from ) // nothrow
0497         {
0498             BOOST_ASSERT( (void*)&from != (void*)this );
0499             if( from.empty() )
0500                 return;
0501             insert( before, &*object );          // nothrow
0502             from.base().erase( object.base() );  // nothrow
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 ) // nothrow
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 ) // nothrow
0519         {
0520             transfer( before, from.begin(), from.end(), from );
0521         }
0522 
0523     public: // C-array support
0524 
0525         void transfer( iterator before, value_type* from,
0526                        size_type size, bool delete_from = true ) // nothrow
0527         {
0528             BOOST_ASSERT( from != 0 );
0529             if( delete_from )
0530             {
0531                 BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
0532                     deleter( *this, from, size );                  // nothrow
0533                 for( size_type i = 0u; i != size; ++i, ++before )
0534                     before = insert( before, *(from+i) );          // nothrow
0535                 deleter.release();                                 // nothrow
0536             }
0537             else
0538             {
0539                 for( size_type i = 0u; i != size; ++i, ++before )
0540                     before = insert( before, *(from+i) );          // nothrow
0541            }
0542         }
0543 
0544         value_type* c_array() // nothrow
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     // clonability
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     // swap
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