fix doc example typo
[boost.git] / boost / ptr_container / ptr_circular_buffer.hpp
blob7fdc01b15de25707788b2699787876e5f31e1882
1 //
2 // Boost.Pointer Container
3 //
4 // Copyright Thorsten Ottosen 2008. 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)
8 //
9 // For more information, see http://www.boost.org/libs/ptr_container/
12 #ifndef BOOST_PTR_CONTAINER_PTR_CIRCULAR_BUFFER_HPP
13 #define BOOST_PTR_CONTAINER_PTR_CIRCULAR_BUFFER_HPP
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 # pragma once
17 #endif
19 #include <boost/circular_buffer.hpp>
20 #include <boost/ptr_container/ptr_sequence_adapter.hpp>
22 namespace boost
25 template
27 class T,
28 class CloneAllocator = heap_clone_allocator,
29 class Allocator = std::allocator<void*>
31 class ptr_circular_buffer : public
32 ptr_sequence_adapter< T,
33 boost::circular_buffer<void*,Allocator>,
34 CloneAllocator >
36 typedef ptr_sequence_adapter< T,
37 boost::circular_buffer<void*,Allocator>,
38 CloneAllocator >
39 base_type;
41 typedef boost::circular_buffer<void*,Allocator> circular_buffer_type;
42 typedef ptr_circular_buffer<T,CloneAllocator,Allocator> this_type;
44 public: // typedefs
45 typedef typename base_type::value_type value_type;
46 typedef value_type* pointer;
47 typedef const value_type* const_pointer;
48 typedef typename base_type::size_type size_type;
49 typedef typename base_type::allocator_type allocator_type;
50 typedef typename base_type::iterator iterator;
51 typedef typename base_type::const_iterator const_iterator;
52 typedef typename base_type::auto_type auto_type;
54 typedef std::pair<pointer,size_type> array_range;
55 typedef std::pair<const_pointer,size_type> const_array_range;
56 typedef typename circular_buffer_type::capacity_type capacity_type;
58 public: // constructors
59 ptr_circular_buffer()
60 { }
62 explicit ptr_circular_buffer( capacity_type n )
63 : base_type( n, ptr_container_detail::fixed_length_sequence_tag() )
64 { }
66 ptr_circular_buffer( capacity_type n,
67 const allocator_type& alloc )
68 : base_type( n, alloc, ptr_container_detail::fixed_length_sequence_tag() )
69 { }
71 template< class ForwardIterator >
72 ptr_circular_buffer( ForwardIterator first, ForwardIterator last )
73 : base_type( first, last, ptr_container_detail::fixed_length_sequence_tag() )
74 { }
76 template< class InputIterator >
77 ptr_circular_buffer( capacity_type n, InputIterator first, InputIterator last )
78 : base_type( n, first, last, ptr_container_detail::fixed_length_sequence_tag() )
79 { }
81 ptr_circular_buffer( const ptr_circular_buffer& r )
82 : base_type( r.size(), r.begin(), r.end(),
83 ptr_container_detail::fixed_length_sequence_tag() )
84 { }
86 template< class U >
87 ptr_circular_buffer( const ptr_circular_buffer<U>& r )
88 : base_type( r.size(), r.begin(), r.end(),
89 ptr_container_detail::fixed_length_sequence_tag() )
90 { }
92 ptr_circular_buffer& operator=( ptr_circular_buffer r )
94 this->swap( r );
95 return *this;
98 BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( ptr_circular_buffer,
99 base_type, this_type )
101 public: // allocators
102 allocator_type& get_allocator()
104 return this->base().get_allocator();
107 allocator_type get_allocator() const
109 return this->base().get_allocator();
112 public: // circular buffer functions
113 array_range array_one() // nothrow
115 typename circular_buffer_type::array_range r = this->base().array_one();
116 return array_range( reinterpret_cast<pointer>(r.first), r.second );
119 const_array_range array_one() const // nothrow
121 typename circular_buffer_type::const_array_range r = this->base().array_one();
122 return const_array_range( reinterpret_cast<const_pointer>(r.first), r.second );
125 array_range array_two() // nothrow
127 typename circular_buffer_type::array_range r = this->base().array_two();
128 return array_range( reinterpret_cast<pointer>(r.first), r.second );
131 const_array_range array_two() const // nothrow
133 typename circular_buffer_type::const_array_range r = this->base().array_two();
134 return const_array_range( reinterpret_cast<const_pointer>(r.first), r.second );
137 pointer linearize() // nothrow
139 return reinterpret_cast<pointer>(this->base().linearize());
142 bool full() const // nothrow
144 return this->base().full();
147 size_type reserve() const // nothrow
149 return this->base().reserve();
152 void reserve( size_type n ) // strong
154 if( capacity() < n )
155 set_capacity( n );
158 capacity_type capacity() const // nothrow
160 return this->base().capacity();
163 void set_capacity( capacity_type new_capacity ) // strong
165 if( this->size() > new_capacity )
167 this->erase( this->begin() + new_capacity, this->end() );
169 this->base().set_capacity( new_capacity );
172 void rset_capacity( capacity_type new_capacity ) // strong
174 if( this->size() > new_capacity )
176 this->erase( this->begin(),
177 this->begin() + (this->size()-new_capacity) );
179 this->base().rset_capacity( new_capacity );
182 void resize( size_type size ) // basic
184 size_type old_size = this->size();
185 if( old_size > size )
187 this->erase( boost::next( this->begin(), size ), this->end() );
189 else if( size > old_size )
191 for( ; old_size != size; ++old_size )
192 this->push_back( new BOOST_DEDUCED_TYPENAME
193 boost::remove_pointer<value_type>::type );
196 BOOST_ASSERT( this->size() == size );
199 void resize( size_type size, value_type to_clone ) // basic
201 size_type old_size = this->size();
202 if( old_size > size )
204 this->erase( boost::next( this->begin(), size ), this->end() );
206 else if( size > old_size )
208 for( ; old_size != size; ++old_size )
209 this->push_back( this->null_policy_allocate_clone( to_clone ) );
212 BOOST_ASSERT( this->size() == size );
215 void rresize( size_type size ) // basic
217 size_type old_size = this->size();
218 if( old_size > size )
220 this->erase( this->begin(),
221 boost::next( this->begin(), old_size - size ) );
223 else if( size > old_size )
225 for( ; old_size != size; ++old_size )
226 this->push_front( new BOOST_DEDUCED_TYPENAME
227 boost::remove_pointer<value_type>::type );
230 BOOST_ASSERT( this->size() == size );
233 void rresize( size_type size, value_type to_clone ) // basic
235 size_type old_size = this->size();
236 if( old_size > size )
238 this->erase( this->begin(),
239 boost::next( this->begin(), old_size - size ) );
241 else if( size > old_size )
243 for( ; old_size != size; ++old_size )
244 this->push_front( this->null_policy_allocate_clone( to_clone ) );
247 BOOST_ASSERT( this->size() == size );
250 template< class InputIterator >
251 void assign( InputIterator first, InputIterator last ) // strong
253 ptr_circular_buffer temp( first, last );
254 this->swap( temp );
257 template< class Range >
258 void assign( const Range& r ) // strong
260 assign( boost::begin(r), boost::end(r ) );
263 void assign( size_type n, value_type to_clone ) // strong
265 ptr_circular_buffer temp( n );
266 for( size_type i = 0u; i != n; ++i )
267 temp.push_back( this->null_policy_allocate_clone( to_clone ) );
268 this->swap( temp );
271 void assign( capacity_type capacity, size_type n,
272 value_type to_clone ) // basic
274 this->assign( (std::min)(n,capacity), to_clone );
277 template< class InputIterator >
278 void assign( capacity_type capacity,
279 InputIterator first, InputIterator last ) // basic
281 this->assign( first, last );
282 this->set_capacity( capacity );
285 void push_back( value_type ptr ) // nothrow
287 BOOST_ASSERT( capacity() > 0 );
288 this->enforce_null_policy( ptr, "Null pointer in 'push_back()'" );
290 auto_type old_ptr;
291 if( full() )
292 old_ptr.reset( &*this->begin() );
293 this->base().push_back( ptr );
296 template< class U >
297 void push_back( std::auto_ptr<U> ptr ) // nothrow
299 push_back( ptr.release() );
302 void push_front( value_type ptr ) // nothrow
304 BOOST_ASSERT( capacity() > 0 );
305 this->enforce_null_policy( ptr, "Null pointer in 'push_front()'" );
307 auto_type old_ptr;
308 if( full() )
309 old_ptr.reset( &*(--this->end()) );
310 this->base().push_front( ptr );
313 template< class U >
314 void push_front( std::auto_ptr<U> ptr ) // nothrow
316 push_front( ptr.release() );
319 iterator insert( iterator pos, value_type ptr ) // nothrow
321 BOOST_ASSERT( capacity() > 0 );
322 this->enforce_null_policy( ptr, "Null pointer in 'insert()'" );
324 auto_type new_ptr( ptr );
325 iterator b = this->begin();
326 if( full() && pos == b )
327 return b;
329 auto_type old_ptr;
330 if( full() )
331 old_ptr.reset( &*this->begin() );
333 new_ptr.release();
334 return this->base().insert( pos.base(), ptr );
337 template< class U >
338 iterator insert( iterator pos, std::auto_ptr<U> ptr ) // nothrow
340 return insert( pos, ptr.release() );
343 template< class InputIterator >
344 void insert( iterator pos, InputIterator first, InputIterator last ) // basic
346 for( ; first != last; ++first, ++pos )
347 pos = insert( pos, this->null_policy_allocate_clone( &*first ) );
350 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
351 #else
352 template< class Range >
353 BOOST_DEDUCED_TYPENAME
354 boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
355 insert( iterator before, const Range& r )
357 insert( before, boost::begin(r), boost::end(r) );
360 #endif
362 iterator rinsert( iterator pos, value_type ptr ) // nothrow
364 BOOST_ASSERT( capacity() > 0 );
365 this->enforce_null_policy( ptr, "Null pointer in 'rinsert()'" );
367 auto_type new_ptr( ptr );
368 iterator b = this->end();
369 if (full() && pos == b)
370 return b;
372 auto_type old_ptr;
373 if( full() )
374 old_ptr.reset( &this->back() );
376 new_ptr.release();
377 return this->base().rinsert( pos.base(), ptr );
380 template< class U >
381 iterator rinsert( iterator pos, std::auto_ptr<U> ptr ) // nothrow
383 return rinsert( pos, ptr.release() );
387 template< class InputIterator >
388 void rinsert( iterator pos, InputIterator first, InputIterator last ) // basic
390 for( ; first != last; ++first, ++pos )
391 pos = rinsert( pos, this->null_policy_allocate_clone( &*first ) );
394 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
395 #else
396 template< class Range >
397 BOOST_DEDUCED_TYPENAME
398 boost::disable_if< ptr_container_detail::is_pointer_or_integral<Range> >::type
399 rinsert( iterator before, const Range& r )
401 rinsert( before, boost::begin(r), boost::end(r) );
404 #endif
406 iterator rerase( iterator pos ) // nothrow
408 BOOST_ASSERT( !this->empty() );
409 BOOST_ASSERT( pos != this->end() );
411 this->remove( pos );
412 return iterator( this->base().rerase( pos.base() ) );
415 iterator rerase( iterator first, iterator last ) // nothrow
417 this->remove( first, last );
418 return iterator( this->base().rerase( first.base(),
419 last.base() ) );
422 template< class Range >
423 iterator rerase( const Range& r ) // nothrow
425 return rerase( boost::begin(r), boost::end(r) );
428 void rotate( const_iterator new_begin ) // nothrow
430 this->base().rotate( new_begin.base() );
433 public: // transfer
434 template< class PtrSeqAdapter >
435 void transfer( iterator before,
436 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator first,
437 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator last,
438 PtrSeqAdapter& from ) // nothrow
440 BOOST_ASSERT( (void*)&from != (void*)this );
441 if( from.empty() )
442 return;
443 for( BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator begin = first;
444 begin != last; ++begin, ++before )
445 before = insert( before, &*begin ); // nothrow
446 from.base().erase( first.base(), last.base() ); // nothrow
449 template< class PtrSeqAdapter >
450 void transfer( iterator before,
451 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator object,
452 PtrSeqAdapter& from ) // nothrow
454 BOOST_ASSERT( (void*)&from != (void*)this );
455 if( from.empty() )
456 return;
457 insert( before, &*object ); // nothrow
458 from.base().erase( object.base() ); // nothrow
461 #if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
462 #else
464 template< class PtrSeqAdapter, class Range >
465 BOOST_DEDUCED_TYPENAME boost::disable_if< boost::is_same< Range,
466 BOOST_DEDUCED_TYPENAME PtrSeqAdapter::iterator > >::type
467 transfer( iterator before, const Range& r, PtrSeqAdapter& from ) // nothrow
469 transfer( before, boost::begin(r), boost::end(r), from );
472 #endif
473 template< class PtrSeqAdapter >
474 void transfer( iterator before, PtrSeqAdapter& from ) // nothrow
476 transfer( before, from.begin(), from.end(), from );
479 public: // C-array support
481 void transfer( iterator before, value_type* from,
482 size_type size, bool delete_from = true ) // nothrow
484 BOOST_ASSERT( from != 0 );
485 if( delete_from )
487 BOOST_DEDUCED_TYPENAME base_type::scoped_deleter
488 deleter( from, size ); // nothrow
489 for( size_type i = 0u; i != size; ++i, ++before )
490 before = insert( before, *(from+i) ); // nothrow
491 deleter.release(); // nothrow
493 else
495 for( size_type i = 0u; i != size; ++i, ++before )
496 before = insert( before, *(from+i) ); // nothrow
500 value_type* c_array() // nothrow
502 if( this->empty() )
503 return 0;
504 this->linearize();
505 T** res = reinterpret_cast<T**>( &this->begin().base()[0] );
506 return res;
511 //////////////////////////////////////////////////////////////////////////////
512 // clonability
514 template< typename T, typename CA, typename A >
515 inline ptr_circular_buffer<T,CA,A>* new_clone( const ptr_circular_buffer<T,CA,A>& r )
517 return r.clone().release();
520 /////////////////////////////////////////////////////////////////////////
521 // swap
523 template< typename T, typename CA, typename A >
524 inline void swap( ptr_circular_buffer<T,CA,A>& l, ptr_circular_buffer<T,CA,A>& r )
526 l.swap(r);
531 #endif