📄 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/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/assert.hpp>
#include <boost/config.hpp>
#include <boost/range/result_iterator.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <algorithm>
#include <exception>
#include <memory>
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 {};
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!" );
}
return CloneAllocator::allocate_clone( *x );
}
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_;
protected:
Cont& c_private() { return c_; }
const Cont& c_private() const { return c_; }
public: // typedefs
typedef BOOST_DEDUCED_TYPENAME Config::object_type
object_type;
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_DEDUCED_TYPENAME Config::reverse_iterator
reverse_iterator;
typedef BOOST_DEDUCED_TYPENAME Config::const_reverse_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 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();
}
void insert_clones_and_release( scoped_deleter& sd ) // strong
{
c_.insert( sd.begin(), sd.end() );
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();
}
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 );
}
template< class Range >
BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type
adl_begin( Range& r )
{
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
return begin( r );
#else
using boost::begin;
return begin( r );
#endif
}
template< class Range >
BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type
adl_end( Range& r )
{
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
return end( r );
#else
using boost::end;
return end( r );
#endif
}
static void enforce_null_policy( Ty_* x, const char* msg )
{
if( !allow_null )
{
if( 0 == x )
throw 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;
}
private:
reversible_ptr_container( const reversible_ptr_container& );
void operator=( const reversible_ptr_container& );
public: // foundation! should be protected!
explicit reversible_ptr_container( const allocator_type& a = allocator_type() )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -