Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
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 * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved.
15 #ifndef BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
16 #define BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP
18 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
22 #include <boost/ptr_container/detail/throw_exception.hpp>
23 #include <boost/ptr_container/detail/scoped_deleter.hpp>
24 #include <boost/ptr_container/detail/static_move_ptr.hpp>
25 #include <boost/ptr_container/exception.hpp>
26 #include <boost/ptr_container/clone_allocator.hpp>
27 #include <boost/ptr_container/nullable.hpp>
29 #ifdef BOOST_NO_SFINAE
31 #include <boost/range/functions.hpp>
34 #include <boost/config.hpp>
35 #include <boost/iterator/reverse_iterator.hpp>
36 #include <boost/range/iterator.hpp>
37 #include <boost/utility/enable_if.hpp>
38 #include <boost/type_traits/is_pointer.hpp>
39 #include <boost/type_traits/is_integral.hpp>
40 #include <boost/serialization/split_member.hpp>
46 #include <boost/range/begin.hpp>
47 #include <boost/range/end.hpp>
53 namespace ptr_container_detail
57 inline T const& serialize_as_const( T const& r )
62 template< class CloneAllocator >
66 void operator()( const T* p ) const
68 CloneAllocator::deallocate_clone( p );
73 struct is_pointer_or_integral
75 BOOST_STATIC_CONSTANT(bool, value = is_pointer<T>::value || is_integral<T>::value );
78 struct is_pointer_or_integral_tag {};
79 struct is_range_tag {};
88 class reversible_ptr_container
92 enum { allow_null = Config::allow_null };
94 BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null );
97 typedef BOOST_DEDUCED_TYPENAME Config::value_type Ty_;
99 template< bool allow_null_values >
100 struct null_clone_allocator
102 template< class Iter >
103 static Ty_* allocate_clone_from_iterator( Iter i )
105 return allocate_clone( Config::get_const_pointer( i ) );
108 static Ty_* allocate_clone( const Ty_* x )
110 if( allow_null_values )
117 BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" );
120 Ty_* res = CloneAllocator::allocate_clone( *x );
121 BOOST_ASSERT( typeid(*res) == typeid(*x) &&
122 "CloneAllocator::allocate_clone() does not clone the "
123 "object properly. Check that new_clone() is implemented"
128 static void deallocate_clone( const Ty_* x )
130 if( allow_null_values )
136 CloneAllocator::deallocate_clone( x );
140 typedef BOOST_DEDUCED_TYPENAME Config::void_container_type Cont;
141 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
142 typedef null_clone_allocator<reversible_ptr_container::allow_null>
145 typedef null_clone_allocator<allow_null> null_cloner_type;
147 typedef clone_deleter<null_cloner_type> Deleter;
152 Cont& c_private() { return c_; }
153 const Cont& c_private() const { return c_; }
156 typedef Ty_* value_type;
157 typedef Ty_* pointer;
158 typedef Ty_& reference;
159 typedef const Ty_& const_reference;
161 typedef BOOST_DEDUCED_TYPENAME Config::iterator
163 typedef BOOST_DEDUCED_TYPENAME Config::const_iterator
165 typedef boost::reverse_iterator< iterator >
167 typedef boost::reverse_iterator< const_iterator >
168 const_reverse_iterator;
169 typedef BOOST_DEDUCED_TYPENAME Cont::difference_type
171 typedef BOOST_DEDUCED_TYPENAME Cont::size_type
173 typedef BOOST_DEDUCED_TYPENAME Config::allocator_type
176 typedef ptr_container_detail::static_move_ptr<Ty_,Deleter>
181 typedef ptr_container_detail::scoped_deleter<Ty_,null_cloner_type>
183 typedef BOOST_DEDUCED_TYPENAME Cont::iterator
185 typedef BOOST_DEDUCED_TYPENAME Cont::const_iterator
189 template< class InputIterator >
190 void copy( InputIterator first, InputIterator last )
192 std::copy( first, last, begin() );
195 void copy( const reversible_ptr_container& r )
197 copy( r.begin(), r.end() );
200 void copy_clones_and_release( scoped_deleter& sd ) // nothrow
202 BOOST_ASSERT( size_type( std::distance( sd.begin(), sd.end() ) ) == c_.size() );
203 std::copy( sd.begin(), sd.end(), c_.begin() );
207 void insert_clones_and_release( scoped_deleter& sd ) // strong
209 c_.insert( sd.begin(), sd.end() );
213 template< class ForwardIterator >
214 void clone_assign( ForwardIterator first,
215 ForwardIterator last ) // strong
217 BOOST_ASSERT( first != last );
218 scoped_deleter sd( first, last ); // strong
219 copy_clones_and_release( sd ); // nothrow
222 template< class ForwardIterator >
223 void clone_back_insert( ForwardIterator first,
224 ForwardIterator last )
226 BOOST_ASSERT( first != last );
227 scoped_deleter sd( first, last );
228 insert_clones_and_release( sd, end() );
233 remove( begin(), end() );
238 void insert_clones_and_release( scoped_deleter& sd,
239 iterator where ) // strong
242 // 'c_.insert' always provides the strong guarantee for T* elements
243 // since a copy constructor of a pointer cannot throw
245 c_.insert( where.base(),
246 sd.begin(), sd.end() );
253 null_policy_deallocate_clone( Config::get_const_pointer(i) );
257 void remove( I first, I last )
259 for( ; first != last; ++first )
263 static void enforce_null_policy( Ty_* x, const char* msg )
267 BOOST_PTR_CONTAINER_THROW_EXCEPTION( 0 == x && "null not allowed",
272 static Ty_* null_policy_allocate_clone( const Ty_* x )
274 return null_cloner_type::allocate_clone( x );
277 static void null_policy_deallocate_clone( const Ty_* x )
279 null_cloner_type::deallocate_clone( x );
283 template< class ForwardIterator >
284 ForwardIterator advance( ForwardIterator begin, size_type n )
286 ForwardIterator iter = begin;
287 std::advance( iter, n );
292 reversible_ptr_container( const reversible_ptr_container& );
293 void operator=( const reversible_ptr_container& );
295 public: // foundation! should be protected!
296 explicit reversible_ptr_container( const allocator_type& a = allocator_type() )
300 template< class PtrContainer >
301 explicit reversible_ptr_container( std::auto_ptr<PtrContainer> clone )
302 : c_( allocator_type() )
309 void constructor_impl( I first, I last, std::input_iterator_tag ) // basic
311 while( first != last )
313 insert( end(), null_cloner_type::allocate_clone_from_iterator(first) );
319 void constructor_impl( I first, I last, std::forward_iterator_tag ) // strong
323 clone_back_insert( first, last );
328 // overhead: null-initilization of container pointer (very cheap compared to cloning)
329 // overhead: 1 heap allocation (very cheap compared to cloning)
330 template< class InputIterator >
331 reversible_ptr_container( InputIterator first,
333 const allocator_type& a = allocator_type() ) // basic, strong
336 constructor_impl( first, last,
337 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
339 BOOST_DEDUCED_TYPENAME
341 iterator_category<InputIterator>::type() );
344 template< class Compare >
345 reversible_ptr_container( const Compare& comp,
346 const allocator_type& a )
349 template< class PtrContainer, class Compare >
350 reversible_ptr_container( std::auto_ptr<PtrContainer> clone,
352 : c_( comp, allocator_type() )
358 ~reversible_ptr_container()
363 template< class PtrContainer >
364 void operator=( std::auto_ptr<PtrContainer> clone )
371 allocator_type get_allocator() const
373 return c_.get_allocator();
376 public: // container requirements
378 { return iterator( c_.begin() ); }
379 const_iterator begin() const
380 { return const_iterator( c_.begin() ); }
382 { return iterator( c_.end() ); }
383 const_iterator end() const
384 { return const_iterator( c_.end() ); }
386 reverse_iterator rbegin()
387 { return reverse_iterator( this->end() ); }
388 const_reverse_iterator rbegin() const
389 { return const_reverse_iterator( this->end() ); }
390 reverse_iterator rend()
391 { return reverse_iterator( this->begin() ); }
392 const_reverse_iterator rend() const
393 { return const_reverse_iterator( this->begin() ); }
395 void swap( reversible_ptr_container& r ) // nothrow
400 size_type size() const // nothrow
405 size_type max_size() const // nothrow
407 return c_.max_size();
410 bool empty() const // nothrow
415 public: // optional container requirements
417 bool operator==( const reversible_ptr_container& r ) const // nothrow
419 if( size() != r.size() )
422 return std::equal( begin(), end(), r.begin() );
425 bool operator!=( const reversible_ptr_container& r ) const // nothrow
427 return !(*this == r);
430 bool operator<( const reversible_ptr_container& r ) const // nothrow
432 return std::lexicographical_compare( begin(), end(), r.begin(), r.end() );
435 bool operator<=( const reversible_ptr_container& r ) const // nothrow
440 bool operator>( const reversible_ptr_container& r ) const // nothrow
445 bool operator>=( const reversible_ptr_container& r ) const // nothrow
452 iterator insert( iterator before, Ty_* x )
454 enforce_null_policy( x, "Null pointer in 'insert()'" );
456 auto_type ptr( x ); // nothrow
457 iterator res( c_.insert( before.base(), x ) ); // strong, commit
458 ptr.release(); // nothrow
463 iterator insert( iterator before, std::auto_ptr<U> x )
465 return insert( before, x.release() );
468 iterator erase( iterator x ) // nothrow
470 BOOST_ASSERT( !empty() );
471 BOOST_ASSERT( x != end() );
474 return iterator( c_.erase( x.base() ) );
477 iterator erase( iterator first, iterator last ) // nothrow
479 //BOOST_ASSERT( !empty() );
480 remove( first, last );
481 return iterator( c_.erase( first.base(),
485 template< class Range >
486 iterator erase( const Range& r )
488 return erase( boost::begin(r), boost::end(r) );
497 public: // access interface
499 auto_type release( iterator where )
501 BOOST_ASSERT( where != end() );
503 BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
504 "'release()' on empty container" );
506 auto_type ptr( Config::get_pointer( where ) ); // nothrow
507 c_.erase( where.base() ); // nothrow
508 return boost::ptr_container_detail::move( ptr );
511 auto_type replace( iterator where, Ty_* x ) // strong
513 BOOST_ASSERT( where != end() );
515 enforce_null_policy( x, "Null pointer in 'replace()'" );
519 BOOST_PTR_CONTAINER_THROW_EXCEPTION( empty(), bad_ptr_container_operation,
520 "'replace()' on empty container" );
522 auto_type old( Config::get_pointer( where ) ); // nothrow
524 //#if defined( __GNUC__ ) || defined( __MWERKS__ ) || defined( __COMO__ )
525 const_cast<void*&>(*where.base()) = ptr.release();
527 // *where.base() = ptr.release(); // nothrow, commit
529 return boost::ptr_container_detail::move( old );
533 auto_type replace( iterator where, std::auto_ptr<U> x )
535 return replace( where, x.release() );
538 auto_type replace( size_type idx, Ty_* x ) // strong
540 enforce_null_policy( x, "Null pointer in 'replace()'" );
544 BOOST_PTR_CONTAINER_THROW_EXCEPTION( idx >= size(), bad_index,
545 "'replace()' out of bounds" );
547 auto_type old( static_cast<Ty_*>( c_[idx] ) ); // nothrow
548 c_[idx] = ptr.release(); // nothrow, commit
549 return boost::ptr_container_detail::move( old );
553 auto_type replace( size_type idx, std::auto_ptr<U> x )
555 return replace( idx, x.release() );
564 template< class Archive >
565 void save_helper( Archive& ar ) const
567 const_iterator i = this->begin(), e = this->end();
569 ar & ptr_container_detail::serialize_as_const(
570 static_cast<value_type>( *i.base() ) );
575 template< class Archive >
576 void save( Archive& ar, const unsigned ) const
578 ar & ptr_container_detail::serialize_as_const( this->size() );
579 this->save_helper( ar );
584 template< class Archive >
585 void load_helper( Archive& ar, size_type n )
588 // Called after an appropriate reserve on c.
592 for( size_type i = 0u; i != n; ++i )
595 // Remark: pointers are not tracked,
596 // so we need not call ar.reset_object_address(v, u)
600 this->insert( this->end(), ptr );
606 template< class Archive >
607 void load( Archive& ar, const unsigned )
611 this->load_helper( ar, n );
614 BOOST_SERIALIZATION_SPLIT_MEMBER()
616 }; // 'reversible_ptr_container'
619 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
620 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
621 typename base_type::auto_type \
622 release( typename base_type::iterator i ) \
624 return boost::ptr_container_detail::move(base_type::release(i)); \
627 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
628 using base_type::release;
632 // two-phase lookup of template functions
633 // is buggy on most compilers, so we use a macro instead
635 #define BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type ) \
637 PC( std::auto_ptr<this_type> r ) \
638 : base_type ( r ) { } \
640 void operator=( std::auto_ptr<this_type> r ) \
642 base_type::operator=( r ); \
645 std::auto_ptr<this_type> release() \
647 std::auto_ptr<this_type> ptr( new this_type );\
648 this->swap( *ptr ); \
651 BOOST_PTR_CONTAINER_DEFINE_RELEASE( base_type ) \
653 std::auto_ptr<this_type> clone() const \
655 return std::auto_ptr<this_type>( new this_type( this->begin(), this->end() ) ); \
658 #define BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \
659 typedef BOOST_DEDUCED_TYPENAME base_type::iterator iterator; \
660 typedef BOOST_DEDUCED_TYPENAME base_type::size_type size_type; \
661 typedef BOOST_DEDUCED_TYPENAME base_type::const_reference const_reference; \
662 typedef BOOST_DEDUCED_TYPENAME base_type::allocator_type allocator_type; \
663 PC( const allocator_type& a = allocator_type() ) : base_type(a) {} \
664 template< class InputIterator > \
665 PC( InputIterator first, InputIterator last, \
666 const allocator_type& a = allocator_type() ) : base_type( first, last, a ) {}
670 #define BOOST_PTR_CONTAINER_DEFINE_NON_INHERITED_MEMBERS( PC, base_type, this_type ) \
671 BOOST_PTR_CONTAINER_DEFINE_CONSTRUCTORS( PC, base_type ) \
672 BOOST_PTR_CONTAINER_DEFINE_RELEASE_AND_CLONE( PC, base_type, this_type )
674 } // namespace 'ptr_container_detail'
676 } // namespace 'boost'