📄 reversible_ptr_container.hpp
字号:
//// Boost.Pointer Container//// Copyright Thorsten Ottosen 2003-2005. Use, modification and// distribution is subject to the Boost Software License, Version// 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//// For more information, see http://www.boost.org/libs/ptr_container///#ifndef BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP#define BOOST_PTR_CONTAINER_DETAIL_REVERSIBLE_PTR_CONTAINER_HPP#if defined(_MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif#include <boost/ptr_container/detail/throw_exception.hpp>#include <boost/ptr_container/detail/scoped_deleter.hpp>#include <boost/ptr_container/detail/static_move_ptr.hpp>#include <boost/ptr_container/exception.hpp>#include <boost/ptr_container/clone_allocator.hpp>#include <boost/ptr_container/nullable.hpp>#ifdef BOOST_NO_SFINAE#else#include <boost/range/functions.hpp>#endif#include <boost/config.hpp>#include <boost/iterator/reverse_iterator.hpp>#include <boost/range/iterator.hpp>#include <boost/utility/enable_if.hpp>#include <boost/type_traits/is_pointer.hpp>#include <boost/type_traits/is_integral.hpp>#include <typeinfo>#include <memory>#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) #pragma warning(push) #pragma warning(disable:4127)#endif namespace boost{namespace ptr_container_detail{ template< class CloneAllocator > struct clone_deleter { template< class T > void operator()( const T* p ) const { CloneAllocator::deallocate_clone( p ); } }; template< class T > struct is_pointer_or_integral { BOOST_STATIC_CONSTANT(bool, value = is_pointer<T>::value || is_integral<T>::value ); }; struct is_pointer_or_integral_tag {}; struct is_range_tag {}; struct sequence_tag {}; struct fixed_length_sequence_tag : sequence_tag {}; struct associative_container_tag {}; struct ordered_associative_container_tag : associative_container_tag {}; struct unordered_associative_container_tag : associative_container_tag {}; template < class Config, class CloneAllocator > class reversible_ptr_container { private: BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null ); typedef BOOST_DEDUCED_TYPENAME Config::value_type Ty_; template< bool allow_null_values > struct null_clone_allocator { template< class Iter > static Ty_* allocate_clone_from_iterator( Iter i ) { return allocate_clone( Config::get_const_pointer( i ) ); } static Ty_* allocate_clone( const Ty_* x ) { if( allow_null_values ) { if( x == 0 ) return 0; } else { BOOST_ASSERT( x != 0 && "Cannot insert clone of null!" ); } Ty_* res = CloneAllocator::allocate_clone( *x ); BOOST_ASSERT( typeid(*res) == typeid(*x) && "CloneAllocator::allocate_clone() does not clone the " "object properly. Check that new_clone() is implemented" " correctly" ); return res; } static void deallocate_clone( const Ty_* x ) { if( allow_null_values ) { if( x == 0 ) return; } CloneAllocator::deallocate_clone( x ); } }; typedef BOOST_DEDUCED_TYPENAME Config::void_container_type Cont;#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) typedef null_clone_allocator<reversible_ptr_container::allow_null> null_cloner_type;#else typedef null_clone_allocator<allow_null> null_cloner_type;#endif typedef clone_deleter<null_cloner_type> Deleter; Cont c_; public: Cont& base() { return c_; } protected: // having this public could break encapsulation const Cont& base() const { return c_; } public: // typedefs typedef Ty_* value_type; typedef Ty_* pointer; typedef Ty_& reference; typedef const Ty_& const_reference; typedef BOOST_DEDUCED_TYPENAME Config::iterator iterator; typedef BOOST_DEDUCED_TYPENAME Config::const_iterator const_iterator; typedef boost::reverse_iterator< iterator > reverse_iterator; typedef boost::reverse_iterator< const_iterator > const_reverse_iterator; typedef BOOST_DEDUCED_TYPENAME Cont::difference_type difference_type; typedef BOOST_DEDUCED_TYPENAME Cont::size_type size_type; typedef BOOST_DEDUCED_TYPENAME Config::allocator_type allocator_type; typedef CloneAllocator clone_allocator_type; typedef ptr_container_detail::static_move_ptr<Ty_,Deleter> auto_type; protected: typedef ptr_container_detail::scoped_deleter<Ty_,null_cloner_type> scoped_deleter; typedef BOOST_DEDUCED_TYPENAME Cont::iterator ptr_iterator; typedef BOOST_DEDUCED_TYPENAME Cont::const_iterator ptr_const_iterator; private: template< class InputIterator > void copy( InputIterator first, InputIterator last ) { std::copy( first, last, begin() ); } void copy( const reversible_ptr_container& r ) { copy( r.begin(), r.end() ); } void copy_clones_and_release( scoped_deleter& sd ) // nothrow { BOOST_ASSERT( size_type( std::distance( sd.begin(), sd.end() ) ) == c_.size() ); std::copy( sd.begin(), sd.end(), c_.begin() ); sd.release(); } template< class ForwardIterator > void clone_assign( ForwardIterator first, ForwardIterator last ) // strong { BOOST_ASSERT( first != last ); scoped_deleter sd( first, last ); // strong copy_clones_and_release( sd ); // nothrow } template< class ForwardIterator > void clone_back_insert( ForwardIterator first, ForwardIterator last ) { BOOST_ASSERT( first != last ); scoped_deleter sd( first, last ); insert_clones_and_release( sd, end() ); } void remove_all() { remove( begin(), end() ); } protected: void insert_clones_and_release( scoped_deleter& sd, iterator where ) // strong { // // 'c_.insert' always provides the strong guarantee for T* elements // since a copy constructor of a pointer cannot throw // c_.insert( where.base(), sd.begin(), sd.end() ); sd.release(); } void insert_clones_and_release( scoped_deleter& sd ) // strong { c_.insert( sd.begin(), sd.end() ); sd.release(); } template< class I > void remove( I i ) { null_policy_deallocate_clone( Config::get_const_pointer(i) ); } template< class I > void remove( I first, I last ) { for( ; first != last; ++first ) remove( first ); } static void enforce_null_policy( const Ty_* x, const char* msg ) { if( !allow_null ) { BOOST_PTR_CONTAINER_THROW_EXCEPTION( 0 == x && "null not allowed", bad_pointer, msg ); } } static Ty_* null_policy_allocate_clone( const Ty_* x ) { return null_cloner_type::allocate_clone( x ); } static void null_policy_deallocate_clone( const Ty_* x ) { null_cloner_type::deallocate_clone( x ); } private: template< class ForwardIterator > ForwardIterator advance( ForwardIterator begin, size_type n ) { ForwardIterator iter = begin; std::advance( iter, n ); return iter; } template< class I > void constructor_impl( I first, I last, std::input_iterator_tag ) // basic { while( first != last ) { insert( end(), null_cloner_type::allocate_clone_from_iterator(first) ); ++first; } } template< class I > void constructor_impl( I first, I last, std::forward_iterator_tag ) // strong { if( first == last ) return; clone_back_insert( first, last ); } template< class I > void associative_constructor_impl( I first, I last ) // strong { if( first == last ) return; scoped_deleter sd( first, last ); insert_clones_and_release( sd ); } public: // foundation! should be protected! reversible_ptr_container() { } template< class SizeType > reversible_ptr_container( SizeType n, unordered_associative_container_tag ) : c_( n ) { } template< class SizeType > reversible_ptr_container( SizeType n, fixed_length_sequence_tag ) : c_( n ) { } template< class SizeType > reversible_ptr_container( SizeType n, const allocator_type& a, fixed_length_sequence_tag ) : c_( n, a ) { } explicit reversible_ptr_container( const allocator_type& a ) : c_( a ) { } template< class PtrContainer > explicit reversible_ptr_container( std::auto_ptr<PtrContainer> clone ) { swap( *clone ); } reversible_ptr_container( const reversible_ptr_container& r ) { constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() ); } template< class C, class V > reversible_ptr_container( const reversible_ptr_container<C,V>& r ) { constructor_impl( r.begin(), r.end(), std::forward_iterator_tag() ); } template< class PtrContainer > reversible_ptr_container& operator=( std::auto_ptr<PtrContainer> clone ) // nothrow { swap( *clone ); return *this; } reversible_ptr_container& operator=( reversible_ptr_container r ) // strong { swap( r ); return *this; } // overhead: null-initilization of container pointer (very cheap compared to cloning) // overhead: 1 heap allocation (very cheap compared to cloning) template< class InputIterator > reversible_ptr_container( InputIterator first, InputIterator last, const allocator_type& a = allocator_type() ) // basic, strong : c_( a ) { constructor_impl( first, last, #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -