Updated Boost libraries to version 1.49, and recompiled them with NDK r8d
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
@@ -42,7 +42,7 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
template < unsigned int Version
|
||||
, class T
|
||||
@@ -71,7 +71,7 @@ class adaptive_pool_base
|
||||
template <int dummy>
|
||||
struct node_pool
|
||||
{
|
||||
typedef detail::shared_adaptive_node_pool
|
||||
typedef ipcdetail::shared_adaptive_node_pool
|
||||
< SegmentManager, sizeof_value<T>::value, NodesPerBlock, MaxFreeBlocks, OverheadPercent> type;
|
||||
|
||||
static type *get(void *p)
|
||||
@@ -83,20 +83,22 @@ class adaptive_pool_base
|
||||
|
||||
public:
|
||||
//-------
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const T>::type const_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
typedef boost::interprocess::version_type<adaptive_pool_base, Version> version;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
|
||||
//!Obtains adaptive_pool_base from
|
||||
@@ -121,14 +123,14 @@ class adaptive_pool_base
|
||||
//!pool. Increments the reference count of the associated node pool.
|
||||
//!Can throw boost::interprocess::bad_alloc
|
||||
adaptive_pool_base(segment_manager *segment_mngr)
|
||||
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
|
||||
: mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
|
||||
|
||||
//!Copy constructor from other adaptive_pool_base. Increments the reference
|
||||
//!count of the associated node pool. Never throws
|
||||
adaptive_pool_base(const adaptive_pool_base &other)
|
||||
: mp_node_pool(other.get_node_pool())
|
||||
{
|
||||
node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
|
||||
node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
|
||||
}
|
||||
|
||||
//!Assignment from other adaptive_pool_base
|
||||
@@ -145,27 +147,27 @@ class adaptive_pool_base
|
||||
template<class T2>
|
||||
adaptive_pool_base
|
||||
(const adaptive_pool_base<Version, T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
|
||||
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
|
||||
: mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
|
||||
|
||||
//!Destructor, removes node_pool_t from memory
|
||||
//!if its reference count reaches to zero. Never throws
|
||||
~adaptive_pool_base()
|
||||
{ detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
|
||||
{ ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))); }
|
||||
|
||||
//!Returns a pointer to the node pool.
|
||||
//!Never throws
|
||||
void* get_node_pool() const
|
||||
{ return detail::get_pointer(mp_node_pool); }
|
||||
{ return ipcdetail::to_raw_pointer(mp_node_pool); }
|
||||
|
||||
//!Returns the segment manager.
|
||||
//!Never throws
|
||||
segment_manager* get_segment_manager()const
|
||||
{ return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
|
||||
{ return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); }
|
||||
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
||||
//!different memory segment, the result is undefined.
|
||||
friend void swap(self_t &alloc1, self_t &alloc2)
|
||||
{ detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
|
||||
{ ipcdetail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
@@ -204,7 +206,7 @@ class adaptive_pool_v1
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef detail::adaptive_pool_base
|
||||
typedef ipcdetail::adaptive_pool_base
|
||||
< 1, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
|
||||
|
||||
template<class T2>
|
||||
@@ -224,7 +226,7 @@ class adaptive_pool_v1
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -250,7 +252,7 @@ template < class T
|
||||
>
|
||||
class adaptive_pool
|
||||
/// @cond
|
||||
: public detail::adaptive_pool_base
|
||||
: public ipcdetail::adaptive_pool_base
|
||||
< 2
|
||||
, T
|
||||
, SegmentManager
|
||||
@@ -262,7 +264,7 @@ class adaptive_pool
|
||||
{
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
typedef detail::adaptive_pool_base
|
||||
typedef ipcdetail::adaptive_pool_base
|
||||
< 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
|
||||
public:
|
||||
typedef boost::interprocess::version_type<adaptive_pool, 2> version;
|
||||
@@ -290,12 +292,12 @@ class adaptive_pool
|
||||
typedef implementation_defined::pointer pointer;
|
||||
typedef implementation_defined::const_pointer const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
//!Obtains adaptive_pool from
|
||||
//!adaptive_pool
|
||||
@@ -372,7 +374,7 @@ class adaptive_pool
|
||||
//!Returns address of non mutable object.
|
||||
//!Never throws
|
||||
const_pointer address(const_reference value) const;
|
||||
|
||||
/*
|
||||
//!Copy construct an object.
|
||||
//!Throws if T's copy constructor throws
|
||||
void construct(const pointer &ptr, const_reference v);
|
||||
@@ -380,7 +382,7 @@ class adaptive_pool
|
||||
//!Destroys object. Throws if object's
|
||||
//!destructor throws
|
||||
void destroy(const pointer &ptr);
|
||||
|
||||
*/
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold. This size only works for memory allocated with
|
||||
//!allocate, allocation_command and allocate_many.
|
||||
@@ -398,7 +400,7 @@ class adaptive_pool
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements);
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
||||
//!contiguous block
|
||||
@@ -424,7 +426,7 @@ class adaptive_pool
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements);
|
||||
multiallocation_chain allocate_individual(size_type num_elements);
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,11 +18,11 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/containers/allocation_type.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/containers/version_type.hpp>
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
@@ -66,13 +67,14 @@ class allocator
|
||||
typedef typename segment_manager::void_pointer aux_pointer_t;
|
||||
|
||||
//Typedef to const void pointer
|
||||
typedef typename
|
||||
boost::pointer_to_other
|
||||
<aux_pointer_t, const void>::type cvoid_ptr;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<aux_pointer_t>::template
|
||||
rebind_pointer<const void>::type cvoid_ptr;
|
||||
|
||||
//Pointer to the allocator
|
||||
typedef typename boost::pointer_to_other
|
||||
<cvoid_ptr, segment_manager>::type alloc_ptr_t;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<cvoid_ptr>::template
|
||||
rebind_pointer<segment_manager>::type alloc_ptr_t;
|
||||
|
||||
//Not assignable from related allocator
|
||||
template<class T2, class SegmentManager2>
|
||||
@@ -87,23 +89,25 @@ class allocator
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef typename boost::pointer_to_other
|
||||
<cvoid_ptr, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<pointer, const T>::type const_pointer;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<cvoid_ptr>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
typedef boost::interprocess::version_type<allocator, 2> version;
|
||||
|
||||
/// @cond
|
||||
|
||||
//Experimental. Don't use.
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
/// @endcond
|
||||
|
||||
@@ -118,7 +122,7 @@ class allocator
|
||||
//!Returns the segment manager.
|
||||
//!Never throws
|
||||
segment_manager* get_segment_manager()const
|
||||
{ return detail::get_pointer(mp_mngr); }
|
||||
{ return ipcdetail::to_raw_pointer(mp_mngr); }
|
||||
|
||||
//!Constructor from the segment manager.
|
||||
//!Never throws
|
||||
@@ -149,7 +153,7 @@ class allocator
|
||||
//!Deallocates memory previously allocated.
|
||||
//!Never throws
|
||||
void deallocate(const pointer &ptr, size_type)
|
||||
{ mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
|
||||
{ mp_mngr->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); }
|
||||
|
||||
//!Returns the number of elements that could be allocated.
|
||||
//!Never throws
|
||||
@@ -159,14 +163,14 @@ class allocator
|
||||
//!Swap segment manager. Does not throw. If each allocator is placed in
|
||||
//!different memory segments, the result is undefined.
|
||||
friend void swap(self_t &alloc1, self_t &alloc2)
|
||||
{ detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
|
||||
{ ipcdetail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
|
||||
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
||||
//!pointed by p can hold. This size only works for memory allocated with
|
||||
//!allocate, allocation_command and allocate_many.
|
||||
size_type size(const pointer &p) const
|
||||
{
|
||||
return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T);
|
||||
return (size_type)mp_mngr->size(ipcdetail::to_raw_pointer(p))/sizeof(T);
|
||||
}
|
||||
|
||||
std::pair<pointer, bool>
|
||||
@@ -176,7 +180,7 @@ class allocator
|
||||
size_type &received_size, const pointer &reuse = 0)
|
||||
{
|
||||
return mp_mngr->allocation_command
|
||||
(command, limit_size, preferred_size, received_size, detail::get_pointer(reuse));
|
||||
(command, limit_size, preferred_size, received_size, ipcdetail::to_raw_pointer(reuse));
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size in a contiguous block
|
||||
@@ -186,7 +190,7 @@ class allocator
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many
|
||||
(size_type elem_size, std::size_t num_elements)
|
||||
(size_type elem_size, size_type num_elements)
|
||||
{
|
||||
return multiallocation_chain(mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
|
||||
}
|
||||
@@ -224,7 +228,7 @@ class allocator
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual
|
||||
(std::size_t num_elements)
|
||||
(size_type num_elements)
|
||||
{ return this->allocate_many(1, num_elements); }
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
@@ -240,7 +244,7 @@ class allocator
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
void deallocate_individual(multiallocation_chain chain)
|
||||
{ return this->deallocate_many(boost::interprocess::move(chain)); }
|
||||
{ return this->deallocate_many(boost::move(chain)); }
|
||||
|
||||
//!Returns address of mutable object.
|
||||
//!Never throws
|
||||
@@ -252,20 +256,18 @@ class allocator
|
||||
const_pointer address(const_reference value) const
|
||||
{ return const_pointer(boost::addressof(value)); }
|
||||
|
||||
//!Copy construct an object
|
||||
//!Throws if T's copy constructor throws
|
||||
void construct(const pointer &ptr, const_reference v)
|
||||
{ new((void*)detail::get_pointer(ptr)) value_type(v); }
|
||||
|
||||
//!Default construct an object.
|
||||
//!Throws if T's default constructor throws
|
||||
void construct(const pointer &ptr)
|
||||
{ new((void*)detail::get_pointer(ptr)) value_type; }
|
||||
//!Constructs an object
|
||||
//!Throws if T's constructor throws
|
||||
//!For backwards compatibility with libraries using C++03 allocators
|
||||
template<class P>
|
||||
void construct(const pointer &ptr, BOOST_FWD_REF(P) p)
|
||||
{ ::new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(::boost::forward<P>(p)); }
|
||||
|
||||
//!Destroys object. Throws if object's
|
||||
//!destructor throws
|
||||
void destroy(const pointer &ptr)
|
||||
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
|
||||
|
||||
};
|
||||
|
||||
//!Equality test for same type
|
||||
@@ -293,7 +295,7 @@ template<class T, class SegmentManager>
|
||||
struct has_trivial_destructor
|
||||
<boost::interprocess::allocator <T, SegmentManager> >
|
||||
{
|
||||
enum { value = true };
|
||||
static const bool value = true;
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -35,7 +35,7 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template < class T
|
||||
, class SegmentManager
|
||||
@@ -44,9 +44,9 @@ template < class T
|
||||
, unsigned char OverheadPercent = 5
|
||||
>
|
||||
class cached_adaptive_pool_v1
|
||||
: public detail::cached_allocator_impl
|
||||
: public ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_adaptive_node_pool
|
||||
, ipcdetail::shared_adaptive_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -56,9 +56,9 @@ class cached_adaptive_pool_v1
|
||||
, 1>
|
||||
{
|
||||
public:
|
||||
typedef detail::cached_allocator_impl
|
||||
typedef ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_adaptive_node_pool
|
||||
, ipcdetail::shared_adaptive_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -74,8 +74,10 @@ class cached_adaptive_pool_v1
|
||||
<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
|
||||
};
|
||||
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
cached_adaptive_pool_v1(SegmentManager *segment_mngr,
|
||||
std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
|
||||
size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
|
||||
: base_t(segment_mngr, max_cached_nodes)
|
||||
{}
|
||||
|
||||
@@ -87,7 +89,7 @@ class cached_adaptive_pool_v1
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -116,9 +118,9 @@ template < class T
|
||||
>
|
||||
class cached_adaptive_pool
|
||||
/// @cond
|
||||
: public detail::cached_allocator_impl
|
||||
: public ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_adaptive_node_pool
|
||||
, ipcdetail::shared_adaptive_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -131,9 +133,9 @@ class cached_adaptive_pool
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
public:
|
||||
typedef detail::cached_allocator_impl
|
||||
typedef ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_adaptive_node_pool
|
||||
, ipcdetail::shared_adaptive_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -170,12 +172,12 @@ class cached_adaptive_pool
|
||||
typedef implementation_defined::pointer pointer;
|
||||
typedef implementation_defined::const_pointer const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
//!Obtains cached_adaptive_pool from
|
||||
//!cached_adaptive_pool
|
||||
@@ -278,7 +280,7 @@ class cached_adaptive_pool
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements);
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
||||
//!contiguous block
|
||||
@@ -304,7 +306,7 @@ class cached_adaptive_pool
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements);
|
||||
multiallocation_chain allocate_individual(size_type num_elements);
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
@@ -320,11 +322,11 @@ class cached_adaptive_pool
|
||||
void deallocate_individual(multiallocation_chain chain);
|
||||
//!Sets the new max cached nodes value. This can provoke deallocations
|
||||
//!if "newmax" is less than current cached nodes. Never throws
|
||||
void set_max_cached_nodes(std::size_t newmax);
|
||||
void set_max_cached_nodes(size_type newmax);
|
||||
|
||||
//!Returns the max cached nodes parameter.
|
||||
//!Never throws
|
||||
std::size_t get_max_cached_nodes() const;
|
||||
size_type get_max_cached_nodes() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -36,16 +36,16 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template < class T
|
||||
, class SegmentManager
|
||||
, std::size_t NodesPerBlock = 64
|
||||
>
|
||||
class cached_node_allocator_v1
|
||||
: public detail::cached_allocator_impl
|
||||
: public ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_node_pool
|
||||
, ipcdetail::shared_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -53,9 +53,9 @@ class cached_node_allocator_v1
|
||||
, 1>
|
||||
{
|
||||
public:
|
||||
typedef detail::cached_allocator_impl
|
||||
typedef ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_node_pool
|
||||
, ipcdetail::shared_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -69,8 +69,10 @@ class cached_node_allocator_v1
|
||||
<T2, SegmentManager, NodesPerBlock> other;
|
||||
};
|
||||
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
cached_node_allocator_v1(SegmentManager *segment_mngr,
|
||||
std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
|
||||
size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
|
||||
: base_t(segment_mngr, max_cached_nodes)
|
||||
{}
|
||||
|
||||
@@ -82,7 +84,7 @@ class cached_node_allocator_v1
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -92,9 +94,9 @@ template < class T
|
||||
>
|
||||
class cached_node_allocator
|
||||
/// @cond
|
||||
: public detail::cached_allocator_impl
|
||||
: public ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_node_pool
|
||||
, ipcdetail::shared_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -105,9 +107,9 @@ class cached_node_allocator
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
public:
|
||||
typedef detail::cached_allocator_impl
|
||||
typedef ipcdetail::cached_allocator_impl
|
||||
< T
|
||||
, detail::shared_node_pool
|
||||
, ipcdetail::shared_node_pool
|
||||
< SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -116,6 +118,7 @@ class cached_node_allocator
|
||||
|
||||
public:
|
||||
typedef boost::interprocess::version_type<cached_node_allocator, 2> version;
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
template<class T2>
|
||||
struct rebind
|
||||
@@ -124,7 +127,7 @@ class cached_node_allocator
|
||||
};
|
||||
|
||||
cached_node_allocator(SegmentManager *segment_mngr,
|
||||
std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
|
||||
size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
|
||||
: base_t(segment_mngr, max_cached_nodes)
|
||||
{}
|
||||
|
||||
@@ -141,12 +144,12 @@ class cached_node_allocator
|
||||
typedef implementation_defined::pointer pointer;
|
||||
typedef implementation_defined::const_pointer const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename SegmentManager::size_type size_type;
|
||||
typedef typename SegmentManager::difference_type difference_type;
|
||||
|
||||
//!Obtains cached_node_allocator from
|
||||
//!cached_node_allocator
|
||||
@@ -249,7 +252,7 @@ class cached_node_allocator
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements);
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
||||
//!contiguous block
|
||||
@@ -275,7 +278,7 @@ class cached_node_allocator
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements);
|
||||
multiallocation_chain allocate_individual(size_type num_elements);
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
@@ -291,11 +294,11 @@ class cached_node_allocator
|
||||
void deallocate_individual(multiallocation_chain it);
|
||||
//!Sets the new max cached nodes value. This can provoke deallocations
|
||||
//!if "newmax" is less than current cached nodes. Never throws
|
||||
void set_max_cached_nodes(std::size_t newmax);
|
||||
void set_max_cached_nodes(size_type newmax);
|
||||
|
||||
//!Returns the max cached nodes parameter.
|
||||
//!Never throws
|
||||
std::size_t get_max_cached_nodes() const;
|
||||
size_type get_max_cached_nodes() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/math_functions.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
@@ -28,7 +27,7 @@
|
||||
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp>
|
||||
#include <boost/container/detail/adaptive_node_pool_impl.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
//!\file
|
||||
@@ -36,7 +35,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template< class SegmentManager
|
||||
, std::size_t NodeSize
|
||||
@@ -45,10 +44,10 @@ template< class SegmentManager
|
||||
, unsigned char OverheadPercent
|
||||
>
|
||||
class private_adaptive_node_pool
|
||||
: public boost::container::containers_detail::private_adaptive_node_pool_impl
|
||||
: public boost::container::container_detail::private_adaptive_node_pool_impl
|
||||
<typename SegmentManager::segment_manager_base_type>
|
||||
{
|
||||
typedef boost::container::containers_detail::private_adaptive_node_pool_impl
|
||||
typedef boost::container::container_detail::private_adaptive_node_pool_impl
|
||||
<typename SegmentManager::segment_manager_base_type> base_t;
|
||||
//Non-copyable
|
||||
private_adaptive_node_pool();
|
||||
@@ -56,12 +55,13 @@ class private_adaptive_node_pool
|
||||
private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
|
||||
|
||||
public:
|
||||
typedef SegmentManager segment_manager;
|
||||
typedef SegmentManager segment_manager;
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
static const size_type nodes_per_block = NodesPerBlock;
|
||||
|
||||
//Deprecated, use node_per_block
|
||||
static const std::size_t nodes_per_chunk = NodesPerBlock;
|
||||
static const size_type nodes_per_chunk = NodesPerBlock;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_adaptive_node_pool(segment_manager *segment_mngr)
|
||||
@@ -84,12 +84,12 @@ template< class SegmentManager
|
||||
, unsigned char OverheadPercent
|
||||
>
|
||||
class shared_adaptive_node_pool
|
||||
: public detail::shared_pool_impl
|
||||
: public ipcdetail::shared_pool_impl
|
||||
< private_adaptive_node_pool
|
||||
<SegmentManager, NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
|
||||
>
|
||||
{
|
||||
typedef detail::shared_pool_impl
|
||||
typedef ipcdetail::shared_pool_impl
|
||||
< private_adaptive_node_pool
|
||||
<SegmentManager, NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
|
||||
> base_t;
|
||||
@@ -99,7 +99,7 @@ class shared_adaptive_node_pool
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -14,25 +14,24 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp> //get_pointer
|
||||
#include <utility> //std::pair
|
||||
#include <boost/interprocess/detail/utilities.hpp> //to_raw_pointer
|
||||
#include <boost/utility/addressof.hpp> //boost::addressof
|
||||
#include <boost/assert.hpp> //BOOST_ASSERT
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp> //bad_alloc
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp> //scoped_lock
|
||||
#include <boost/interprocess/containers/allocation_type.hpp> //boost::interprocess::allocation_type
|
||||
#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
|
||||
#include <boost/interprocess/detail/segment_manager_helper.hpp>
|
||||
#include <algorithm> //std::swap
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <algorithm> //std::swap
|
||||
#include <utility> //std::pair
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
@@ -67,7 +66,7 @@ struct sizeof_value<const volatile void>
|
||||
static const std::size_t value = sizeof(void*);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
//!Object function that creates the node allocator if it is not created and
|
||||
//!increments reference count if it is already created
|
||||
@@ -99,7 +98,7 @@ struct get_or_create_node_pool_func
|
||||
template<class NodePool>
|
||||
inline NodePool *get_or_create_node_pool(typename NodePool::segment_manager *mgnr)
|
||||
{
|
||||
detail::get_or_create_node_pool_func<NodePool> func(mgnr);
|
||||
ipcdetail::get_or_create_node_pool_func<NodePool> func(mgnr);
|
||||
mgnr->atomic_func(func);
|
||||
return func.mp_node_pool;
|
||||
}
|
||||
@@ -147,17 +146,19 @@ class cache_impl
|
||||
{
|
||||
typedef typename NodePool::segment_manager::
|
||||
void_pointer void_pointer;
|
||||
typedef typename pointer_to_other
|
||||
<void_pointer, NodePool>::type node_pool_ptr;
|
||||
typedef typename NodePool::multiallocation_chain multiallocation_chain;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<NodePool>::type node_pool_ptr;
|
||||
typedef typename NodePool::multiallocation_chain multiallocation_chain;
|
||||
typedef typename NodePool::segment_manager::size_type size_type;
|
||||
node_pool_ptr mp_node_pool;
|
||||
multiallocation_chain m_cached_nodes;
|
||||
std::size_t m_max_cached_nodes;
|
||||
size_type m_max_cached_nodes;
|
||||
|
||||
public:
|
||||
typedef typename NodePool::segment_manager segment_manager;
|
||||
|
||||
cache_impl(segment_manager *segment_mngr, std::size_t max_cached_nodes)
|
||||
cache_impl(segment_manager *segment_mngr, size_type max_cached_nodes)
|
||||
: mp_node_pool(get_or_create_node_pool<NodePool>(segment_mngr))
|
||||
, m_max_cached_nodes(max_cached_nodes)
|
||||
{}
|
||||
@@ -172,16 +173,16 @@ class cache_impl
|
||||
~cache_impl()
|
||||
{
|
||||
this->deallocate_all_cached_nodes();
|
||||
detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool));
|
||||
ipcdetail::destroy_node_pool_if_last_link(ipcdetail::to_raw_pointer(mp_node_pool));
|
||||
}
|
||||
|
||||
NodePool *get_node_pool() const
|
||||
{ return detail::get_pointer(mp_node_pool); }
|
||||
{ return ipcdetail::to_raw_pointer(mp_node_pool); }
|
||||
|
||||
segment_manager *get_segment_manager() const
|
||||
{ return mp_node_pool->get_segment_manager(); }
|
||||
|
||||
std::size_t get_max_cached_nodes() const
|
||||
size_type get_max_cached_nodes() const
|
||||
{ return m_max_cached_nodes; }
|
||||
|
||||
void *cached_allocation()
|
||||
@@ -190,19 +191,19 @@ class cache_impl
|
||||
if(m_cached_nodes.empty()){
|
||||
m_cached_nodes = mp_node_pool->allocate_nodes(m_max_cached_nodes/2);
|
||||
}
|
||||
void *ret = detail::get_pointer(m_cached_nodes.front());
|
||||
void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.front());
|
||||
m_cached_nodes.pop_front();
|
||||
return ret;
|
||||
}
|
||||
|
||||
multiallocation_chain cached_allocation(std::size_t n)
|
||||
multiallocation_chain cached_allocation(size_type n)
|
||||
{
|
||||
multiallocation_chain chain;
|
||||
std::size_t count = n, allocated(0);
|
||||
size_type count = n, allocated(0);
|
||||
BOOST_TRY{
|
||||
//If don't have any cached node, we have to get a new list of free nodes from the pool
|
||||
while(!m_cached_nodes.empty() && count--){
|
||||
void *ret = detail::get_pointer(m_cached_nodes.front());
|
||||
void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.front());
|
||||
m_cached_nodes.pop_front();
|
||||
chain.push_back(ret);
|
||||
++allocated;
|
||||
@@ -212,10 +213,10 @@ class cache_impl
|
||||
multiallocation_chain chain2(mp_node_pool->allocate_nodes(n - allocated));
|
||||
chain.splice_after(chain.last(), chain2, chain2.before_begin(), chain2.last(), n - allocated);
|
||||
}
|
||||
return boost::interprocess::move(chain);
|
||||
return boost::move(chain);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
this->cached_deallocation(boost::interprocess::move(chain));
|
||||
this->cached_deallocation(boost::move(chain));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -250,7 +251,7 @@ class cache_impl
|
||||
|
||||
//!Sets the new max cached nodes value. This can provoke deallocations
|
||||
//!if "newmax" is less than current cached nodes. Never throws
|
||||
void set_max_cached_nodes(std::size_t newmax)
|
||||
void set_max_cached_nodes(size_type newmax)
|
||||
{
|
||||
m_max_cached_nodes = newmax;
|
||||
this->priv_deallocate_remaining_nodes();
|
||||
@@ -261,7 +262,7 @@ class cache_impl
|
||||
void deallocate_all_cached_nodes()
|
||||
{
|
||||
if(m_cached_nodes.empty()) return;
|
||||
mp_node_pool->deallocate_nodes(boost::interprocess::move(m_cached_nodes));
|
||||
mp_node_pool->deallocate_nodes(boost::move(m_cached_nodes));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -275,13 +276,13 @@ class cache_impl
|
||||
}
|
||||
|
||||
//!Frees n cached nodes at once. Never throws
|
||||
void priv_deallocate_n_nodes(std::size_t n)
|
||||
void priv_deallocate_n_nodes(size_type n)
|
||||
{
|
||||
//This only occurs if this allocator deallocate memory allocated
|
||||
//with other equal allocator. Since the cache is full, and more
|
||||
//deallocations are probably coming, we'll make some room in cache
|
||||
//in a single, efficient multi node deallocation.
|
||||
std::size_t count(n);
|
||||
size_type count(n);
|
||||
typename multiallocation_chain::iterator it(m_cached_nodes.before_begin());
|
||||
while(count--){
|
||||
++it;
|
||||
@@ -289,15 +290,15 @@ class cache_impl
|
||||
multiallocation_chain chain;
|
||||
chain.splice_after(chain.before_begin(), m_cached_nodes, m_cached_nodes.before_begin(), it, n);
|
||||
//Deallocate all new linked list at once
|
||||
mp_node_pool->deallocate_nodes(boost::interprocess::move(chain));
|
||||
mp_node_pool->deallocate_nodes(boost::move(chain));
|
||||
}
|
||||
|
||||
public:
|
||||
void swap(cache_impl &other)
|
||||
{
|
||||
detail::do_swap(mp_node_pool, other.mp_node_pool);
|
||||
ipcdetail::do_swap(mp_node_pool, other.mp_node_pool);
|
||||
m_cached_nodes.swap(other.m_cached_nodes);
|
||||
detail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
|
||||
ipcdetail::do_swap(m_max_cached_nodes, other.m_max_cached_nodes);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -312,18 +313,20 @@ class array_allocation_impl
|
||||
typedef typename SegmentManager::void_pointer void_pointer;
|
||||
|
||||
public:
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const T>::type const_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef typename SegmentManager::size_type size_type;
|
||||
typedef typename SegmentManager::difference_type difference_type;
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
|
||||
|
||||
@@ -333,7 +336,7 @@ class array_allocation_impl
|
||||
//!allocate, allocation_command and allocate_many.
|
||||
size_type size(const pointer &p) const
|
||||
{
|
||||
return (size_type)this->derived()->get_segment_manager()->size(detail::get_pointer(p))/sizeof(T);
|
||||
return (size_type)this->derived()->get_segment_manager()->size(ipcdetail::to_raw_pointer(p))/sizeof(T);
|
||||
}
|
||||
|
||||
std::pair<pointer, bool>
|
||||
@@ -343,7 +346,7 @@ class array_allocation_impl
|
||||
size_type &received_size, const pointer &reuse = 0)
|
||||
{
|
||||
return this->derived()->get_segment_manager()->allocation_command
|
||||
(command, limit_size, preferred_size, received_size, detail::get_pointer(reuse));
|
||||
(command, limit_size, preferred_size, received_size, ipcdetail::to_raw_pointer(reuse));
|
||||
}
|
||||
|
||||
//!Allocates many elements of size elem_size in a contiguous block
|
||||
@@ -352,7 +355,7 @@ class array_allocation_impl
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements)
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements)
|
||||
{
|
||||
return this->derived()->get_segment_manager()->allocate_many(sizeof(T)*elem_size, num_elements);
|
||||
}
|
||||
@@ -372,7 +375,7 @@ class array_allocation_impl
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
void deallocate_many(multiallocation_chain chain)
|
||||
{ return this->derived()->get_segment_manager()->deallocate_many(boost::interprocess::move(chain)); }
|
||||
{ return this->derived()->get_segment_manager()->deallocate_many(boost::move(chain)); }
|
||||
|
||||
//!Returns the number of elements that could be
|
||||
//!allocated. Never throws
|
||||
@@ -389,15 +392,12 @@ class array_allocation_impl
|
||||
const_pointer address(const_reference value) const
|
||||
{ return const_pointer(boost::addressof(value)); }
|
||||
|
||||
//!Default construct an object.
|
||||
//!Throws if T's default constructor throws
|
||||
void construct(const pointer &ptr)
|
||||
{ new((void*)detail::get_pointer(ptr)) value_type; }
|
||||
|
||||
//!Copy construct an object
|
||||
//!Throws if T's copy constructor throws
|
||||
void construct(const pointer &ptr, const_reference v)
|
||||
{ new((void*)detail::get_pointer(ptr)) value_type(v); }
|
||||
//!Constructs an object
|
||||
//!Throws if T's constructor throws
|
||||
//!For backwards compatibility with libraries using C++03 allocators
|
||||
template<class P>
|
||||
void construct(const pointer &ptr, BOOST_FWD_REF(P) p)
|
||||
{ ::new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(::boost::forward<P>(p)); }
|
||||
|
||||
//!Destroys object. Throws if object's
|
||||
//!destructor throws
|
||||
@@ -419,22 +419,25 @@ class node_pool_allocation_impl
|
||||
{ return static_cast<Derived*>(this); }
|
||||
|
||||
typedef typename SegmentManager::void_pointer void_pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const void>::type cvoid_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const void>::type cvoid_pointer;
|
||||
|
||||
public:
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const T>::type const_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef typename SegmentManager::size_type size_type;
|
||||
typedef typename SegmentManager::difference_type difference_type;
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
|
||||
|
||||
@@ -471,9 +474,9 @@ class node_pool_allocation_impl
|
||||
typedef typename node_pool<0>::type node_pool_t;
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
|
||||
if(Version == 1 && count == 1)
|
||||
pool->deallocate_node(detail::get_pointer(ptr));
|
||||
pool->deallocate_node(ipcdetail::to_raw_pointer(ptr));
|
||||
else
|
||||
pool->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
|
||||
pool->get_segment_manager()->deallocate((void*)ipcdetail::to_raw_pointer(ptr));
|
||||
}
|
||||
|
||||
//!Allocates just one object. Memory allocated with this function
|
||||
@@ -492,7 +495,7 @@ class node_pool_allocation_impl
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements)
|
||||
multiallocation_chain allocate_individual(size_type num_elements)
|
||||
{
|
||||
typedef typename node_pool<0>::type node_pool_t;
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
|
||||
@@ -506,7 +509,7 @@ class node_pool_allocation_impl
|
||||
{
|
||||
typedef typename node_pool<0>::type node_pool_t;
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
|
||||
pool->deallocate_node(detail::get_pointer(p));
|
||||
pool->deallocate_node(ipcdetail::to_raw_pointer(p));
|
||||
}
|
||||
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
||||
@@ -547,17 +550,18 @@ class cached_allocator_impl
|
||||
typedef NodePool node_pool_t;
|
||||
typedef typename NodePool::segment_manager segment_manager;
|
||||
typedef typename segment_manager::void_pointer void_pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const void>::type cvoid_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const void>::type cvoid_pointer;
|
||||
typedef typename base_t::pointer pointer;
|
||||
typedef typename base_t::size_type size_type;
|
||||
typedef typename base_t::multiallocation_chain multiallocation_chain;
|
||||
typedef typename base_t::value_type value_type;
|
||||
|
||||
public:
|
||||
enum { DEFAULT_MAX_CACHED_NODES = 64 };
|
||||
static const std::size_t DEFAULT_MAX_CACHED_NODES = 64;
|
||||
|
||||
cached_allocator_impl(segment_manager *segment_mngr, std::size_t max_cached_nodes)
|
||||
cached_allocator_impl(segment_manager *segment_mngr, size_type max_cached_nodes)
|
||||
: m_cache(segment_mngr, max_cached_nodes)
|
||||
{}
|
||||
|
||||
@@ -587,12 +591,12 @@ class cached_allocator_impl
|
||||
|
||||
//!Sets the new max cached nodes value. This can provoke deallocations
|
||||
//!if "newmax" is less than current cached nodes. Never throws
|
||||
void set_max_cached_nodes(std::size_t newmax)
|
||||
void set_max_cached_nodes(size_type newmax)
|
||||
{ m_cache.set_max_cached_nodes(newmax); }
|
||||
|
||||
//!Returns the max cached nodes parameter.
|
||||
//!Never throws
|
||||
std::size_t get_max_cached_nodes() const
|
||||
size_type get_max_cached_nodes() const
|
||||
{ return m_cache.get_max_cached_nodes(); }
|
||||
|
||||
//!Allocate memory for an array of count elements.
|
||||
@@ -617,10 +621,10 @@ class cached_allocator_impl
|
||||
{
|
||||
(void)count;
|
||||
if(Version == 1 && count == 1){
|
||||
m_cache.cached_deallocation(detail::get_pointer(ptr));
|
||||
m_cache.cached_deallocation(ipcdetail::to_raw_pointer(ptr));
|
||||
}
|
||||
else{
|
||||
this->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
|
||||
this->get_segment_manager()->deallocate((void*)ipcdetail::to_raw_pointer(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,14 +640,14 @@ class cached_allocator_impl
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements)
|
||||
multiallocation_chain allocate_individual(size_type num_elements)
|
||||
{ return multiallocation_chain(this->m_cache.cached_allocation(num_elements)); }
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
//!with other functions different from allocate_one(). Never throws
|
||||
void deallocate_one(const pointer &p)
|
||||
{ this->m_cache.cached_deallocation(detail::get_pointer(p)); }
|
||||
{ this->m_cache.cached_deallocation(ipcdetail::to_raw_pointer(p)); }
|
||||
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
||||
@@ -655,7 +659,7 @@ class cached_allocator_impl
|
||||
{
|
||||
typename node_pool_t::multiallocation_chain mem
|
||||
(chain.extract_multiallocation_chain());
|
||||
m_cache.cached_deallocation(boost::interprocess::move(mem));
|
||||
m_cache.cached_deallocation(boost::move(mem));
|
||||
}
|
||||
|
||||
//!Deallocates all free blocks of the pool
|
||||
@@ -708,6 +712,8 @@ class shared_pool_impl
|
||||
segment_manager segment_manager;
|
||||
typedef typename private_node_allocator_t::
|
||||
multiallocation_chain multiallocation_chain;
|
||||
typedef typename private_node_allocator_t::
|
||||
size_type size_type;
|
||||
|
||||
private:
|
||||
typedef typename segment_manager::mutex_family::mutex_type mutex_type;
|
||||
@@ -742,7 +748,7 @@ class shared_pool_impl
|
||||
/*
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
//!can throw boost::interprocess::bad_alloc
|
||||
void allocate_nodes(multiallocation_chain &nodes, std::size_t n)
|
||||
void allocate_nodes(multiallocation_chain &nodes, size_type n)
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
|
||||
@@ -752,7 +758,7 @@ class shared_pool_impl
|
||||
*/
|
||||
//!Allocates n nodes.
|
||||
//!Can throw boost::interprocess::bad_alloc
|
||||
multiallocation_chain allocate_nodes(const std::size_t n)
|
||||
multiallocation_chain allocate_nodes(const size_type n)
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
|
||||
@@ -761,7 +767,7 @@ class shared_pool_impl
|
||||
}
|
||||
|
||||
//!Deallocates a linked list of nodes ending in null pointer. Never throws
|
||||
void deallocate_nodes(multiallocation_chain &nodes, std::size_t num)
|
||||
void deallocate_nodes(multiallocation_chain &nodes, size_type num)
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
|
||||
@@ -775,7 +781,7 @@ class shared_pool_impl
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
|
||||
//-----------------------
|
||||
private_node_allocator_t::deallocate_nodes(boost::interprocess::move(chain));
|
||||
private_node_allocator_t::deallocate_nodes(boost::move(chain));
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
@@ -799,7 +805,7 @@ class shared_pool_impl
|
||||
}
|
||||
|
||||
//!Increments internal reference count and returns new count. Never throws
|
||||
std::size_t inc_ref_count()
|
||||
size_type inc_ref_count()
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
|
||||
@@ -808,7 +814,7 @@ class shared_pool_impl
|
||||
}
|
||||
|
||||
//!Decrements internal reference count and returns new count. Never throws
|
||||
std::size_t dec_ref_count()
|
||||
size_type dec_ref_count()
|
||||
{
|
||||
//-----------------------
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header);
|
||||
@@ -840,14 +846,14 @@ class shared_pool_impl
|
||||
//!the mutex type to allow EBO when using null_mutex
|
||||
struct header_t : mutex_type
|
||||
{
|
||||
std::size_t m_usecount; //Number of attached allocators
|
||||
size_type m_usecount; //Number of attached allocators
|
||||
|
||||
header_t()
|
||||
: m_usecount(0) {}
|
||||
} m_header;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -20,11 +20,10 @@
|
||||
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/math/common_factor_ct.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/node_pool_impl.hpp>
|
||||
#include <boost/container/detail/node_pool_impl.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
@@ -33,7 +32,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
|
||||
|
||||
@@ -44,10 +43,10 @@ namespace detail {
|
||||
template< class SegmentManager, std::size_t NodeSize, std::size_t NodesPerBlock >
|
||||
class private_node_pool
|
||||
//Inherit from the implementation to avoid template bloat
|
||||
: public boost::container::containers_detail::
|
||||
: public boost::container::container_detail::
|
||||
private_node_pool_impl<typename SegmentManager::segment_manager_base_type>
|
||||
{
|
||||
typedef boost::container::containers_detail::private_node_pool_impl
|
||||
typedef boost::container::container_detail::private_node_pool_impl
|
||||
<typename SegmentManager::segment_manager_base_type> base_t;
|
||||
//Non-copyable
|
||||
private_node_pool();
|
||||
@@ -55,11 +54,12 @@ class private_node_pool
|
||||
private_node_pool &operator=(const private_node_pool &);
|
||||
|
||||
public:
|
||||
typedef SegmentManager segment_manager;
|
||||
typedef SegmentManager segment_manager;
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
static const std::size_t nodes_per_block = NodesPerBlock;
|
||||
static const size_type nodes_per_block = NodesPerBlock;
|
||||
//Deprecated, use nodes_per_block
|
||||
static const std::size_t nodes_per_chunk = NodesPerBlock;
|
||||
static const size_type nodes_per_chunk = NodesPerBlock;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_node_pool(segment_manager *segment_mngr)
|
||||
@@ -85,12 +85,12 @@ template< class SegmentManager
|
||||
, std::size_t NodesPerBlock
|
||||
>
|
||||
class shared_node_pool
|
||||
: public detail::shared_pool_impl
|
||||
: public ipcdetail::shared_pool_impl
|
||||
< private_node_pool
|
||||
<SegmentManager, NodeSize, NodesPerBlock>
|
||||
>
|
||||
{
|
||||
typedef detail::shared_pool_impl
|
||||
typedef ipcdetail::shared_pool_impl
|
||||
< private_node_pool
|
||||
<SegmentManager, NodeSize, NodesPerBlock>
|
||||
> base_t;
|
||||
@@ -100,7 +100,7 @@ class shared_node_pool
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2007-2011. Distributed under 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)
|
||||
//
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
|
||||
template<class VoidPointer>
|
||||
@@ -41,7 +41,7 @@ struct node_slist
|
||||
<node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
#include <boost/interprocess/allocators/detail/node_pool.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
|
||||
#include <memory>
|
||||
@@ -41,7 +41,7 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
template < unsigned int Version
|
||||
, class T
|
||||
@@ -68,7 +68,7 @@ class node_allocator_base
|
||||
template <int dummy>
|
||||
struct node_pool
|
||||
{
|
||||
typedef detail::shared_node_pool
|
||||
typedef ipcdetail::shared_node_pool
|
||||
< SegmentManager, sizeof_value<T>::value, NodesPerBlock> type;
|
||||
|
||||
static type *get(void *p)
|
||||
@@ -80,20 +80,22 @@ class node_allocator_base
|
||||
|
||||
public:
|
||||
//-------
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const T>::type const_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
typedef boost::interprocess::version_type<node_allocator_base, Version> version;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
|
||||
//!Obtains node_allocator_base from
|
||||
@@ -120,14 +122,14 @@ class node_allocator_base
|
||||
//!pool. Increments the reference count of the associated node pool.
|
||||
//!Can throw boost::interprocess::bad_alloc
|
||||
node_allocator_base(segment_manager *segment_mngr)
|
||||
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
|
||||
: mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
|
||||
|
||||
//!Copy constructor from other node_allocator_base. Increments the reference
|
||||
//!count of the associated node pool. Never throws
|
||||
node_allocator_base(const node_allocator_base &other)
|
||||
: mp_node_pool(other.get_node_pool())
|
||||
{
|
||||
node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
|
||||
node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->inc_ref_count();
|
||||
}
|
||||
|
||||
//!Copy constructor from related node_allocator_base. If not present, constructs
|
||||
@@ -136,7 +138,7 @@ class node_allocator_base
|
||||
template<class T2>
|
||||
node_allocator_base
|
||||
(const node_allocator_base<Version, T2, SegmentManager, NodesPerBlock> &other)
|
||||
: mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
|
||||
: mp_node_pool(ipcdetail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
|
||||
|
||||
//!Assignment from other node_allocator_base
|
||||
node_allocator_base& operator=(const node_allocator_base &other)
|
||||
@@ -149,22 +151,22 @@ class node_allocator_base
|
||||
//!Destructor, removes node_pool_t from memory
|
||||
//!if its reference count reaches to zero. Never throws
|
||||
~node_allocator_base()
|
||||
{ detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
|
||||
{ ipcdetail::destroy_node_pool_if_last_link(node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))); }
|
||||
|
||||
//!Returns a pointer to the node pool.
|
||||
//!Never throws
|
||||
void* get_node_pool() const
|
||||
{ return detail::get_pointer(mp_node_pool); }
|
||||
{ return ipcdetail::to_raw_pointer(mp_node_pool); }
|
||||
|
||||
//!Returns the segment manager.
|
||||
//!Never throws
|
||||
segment_manager* get_segment_manager()const
|
||||
{ return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
|
||||
{ return node_pool<0>::get(ipcdetail::to_raw_pointer(mp_node_pool))->get_segment_manager(); }
|
||||
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
||||
//!different memory segment, the result is undefined.
|
||||
friend void swap(self_t &alloc1, self_t &alloc2)
|
||||
{ detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
|
||||
{ ipcdetail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
@@ -199,7 +201,7 @@ class node_allocator_v1
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef detail::node_allocator_base
|
||||
typedef ipcdetail::node_allocator_base
|
||||
< 1, T, SegmentManager, NodesPerBlock> base_t;
|
||||
|
||||
template<class T2>
|
||||
@@ -219,7 +221,7 @@ class node_allocator_v1
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -237,7 +239,7 @@ template < class T
|
||||
>
|
||||
class node_allocator
|
||||
/// @cond
|
||||
: public detail::node_allocator_base
|
||||
: public ipcdetail::node_allocator_base
|
||||
< 2
|
||||
, T
|
||||
, SegmentManager
|
||||
@@ -247,7 +249,7 @@ class node_allocator
|
||||
{
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
typedef detail::node_allocator_base
|
||||
typedef ipcdetail::node_allocator_base
|
||||
< 2, T, SegmentManager, NodesPerBlock> base_t;
|
||||
public:
|
||||
typedef boost::interprocess::version_type<node_allocator, 2> version;
|
||||
@@ -275,12 +277,12 @@ class node_allocator
|
||||
typedef implementation_defined::pointer pointer;
|
||||
typedef implementation_defined::const_pointer const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
//!Obtains node_allocator from
|
||||
//!node_allocator
|
||||
@@ -383,7 +385,7 @@ class node_allocator
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements);
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
||||
//!contiguous block
|
||||
@@ -409,7 +411,7 @@ class node_allocator
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements);
|
||||
multiallocation_chain allocate_individual(size_type num_elements);
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,13 +18,13 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
@@ -40,7 +40,7 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template < unsigned int Version
|
||||
, class T
|
||||
@@ -68,7 +68,7 @@ class private_adaptive_pool_base
|
||||
typedef private_adaptive_pool_base
|
||||
< Version, T, SegmentManager, NodesPerBlock
|
||||
, MaxFreeBlocks, OverheadPercent> self_t;
|
||||
typedef detail::private_adaptive_node_pool
|
||||
typedef ipcdetail::private_adaptive_node_pool
|
||||
<SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -81,20 +81,22 @@ class private_adaptive_pool_base
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const T>::type const_pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::size_type difference_type;
|
||||
typedef boost::interprocess::version_type
|
||||
<private_adaptive_pool_base, Version> version;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
|
||||
//!Obtains node_allocator from other node_allocator
|
||||
@@ -110,7 +112,7 @@ class private_adaptive_pool_base
|
||||
template <int dummy>
|
||||
struct node_pool
|
||||
{
|
||||
typedef detail::private_adaptive_node_pool
|
||||
typedef ipcdetail::private_adaptive_node_pool
|
||||
<SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -203,7 +205,7 @@ class private_adaptive_pool_v1
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef detail::private_adaptive_pool_base
|
||||
typedef ipcdetail::private_adaptive_pool_base
|
||||
< 1, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
|
||||
|
||||
template<class T2>
|
||||
@@ -223,7 +225,7 @@ class private_adaptive_pool_v1
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -248,7 +250,7 @@ template < class T
|
||||
>
|
||||
class private_adaptive_pool
|
||||
/// @cond
|
||||
: public detail::private_adaptive_pool_base
|
||||
: public ipcdetail::private_adaptive_pool_base
|
||||
< 2
|
||||
, T
|
||||
, SegmentManager
|
||||
@@ -260,7 +262,7 @@ class private_adaptive_pool
|
||||
{
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
typedef detail::private_adaptive_pool_base
|
||||
typedef ipcdetail::private_adaptive_pool_base
|
||||
< 2, T, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> base_t;
|
||||
public:
|
||||
typedef boost::interprocess::version_type<private_adaptive_pool, 2> version;
|
||||
@@ -289,12 +291,12 @@ class private_adaptive_pool
|
||||
typedef implementation_defined::pointer pointer;
|
||||
typedef implementation_defined::const_pointer const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
|
||||
//!Obtains private_adaptive_pool from
|
||||
//!private_adaptive_pool
|
||||
@@ -398,7 +400,7 @@ class private_adaptive_pool
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements);
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
||||
//!contiguous block
|
||||
@@ -424,7 +426,7 @@ class private_adaptive_pool
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements);
|
||||
multiallocation_chain allocate_individual(size_type num_elements);
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,13 +18,13 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/interprocess/allocators/detail/node_pool.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
@@ -40,7 +40,7 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template < unsigned int Version
|
||||
, class T
|
||||
@@ -64,7 +64,7 @@ class private_node_allocator_base
|
||||
private:
|
||||
typedef private_node_allocator_base
|
||||
< Version, T, SegmentManager, NodesPerBlock> self_t;
|
||||
typedef detail::private_node_pool
|
||||
typedef ipcdetail::private_node_pool
|
||||
<SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -75,20 +75,23 @@ class private_node_allocator_base
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, T>::type pointer;
|
||||
typedef typename boost::
|
||||
pointer_to_other<void_pointer, const T>::type const_pointer;
|
||||
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<T>::type pointer;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<void_pointer>::template
|
||||
rebind_pointer<const T>::type const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manager::difference_type difference_type;
|
||||
typedef boost::interprocess::version_type
|
||||
<private_node_allocator_base, Version> version;
|
||||
typedef boost::container::containers_detail::transform_multiallocation_chain
|
||||
typedef boost::container::container_detail::transform_multiallocation_chain
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
|
||||
|
||||
//!Obtains node_allocator from other node_allocator
|
||||
@@ -103,7 +106,7 @@ class private_node_allocator_base
|
||||
template <int dummy>
|
||||
struct node_pool
|
||||
{
|
||||
typedef detail::private_node_pool
|
||||
typedef ipcdetail::private_node_pool
|
||||
<SegmentManager
|
||||
, sizeof_value<T>::value
|
||||
, NodesPerBlock
|
||||
@@ -190,7 +193,7 @@ class private_node_allocator_v1
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef detail::private_node_allocator_base
|
||||
typedef ipcdetail::private_node_allocator_base
|
||||
< 1, T, SegmentManager, NodesPerBlock> base_t;
|
||||
|
||||
template<class T2>
|
||||
@@ -210,7 +213,7 @@ class private_node_allocator_v1
|
||||
{}
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -226,7 +229,7 @@ template < class T
|
||||
>
|
||||
class private_node_allocator
|
||||
/// @cond
|
||||
: public detail::private_node_allocator_base
|
||||
: public ipcdetail::private_node_allocator_base
|
||||
< 2
|
||||
, T
|
||||
, SegmentManager
|
||||
@@ -236,7 +239,7 @@ class private_node_allocator
|
||||
{
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
||||
typedef detail::private_node_allocator_base
|
||||
typedef ipcdetail::private_node_allocator_base
|
||||
< 2, T, SegmentManager, NodesPerBlock> base_t;
|
||||
public:
|
||||
typedef boost::interprocess::version_type<private_node_allocator, 2> version;
|
||||
@@ -265,12 +268,12 @@ class private_node_allocator
|
||||
typedef implementation_defined::pointer pointer;
|
||||
typedef implementation_defined::const_pointer const_pointer;
|
||||
typedef T value_type;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<value_type>::type reference;
|
||||
typedef typename detail::add_reference
|
||||
typedef typename ipcdetail::add_reference
|
||||
<const value_type>::type const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef typename segment_manager::size_type size_type;
|
||||
typedef typename segment_manage::difference_type difference_type;
|
||||
|
||||
//!Obtains private_node_allocator from
|
||||
//!private_node_allocator
|
||||
@@ -374,7 +377,7 @@ class private_node_allocator
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
||||
//!with deallocate(...)
|
||||
multiallocation_chain allocate_many(size_type elem_size, std::size_t num_elements);
|
||||
multiallocation_chain allocate_many(size_type elem_size, size_type num_elements);
|
||||
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
||||
//!contiguous block
|
||||
@@ -400,7 +403,7 @@ class private_node_allocator
|
||||
//!preferred_elements. The number of actually allocated elements is
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
||||
//!must be deallocated only with deallocate_one().
|
||||
multiallocation_chain allocate_individual(std::size_t num_elements);
|
||||
multiallocation_chain allocate_individual(size_type num_elements);
|
||||
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/mapped_region.hpp>
|
||||
#include <cstddef>
|
||||
@@ -37,7 +37,7 @@ namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
class raw_mapped_region_creator
|
||||
{
|
||||
@@ -101,7 +101,7 @@ anonymous_shared_memory(std::size_t size, void *address = 0)
|
||||
if(fd != -1)
|
||||
close(fd);
|
||||
|
||||
return detail::raw_mapped_region_creator::create_posix_mapped_region(address, 0, size);
|
||||
return ipcdetail::raw_mapped_region_creator::create_posix_mapped_region(address, 0, size);
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/allocation_type.hpp>
|
||||
#include <boost/container/detail/allocation_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
|
||||
#define BOOST_CONTAINERS_CONTAINERS_FWD_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Standard predeclarations
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace boost{
|
||||
namespace intrusive{
|
||||
//Create namespace to avoid compilation errors
|
||||
}}
|
||||
|
||||
namespace boost{ namespace container{ namespace containers_detail{
|
||||
|
||||
namespace bi = boost::intrusive;
|
||||
|
||||
}}}
|
||||
|
||||
namespace std {
|
||||
|
||||
template <class T>
|
||||
class allocator;
|
||||
|
||||
template <class T>
|
||||
struct less;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair;
|
||||
|
||||
template <class CharType>
|
||||
struct char_traits;
|
||||
|
||||
} //namespace std {
|
||||
|
||||
/// @endcond
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Containers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
//vector class
|
||||
template <class T
|
||||
,class A = std::allocator<T> >
|
||||
class vector;
|
||||
|
||||
//vector class
|
||||
template <class T
|
||||
,class A = std::allocator<T> >
|
||||
class stable_vector;
|
||||
|
||||
//vector class
|
||||
template <class T
|
||||
,class A = std::allocator<T> >
|
||||
class deque;
|
||||
|
||||
//list class
|
||||
template <class T
|
||||
,class A = std::allocator<T> >
|
||||
class list;
|
||||
|
||||
//slist class
|
||||
template <class T
|
||||
,class Alloc = std::allocator<T> >
|
||||
class slist;
|
||||
|
||||
//set class
|
||||
template <class T
|
||||
,class Pred = std::less<T>
|
||||
,class Alloc = std::allocator<T> >
|
||||
class set;
|
||||
|
||||
//multiset class
|
||||
template <class T
|
||||
,class Pred = std::less<T>
|
||||
,class Alloc = std::allocator<T> >
|
||||
class multiset;
|
||||
|
||||
//map class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Pred = std::less<Key>
|
||||
,class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class map;
|
||||
|
||||
//multimap class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Pred = std::less<Key>
|
||||
,class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class multimap;
|
||||
|
||||
//flat_set class
|
||||
template <class T
|
||||
,class Pred = std::less<T>
|
||||
,class Alloc = std::allocator<T> >
|
||||
class flat_set;
|
||||
|
||||
//flat_multiset class
|
||||
template <class T
|
||||
,class Pred = std::less<T>
|
||||
,class Alloc = std::allocator<T> >
|
||||
class flat_multiset;
|
||||
|
||||
//flat_map class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Pred = std::less<Key>
|
||||
,class Alloc = std::allocator<std::pair<Key, T> > >
|
||||
class flat_map;
|
||||
|
||||
//flat_multimap class
|
||||
template <class Key
|
||||
,class T
|
||||
,class Pred = std::less<Key>
|
||||
,class Alloc = std::allocator<std::pair<Key, T> > >
|
||||
class flat_multimap;
|
||||
|
||||
//basic_string class
|
||||
template <class CharT
|
||||
,class Traits = std::char_traits<CharT>
|
||||
,class Alloc = std::allocator<CharT> >
|
||||
class basic_string;
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
struct ordered_range_impl_t {};
|
||||
|
||||
//! Type used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
struct ordered_unique_range_impl_t{};
|
||||
|
||||
/// @cond
|
||||
|
||||
typedef ordered_range_impl_t * ordered_range_t;
|
||||
typedef ordered_unique_range_impl_t *ordered_unique_range_t;
|
||||
|
||||
/// @endcond
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered
|
||||
static const ordered_range_t ordered_range = 0;
|
||||
|
||||
//! Value used to tag that the input range is
|
||||
//! guaranteed to be ordered and unique
|
||||
static const ordered_unique_range_t ordered_unique_range = 0;
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace detail_really_deep_namespace {
|
||||
|
||||
//Otherwise, gcc issues a warning of previously defined
|
||||
//anonymous_instance and unique_instance
|
||||
struct dummy
|
||||
{
|
||||
dummy()
|
||||
{
|
||||
(void)ordered_range;
|
||||
(void)ordered_unique_range;
|
||||
}
|
||||
};
|
||||
|
||||
} //detail_really_deep_namespace {
|
||||
|
||||
/// @endcond
|
||||
|
||||
}} //namespace boost { namespace container {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,641 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
struct hdr_offset_holder
|
||||
{
|
||||
hdr_offset_holder(std::size_t offset = 0)
|
||||
: hdr_offset(offset)
|
||||
{}
|
||||
std::size_t hdr_offset;
|
||||
};
|
||||
|
||||
template<class VoidPointer>
|
||||
struct adaptive_pool_types
|
||||
{
|
||||
typedef VoidPointer void_pointer;
|
||||
typedef typename bi::make_set_base_hook
|
||||
< bi::void_pointer<void_pointer>
|
||||
, bi::optimize_size<true>
|
||||
, bi::constant_time_size<false>
|
||||
, bi::link_mode<bi::normal_link> >::type multiset_hook_t;
|
||||
|
||||
struct block_info_t
|
||||
:
|
||||
public hdr_offset_holder,
|
||||
public multiset_hook_t
|
||||
{
|
||||
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
|
||||
//An intrusive list of free node from this block
|
||||
free_nodes_t free_nodes;
|
||||
friend bool operator <(const block_info_t &l, const block_info_t &r)
|
||||
{
|
||||
// { return l.free_nodes.size() < r.free_nodes.size(); }
|
||||
//Let's order blocks first by free nodes and then by address
|
||||
//so that highest address fully free blocks are deallocated.
|
||||
//This improves returning memory to the OS (trimming).
|
||||
const bool is_less = l.free_nodes.size() < r.free_nodes.size();
|
||||
const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
|
||||
return is_less || (is_equal && (&l < &r));
|
||||
}
|
||||
|
||||
friend bool operator ==(const block_info_t &l, const block_info_t &r)
|
||||
{ return &l == &r; }
|
||||
};
|
||||
typedef typename bi::make_multiset
|
||||
<block_info_t, bi::base_hook<multiset_hook_t> >::type block_multiset_t;
|
||||
};
|
||||
|
||||
|
||||
inline std::size_t calculate_alignment
|
||||
( std::size_t overhead_percent, std::size_t real_node_size
|
||||
, std::size_t hdr_size, std::size_t hdr_offset_size, std::size_t payload_per_allocation)
|
||||
{
|
||||
//to-do: handle real_node_size != node_size
|
||||
const std::size_t divisor = overhead_percent*real_node_size;
|
||||
const std::size_t dividend = hdr_offset_size*100;
|
||||
std::size_t elements_per_subblock = (dividend - 1)/divisor + 1;
|
||||
std::size_t candidate_power_of_2 =
|
||||
upper_power_of_2(elements_per_subblock*real_node_size + hdr_offset_size);
|
||||
bool overhead_satisfied = false;
|
||||
//Now calculate the wors-case overhead for a subblock
|
||||
const std::size_t max_subblock_overhead = hdr_size + payload_per_allocation;
|
||||
while(!overhead_satisfied){
|
||||
elements_per_subblock = (candidate_power_of_2 - max_subblock_overhead)/real_node_size;
|
||||
const std::size_t overhead_size = candidate_power_of_2 - elements_per_subblock*real_node_size;
|
||||
if(overhead_size*100/candidate_power_of_2 < overhead_percent){
|
||||
overhead_satisfied = true;
|
||||
}
|
||||
else{
|
||||
candidate_power_of_2 <<= 1;
|
||||
}
|
||||
}
|
||||
return candidate_power_of_2;
|
||||
}
|
||||
|
||||
inline void calculate_num_subblocks
|
||||
(std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_block
|
||||
, std::size_t &num_subblocks, std::size_t &real_num_node, std::size_t overhead_percent
|
||||
, std::size_t hdr_size, std::size_t hdr_offset_size, std::size_t payload_per_allocation)
|
||||
{
|
||||
std::size_t elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
|
||||
std::size_t possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
|
||||
std::size_t hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
|
||||
while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
|
||||
++possible_num_subblock;
|
||||
}
|
||||
elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
|
||||
bool overhead_satisfied = false;
|
||||
while(!overhead_satisfied){
|
||||
const std::size_t total_data = (elements_per_subblock*(possible_num_subblock-1) + hdr_subblock_elements)*real_node_size;
|
||||
const std::size_t total_size = alignment*possible_num_subblock;
|
||||
if((total_size - total_data)*100/total_size < overhead_percent){
|
||||
overhead_satisfied = true;
|
||||
}
|
||||
else{
|
||||
++possible_num_subblock;
|
||||
}
|
||||
}
|
||||
num_subblocks = possible_num_subblock;
|
||||
real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
|
||||
}
|
||||
|
||||
template<class SegmentManagerBase, bool AlignOnly = false>
|
||||
class private_adaptive_node_pool_impl
|
||||
{
|
||||
//Non-copyable
|
||||
private_adaptive_node_pool_impl();
|
||||
private_adaptive_node_pool_impl(const private_adaptive_node_pool_impl &);
|
||||
private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
|
||||
typedef private_adaptive_node_pool_impl this_type;
|
||||
|
||||
typedef typename SegmentManagerBase::void_pointer void_pointer;
|
||||
static const std::size_t PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
|
||||
typedef bool_<AlignOnly> IsAlignOnly;
|
||||
typedef true_ AlignOnlyTrue;
|
||||
typedef false_ AlignOnlyFalse;
|
||||
|
||||
public:
|
||||
typedef typename node_slist<void_pointer>::node_t node_t;
|
||||
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
|
||||
typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
|
||||
|
||||
private:
|
||||
typedef typename adaptive_pool_types<void_pointer>::block_info_t block_info_t;
|
||||
typedef typename adaptive_pool_types<void_pointer>::block_multiset_t block_multiset_t;
|
||||
typedef typename block_multiset_t::iterator block_iterator;
|
||||
|
||||
static const std::size_t MaxAlign = alignment_of<node_t>::value;
|
||||
static const std::size_t HdrSize = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
|
||||
static const std::size_t HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
|
||||
|
||||
|
||||
public:
|
||||
//!Segment manager typedef
|
||||
typedef SegmentManagerBase segment_manager_base_type;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_adaptive_node_pool_impl
|
||||
( segment_manager_base_type *segment_mngr_base
|
||||
, std::size_t node_size
|
||||
, std::size_t nodes_per_block
|
||||
, std::size_t max_free_blocks
|
||||
, unsigned char overhead_percent
|
||||
)
|
||||
: m_max_free_blocks(max_free_blocks)
|
||||
, m_real_node_size(lcm(node_size, std::size_t(alignment_of<node_t>::value)))
|
||||
//Round the size to a power of two value.
|
||||
//This is the total memory size (including payload) that we want to
|
||||
//allocate from the general-purpose allocator
|
||||
, m_real_block_alignment
|
||||
(AlignOnly ?
|
||||
upper_power_of_2(HdrSize + m_real_node_size*nodes_per_block) :
|
||||
calculate_alignment( overhead_percent, m_real_node_size
|
||||
, HdrSize, HdrOffsetSize, PayloadPerAllocation))
|
||||
//This is the real number of nodes per block
|
||||
, m_num_subblocks(0)
|
||||
, m_real_num_node(AlignOnly ? (m_real_block_alignment - PayloadPerAllocation - HdrSize)/m_real_node_size : 0)
|
||||
//General purpose allocator
|
||||
, mp_segment_mngr_base(segment_mngr_base)
|
||||
, m_block_multiset()
|
||||
, m_totally_free_blocks(0)
|
||||
{
|
||||
if(!AlignOnly){
|
||||
calculate_num_subblocks
|
||||
( m_real_block_alignment
|
||||
, m_real_node_size
|
||||
, nodes_per_block
|
||||
, m_num_subblocks
|
||||
, m_real_num_node
|
||||
, overhead_percent
|
||||
, HdrSize
|
||||
, HdrOffsetSize
|
||||
, PayloadPerAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~private_adaptive_node_pool_impl()
|
||||
{ priv_clear(); }
|
||||
|
||||
std::size_t get_real_num_node() const
|
||||
{ return m_real_num_node; }
|
||||
|
||||
//!Returns the segment manager. Never throws
|
||||
segment_manager_base_type* get_segment_manager_base()const
|
||||
{ return containers_detail::get_pointer(mp_segment_mngr_base); }
|
||||
|
||||
//!Allocates array of count elements. Can throw
|
||||
void *allocate_node()
|
||||
{
|
||||
priv_invariants();
|
||||
//If there are no free nodes we allocate a new block
|
||||
if (m_block_multiset.empty()){
|
||||
priv_alloc_block(1);
|
||||
}
|
||||
//We take the first free node the multiset can't be empty
|
||||
return priv_take_first_node();
|
||||
}
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *pElem)
|
||||
{
|
||||
multiallocation_chain chain;
|
||||
chain.push_front(void_pointer(pElem));
|
||||
this->priv_reinsert_nodes_in_block(chain, 1);
|
||||
//Update free block count<
|
||||
if(m_totally_free_blocks > m_max_free_blocks){
|
||||
this->priv_deallocate_free_blocks(m_max_free_blocks);
|
||||
}
|
||||
priv_invariants();
|
||||
}
|
||||
|
||||
//!Allocates n nodes.
|
||||
//!Can throw
|
||||
multiallocation_chain allocate_nodes(const std::size_t n)
|
||||
{
|
||||
multiallocation_chain chain;
|
||||
std::size_t i = 0;
|
||||
try{
|
||||
priv_invariants();
|
||||
while(i != n){
|
||||
//If there are no free nodes we allocate all needed blocks
|
||||
if (m_block_multiset.empty()){
|
||||
priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
|
||||
}
|
||||
free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
|
||||
const std::size_t free_nodes_count_before = free_nodes.size();
|
||||
if(free_nodes_count_before == m_real_num_node){
|
||||
--m_totally_free_blocks;
|
||||
}
|
||||
const std::size_t num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
|
||||
for(std::size_t j = 0; j != num_elems; ++j){
|
||||
void *new_node = &free_nodes.front();
|
||||
free_nodes.pop_front();
|
||||
chain.push_back(new_node);
|
||||
}
|
||||
|
||||
if(free_nodes.empty()){
|
||||
m_block_multiset.erase(m_block_multiset.begin());
|
||||
}
|
||||
i += num_elems;
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
this->deallocate_nodes(BOOST_CONTAINER_MOVE_NAMESPACE::move(chain));
|
||||
throw;
|
||||
}
|
||||
priv_invariants();
|
||||
return BOOST_CONTAINER_MOVE_NAMESPACE::move(chain);
|
||||
}
|
||||
|
||||
//!Deallocates a linked list of nodes. Never throws
|
||||
void deallocate_nodes(multiallocation_chain nodes)
|
||||
{
|
||||
this->priv_reinsert_nodes_in_block(nodes, nodes.size());
|
||||
if(m_totally_free_blocks > m_max_free_blocks){
|
||||
this->priv_deallocate_free_blocks(m_max_free_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
void deallocate_free_blocks()
|
||||
{ this->priv_deallocate_free_blocks(0); }
|
||||
|
||||
std::size_t num_free_nodes()
|
||||
{
|
||||
typedef typename block_multiset_t::const_iterator citerator;
|
||||
std::size_t count = 0;
|
||||
citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
|
||||
for(; it != itend; ++it){
|
||||
count += it->free_nodes.size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void swap(private_adaptive_node_pool_impl &other)
|
||||
{
|
||||
BOOST_ASSERT(m_max_free_blocks == other.m_max_free_blocks);
|
||||
BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
|
||||
BOOST_ASSERT(m_real_block_alignment == other.m_real_block_alignment);
|
||||
BOOST_ASSERT(m_real_num_node == other.m_real_num_node);
|
||||
std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
|
||||
std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
|
||||
m_block_multiset.swap(other.m_block_multiset);
|
||||
}
|
||||
|
||||
//Deprecated, use deallocate_free_blocks
|
||||
void deallocate_free_chunks()
|
||||
{ this->priv_deallocate_free_blocks(0); }
|
||||
|
||||
private:
|
||||
void priv_deallocate_free_blocks(std::size_t max_free_blocks)
|
||||
{
|
||||
priv_invariants();
|
||||
//Now check if we've reached the free nodes limit
|
||||
//and check if we have free blocks. If so, deallocate as much
|
||||
//as we can to stay below the limit
|
||||
for( block_iterator itend = m_block_multiset.end()
|
||||
; m_totally_free_blocks > max_free_blocks
|
||||
; --m_totally_free_blocks
|
||||
){
|
||||
BOOST_ASSERT(!m_block_multiset.empty());
|
||||
block_iterator it = itend;
|
||||
--it;
|
||||
BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
|
||||
m_block_multiset.erase_and_dispose(it, block_destroyer(this));
|
||||
}
|
||||
}
|
||||
|
||||
void priv_reinsert_nodes_in_block(multiallocation_chain &chain, std::size_t n)
|
||||
{
|
||||
block_iterator block_it(m_block_multiset.end());
|
||||
while(n--){
|
||||
void *pElem = containers_detail::get_pointer(chain.front());
|
||||
chain.pop_front();
|
||||
priv_invariants();
|
||||
block_info_t *block_info = this->priv_block_from_node(pElem);
|
||||
BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
|
||||
//We put the node at the beginning of the free node list
|
||||
node_t * to_deallocate = static_cast<node_t*>(pElem);
|
||||
block_info->free_nodes.push_front(*to_deallocate);
|
||||
|
||||
block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
|
||||
block_iterator next_block(this_block);
|
||||
++next_block;
|
||||
|
||||
//Cache the free nodes from the block
|
||||
std::size_t this_block_free_nodes = this_block->free_nodes.size();
|
||||
|
||||
if(this_block_free_nodes == 1){
|
||||
m_block_multiset.insert(m_block_multiset.begin(), *block_info);
|
||||
}
|
||||
else{
|
||||
block_iterator next_block(this_block);
|
||||
++next_block;
|
||||
if(next_block != block_it){
|
||||
std::size_t next_free_nodes = next_block->free_nodes.size();
|
||||
if(this_block_free_nodes > next_free_nodes){
|
||||
//Now move the block to the new position
|
||||
m_block_multiset.erase(this_block);
|
||||
m_block_multiset.insert(*block_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Update free block count
|
||||
if(this_block_free_nodes == m_real_num_node){
|
||||
++m_totally_free_blocks;
|
||||
}
|
||||
priv_invariants();
|
||||
}
|
||||
}
|
||||
|
||||
node_t *priv_take_first_node()
|
||||
{
|
||||
BOOST_ASSERT(m_block_multiset.begin() != m_block_multiset.end());
|
||||
//We take the first free node the multiset can't be empty
|
||||
free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
|
||||
node_t *first_node = &free_nodes.front();
|
||||
const std::size_t free_nodes_count = free_nodes.size();
|
||||
BOOST_ASSERT(0 != free_nodes_count);
|
||||
free_nodes.pop_front();
|
||||
if(free_nodes_count == 1){
|
||||
m_block_multiset.erase(m_block_multiset.begin());
|
||||
}
|
||||
else if(free_nodes_count == m_real_num_node){
|
||||
--m_totally_free_blocks;
|
||||
}
|
||||
priv_invariants();
|
||||
return first_node;
|
||||
}
|
||||
|
||||
class block_destroyer;
|
||||
friend class block_destroyer;
|
||||
|
||||
class block_destroyer
|
||||
{
|
||||
public:
|
||||
block_destroyer(const this_type *impl)
|
||||
: mp_impl(impl)
|
||||
{}
|
||||
|
||||
void operator()(typename block_multiset_t::pointer to_deallocate)
|
||||
{ return this->do_destroy(to_deallocate, IsAlignOnly()); }
|
||||
|
||||
private:
|
||||
void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyTrue)
|
||||
{
|
||||
std::size_t free_nodes = to_deallocate->free_nodes.size();
|
||||
(void)free_nodes;
|
||||
BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
|
||||
mp_impl->mp_segment_mngr_base->deallocate(to_deallocate);
|
||||
}
|
||||
|
||||
void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyFalse)
|
||||
{
|
||||
std::size_t free_nodes = to_deallocate->free_nodes.size();
|
||||
(void)free_nodes;
|
||||
BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
|
||||
BOOST_ASSERT(0 == to_deallocate->hdr_offset);
|
||||
hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(containers_detail::get_pointer(to_deallocate));
|
||||
mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
|
||||
}
|
||||
|
||||
const this_type *mp_impl;
|
||||
};
|
||||
|
||||
//This macro will activate invariant checking. Slow, but helpful for debugging the code.
|
||||
//#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
|
||||
void priv_invariants()
|
||||
#ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
|
||||
#undef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
|
||||
{
|
||||
//We iterate through the block tree to free the memory
|
||||
block_iterator it(m_block_multiset.begin()),
|
||||
itend(m_block_multiset.end()), to_deallocate;
|
||||
if(it != itend){
|
||||
for(++it; it != itend; ++it){
|
||||
block_iterator prev(it);
|
||||
--prev;
|
||||
std::size_t sp = prev->free_nodes.size(),
|
||||
si = it->free_nodes.size();
|
||||
BOOST_ASSERT(sp <= si);
|
||||
(void)sp; (void)si;
|
||||
}
|
||||
}
|
||||
//Check that the total free nodes are correct
|
||||
it = m_block_multiset.begin();
|
||||
itend = m_block_multiset.end();
|
||||
std::size_t total_free_nodes = 0;
|
||||
for(; it != itend; ++it){
|
||||
total_free_nodes += it->free_nodes.size();
|
||||
}
|
||||
BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
|
||||
|
||||
//Check that the total totally free blocks are correct
|
||||
it = m_block_multiset.begin();
|
||||
itend = m_block_multiset.end();
|
||||
total_free = 0;
|
||||
for(; it != itend; ++it){
|
||||
total_free += it->free_nodes.size() == m_real_num_node;
|
||||
}
|
||||
BOOST_ASSERT(total_free >= m_totally_free_blocks);
|
||||
|
||||
if(!AlignOnly){
|
||||
//Check that header offsets are correct
|
||||
it = m_block_multiset.begin();
|
||||
for(; it != itend; ++it){
|
||||
hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
|
||||
for(std::size_t i = 0, max = m_num_subblocks; i < max; ++i){
|
||||
BOOST_ASSERT(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
|
||||
BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
|
||||
BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
|
||||
hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
{} //empty
|
||||
#endif
|
||||
|
||||
//!Deallocates all used memory. Never throws
|
||||
void priv_clear()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
block_iterator it = m_block_multiset.begin();
|
||||
block_iterator itend = m_block_multiset.end();
|
||||
std::size_t num_free_nodes = 0;
|
||||
for(; it != itend; ++it){
|
||||
//Check for memory leak
|
||||
BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
|
||||
++num_free_nodes;
|
||||
}
|
||||
BOOST_ASSERT(num_free_nodes == m_totally_free_blocks);
|
||||
#endif
|
||||
//Check for memory leaks
|
||||
priv_invariants();
|
||||
m_block_multiset.clear_and_dispose(block_destroyer(this));
|
||||
m_totally_free_blocks = 0;
|
||||
}
|
||||
|
||||
block_info_t *priv_block_from_node(void *node, AlignOnlyFalse) const
|
||||
{
|
||||
hdr_offset_holder *hdr_off_holder =
|
||||
reinterpret_cast<hdr_offset_holder*>((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
|
||||
BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
|
||||
BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
|
||||
block_info_t *block = reinterpret_cast<block_info_t *>
|
||||
(reinterpret_cast<char*>(hdr_off_holder) + hdr_off_holder->hdr_offset);
|
||||
BOOST_ASSERT(block->hdr_offset == 0);
|
||||
return block;
|
||||
}
|
||||
|
||||
block_info_t *priv_block_from_node(void *node, AlignOnlyTrue) const
|
||||
{
|
||||
return (block_info_t *)((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
|
||||
}
|
||||
|
||||
block_info_t *priv_block_from_node(void *node) const
|
||||
{ return priv_block_from_node(node, IsAlignOnly()); }
|
||||
|
||||
hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
|
||||
{
|
||||
hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
|
||||
(reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
|
||||
BOOST_ASSERT(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
|
||||
BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
|
||||
BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
|
||||
return hdr_off_holder;
|
||||
}
|
||||
|
||||
//!Allocates a several blocks of nodes. Can throw
|
||||
void priv_alloc_block(std::size_t n, AlignOnlyTrue)
|
||||
{
|
||||
std::size_t real_block_size = m_real_block_alignment - PayloadPerAllocation;
|
||||
for(std::size_t i = 0; i != n; ++i){
|
||||
//We allocate a new NodeBlock and put it the last
|
||||
//element of the tree
|
||||
char *mem_address = static_cast<char*>
|
||||
(mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
|
||||
if(!mem_address) throw std::bad_alloc();
|
||||
++m_totally_free_blocks;
|
||||
block_info_t *c_info = new(mem_address)block_info_t;
|
||||
m_block_multiset.insert(m_block_multiset.end(), *c_info);
|
||||
|
||||
mem_address += HdrSize;
|
||||
//We initialize all Nodes in Node Block to insert
|
||||
//them in the free Node list
|
||||
typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
|
||||
for(std::size_t i = 0; i < m_real_num_node; ++i){
|
||||
prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *(node_t*)mem_address);
|
||||
mem_address += m_real_node_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void priv_alloc_block(std::size_t n, AlignOnlyFalse)
|
||||
{
|
||||
std::size_t real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
|
||||
std::size_t elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
|
||||
std::size_t hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
|
||||
|
||||
for(std::size_t i = 0; i != n; ++i){
|
||||
//We allocate a new NodeBlock and put it the last
|
||||
//element of the tree
|
||||
char *mem_address = static_cast<char*>
|
||||
(mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
|
||||
if(!mem_address) throw std::bad_alloc();
|
||||
++m_totally_free_blocks;
|
||||
|
||||
//First initialize header information on the last subblock
|
||||
char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
|
||||
block_info_t *c_info = new(hdr_addr)block_info_t;
|
||||
//Some structural checks
|
||||
BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
|
||||
static_cast<void*>(c_info));
|
||||
typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
|
||||
for( std::size_t subblock = 0, maxsubblock = m_num_subblocks - 1
|
||||
; subblock < maxsubblock
|
||||
; ++subblock, mem_address += m_real_block_alignment){
|
||||
//Initialize header offset mark
|
||||
new(mem_address) hdr_offset_holder(std::size_t(hdr_addr - mem_address));
|
||||
char *pNode = mem_address + HdrOffsetSize;
|
||||
for(std::size_t i = 0; i < elements_per_subblock; ++i){
|
||||
prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
|
||||
pNode += m_real_node_size;
|
||||
}
|
||||
}
|
||||
{
|
||||
char *pNode = hdr_addr + HdrSize;
|
||||
//We initialize all Nodes in Node Block to insert
|
||||
//them in the free Node list
|
||||
for(std::size_t i = 0; i < hdr_subblock_elements; ++i){
|
||||
prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
|
||||
pNode += m_real_node_size;
|
||||
}
|
||||
}
|
||||
//Insert the block after the free node list is full
|
||||
m_block_multiset.insert(m_block_multiset.end(), *c_info);
|
||||
}
|
||||
}
|
||||
|
||||
//!Allocates a block of nodes. Can throw std::bad_alloc
|
||||
void priv_alloc_block(std::size_t n)
|
||||
{ return priv_alloc_block(n, IsAlignOnly()); }
|
||||
|
||||
private:
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
|
||||
const std::size_t m_max_free_blocks;
|
||||
const std::size_t m_real_node_size;
|
||||
//Round the size to a power of two value.
|
||||
//This is the total memory size (including payload) that we want to
|
||||
//allocate from the general-purpose allocator
|
||||
const std::size_t m_real_block_alignment;
|
||||
std::size_t m_num_subblocks;
|
||||
//This is the real number of nodes per block
|
||||
//const
|
||||
std::size_t m_real_num_node;
|
||||
segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
|
||||
block_multiset_t m_block_multiset; //Intrusive block list
|
||||
std::size_t m_totally_free_blocks; //Free blocks
|
||||
};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
@@ -1,385 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
|
||||
#define BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
#include <iterator> //std::iterator_traits
|
||||
#include <new> //placement new
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace container { namespace containers_detail {
|
||||
|
||||
//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
|
||||
template<class T, class Iterator>
|
||||
struct advanced_insert_aux_int
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
|
||||
virtual void copy_all_to(Iterator p) = 0;
|
||||
virtual void uninitialized_copy_all_to(Iterator p) = 0;
|
||||
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
|
||||
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
|
||||
virtual ~advanced_insert_aux_int() {}
|
||||
};
|
||||
|
||||
//This class template will adapt each FwIt types to advanced_insert_aux_int
|
||||
template<class T, class FwdIt, class Iterator>
|
||||
struct advanced_insert_aux_proxy
|
||||
: public advanced_insert_aux_int<T, Iterator>
|
||||
{
|
||||
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
|
||||
advanced_insert_aux_proxy(FwdIt first, FwdIt last)
|
||||
: first_(first), last_(last)
|
||||
{}
|
||||
|
||||
virtual ~advanced_insert_aux_proxy()
|
||||
{}
|
||||
|
||||
virtual void copy_all_to(Iterator p)
|
||||
{ ::BOOST_CONTAINER_MOVE_NAMESPACE::copy_or_move(first_, last_, p); }
|
||||
|
||||
virtual void uninitialized_copy_all_to(Iterator p)
|
||||
{ ::BOOST_CONTAINER_MOVE_NAMESPACE::uninitialized_copy_or_move(first_, last_, p); }
|
||||
|
||||
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
|
||||
{
|
||||
FwdIt mid = first_;
|
||||
std::advance(mid, division_count);
|
||||
if(first_n){
|
||||
::BOOST_CONTAINER_MOVE_NAMESPACE::uninitialized_copy_or_move(first_, mid, pos);
|
||||
first_ = mid;
|
||||
}
|
||||
else{
|
||||
::BOOST_CONTAINER_MOVE_NAMESPACE::uninitialized_copy_or_move(mid, last_, pos);
|
||||
last_ = mid;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
|
||||
{
|
||||
FwdIt mid = first_;
|
||||
std::advance(mid, division_count);
|
||||
if(first_n){
|
||||
::BOOST_CONTAINER_MOVE_NAMESPACE::copy_or_move(first_, mid, pos);
|
||||
first_ = mid;
|
||||
}
|
||||
else{
|
||||
::BOOST_CONTAINER_MOVE_NAMESPACE::copy_or_move(mid, last_, pos);
|
||||
last_ = mid;
|
||||
}
|
||||
}
|
||||
|
||||
FwdIt first_, last_;
|
||||
};
|
||||
|
||||
//This class template will adapt each FwIt types to advanced_insert_aux_int
|
||||
template<class T, class Iterator, class SizeType>
|
||||
struct default_construct_aux_proxy
|
||||
: public advanced_insert_aux_int<T, Iterator>
|
||||
{
|
||||
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
|
||||
default_construct_aux_proxy(SizeType count)
|
||||
: count_(count)
|
||||
{}
|
||||
|
||||
void uninitialized_copy_impl(Iterator p, const SizeType n)
|
||||
{
|
||||
BOOST_ASSERT(n <= count_);
|
||||
Iterator orig_p = p;
|
||||
SizeType i = 0;
|
||||
try{
|
||||
for(; i < n; ++i, ++p){
|
||||
new(containers_detail::get_pointer(&*p))T();
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
while(i--){
|
||||
containers_detail::get_pointer(&*orig_p++)->~T();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
count_ -= n;
|
||||
}
|
||||
|
||||
virtual ~default_construct_aux_proxy()
|
||||
{}
|
||||
|
||||
virtual void copy_all_to(Iterator)
|
||||
{ //This should never be called with any count
|
||||
BOOST_ASSERT(count_ == 0);
|
||||
}
|
||||
|
||||
virtual void uninitialized_copy_all_to(Iterator p)
|
||||
{ this->uninitialized_copy_impl(p, count_); }
|
||||
|
||||
virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
|
||||
{
|
||||
SizeType new_count;
|
||||
if(first_n){
|
||||
new_count = division_count;
|
||||
}
|
||||
else{
|
||||
BOOST_ASSERT(difference_type(count_)>= division_count);
|
||||
new_count = count_ - division_count;
|
||||
}
|
||||
this->uninitialized_copy_impl(pos, new_count);
|
||||
}
|
||||
|
||||
virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
|
||||
{
|
||||
BOOST_ASSERT(count_ == 0);
|
||||
SizeType new_count;
|
||||
if(first_n){
|
||||
new_count = division_count;
|
||||
}
|
||||
else{
|
||||
BOOST_ASSERT(difference_type(count_)>= division_count);
|
||||
new_count = count_ - division_count;
|
||||
}
|
||||
//This function should never called with a count different to zero
|
||||
BOOST_ASSERT(new_count == 0);
|
||||
(void)new_count;
|
||||
}
|
||||
|
||||
SizeType count_;
|
||||
};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace containers_detail {
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
#include <typeinfo>
|
||||
//#include <iostream> //For debugging purposes
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
//This class template will adapt each FwIt types to advanced_insert_aux_int
|
||||
template<class T, class Iterator, class ...Args>
|
||||
struct advanced_insert_aux_emplace
|
||||
: public advanced_insert_aux_int<T, Iterator>
|
||||
{
|
||||
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
|
||||
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
explicit advanced_insert_aux_emplace(Args&&... args)
|
||||
: args_(args...)
|
||||
, used_(false)
|
||||
{}
|
||||
|
||||
~advanced_insert_aux_emplace()
|
||||
{}
|
||||
|
||||
virtual void copy_all_to(Iterator p)
|
||||
{ this->priv_copy_all_to(index_tuple_t(), p); }
|
||||
|
||||
virtual void uninitialized_copy_all_to(Iterator p)
|
||||
{ this->priv_uninitialized_copy_all_to(index_tuple_t(), p); }
|
||||
|
||||
virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
|
||||
{ this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
|
||||
|
||||
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
|
||||
{ this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
|
||||
|
||||
private:
|
||||
template<int ...IdxPack>
|
||||
void priv_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
|
||||
{
|
||||
if(!used_){
|
||||
*p = BOOST_CONTAINER_MOVE_NAMESPACE::move(T (::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...));
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
template<int ...IdxPack>
|
||||
void priv_uninitialized_copy_all_to(const index_tuple<IdxPack...>&, Iterator p)
|
||||
{
|
||||
if(!used_){
|
||||
new(containers_detail::get_pointer(&*p))T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...);
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
template<int ...IdxPack>
|
||||
void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
|
||||
{
|
||||
BOOST_ASSERT(division_count <=1);
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
|
||||
if(!used_){
|
||||
new(containers_detail::get_pointer(&*p))T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...);
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int ...IdxPack>
|
||||
void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
|
||||
{
|
||||
BOOST_ASSERT(division_count <=1);
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
|
||||
if(!used_){
|
||||
*p = BOOST_CONTAINER_MOVE_NAMESPACE::move(T(::boost::container::containers_detail::stored_ref<Args>::forward(get<IdxPack>(args_))...));
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
tuple<Args&...> args_;
|
||||
bool used_;
|
||||
};
|
||||
|
||||
}}} //namespace boost { namespace container { namespace containers_detail {
|
||||
|
||||
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
//This class template will adapt each FwIt types to advanced_insert_aux_int
|
||||
template<class T, class Iterator>
|
||||
struct advanced_insert_aux_emplace
|
||||
: public advanced_insert_aux_int<T, Iterator>
|
||||
{
|
||||
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type;
|
||||
advanced_insert_aux_emplace()
|
||||
: used_(false)
|
||||
{}
|
||||
|
||||
~advanced_insert_aux_emplace()
|
||||
{}
|
||||
|
||||
virtual void copy_all_to(Iterator p)
|
||||
{
|
||||
if(!used_){
|
||||
value_init<T>v;
|
||||
*p = BOOST_CONTAINER_MOVE_NAMESPACE::move(v.m_t);
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void uninitialized_copy_all_to(Iterator p)
|
||||
{
|
||||
if(!used_){
|
||||
new(containers_detail::get_pointer(&*p))T();
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
|
||||
{
|
||||
BOOST_ASSERT(division_count <=1);
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
|
||||
if(!used_){
|
||||
new(containers_detail::get_pointer(&*p))T();
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
|
||||
{
|
||||
BOOST_ASSERT(division_count <=1);
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){
|
||||
if(!used_){
|
||||
value_init<T>v;
|
||||
*p = BOOST_CONTAINER_MOVE_NAMESPACE::move(v.m_t);
|
||||
used_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool used_;
|
||||
};
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<class T, class Iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
|
||||
: public advanced_insert_aux_int<T, Iterator> \
|
||||
{ \
|
||||
typedef typename advanced_insert_aux_int<T, Iterator>::difference_type difference_type; \
|
||||
\
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
|
||||
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
|
||||
: used_(false), BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
|
||||
\
|
||||
virtual void copy_all_to(Iterator p) \
|
||||
{ \
|
||||
if(!used_){ \
|
||||
T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
|
||||
*p = BOOST_CONTAINER_MOVE_NAMESPACE::move(v); \
|
||||
used_ = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
virtual void uninitialized_copy_all_to(Iterator p) \
|
||||
{ \
|
||||
if(!used_){ \
|
||||
new(containers_detail::get_pointer(&*p))T \
|
||||
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
|
||||
used_ = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
virtual void uninitialized_copy_some_and_update \
|
||||
(Iterator p, difference_type division_count, bool first_n) \
|
||||
{ \
|
||||
BOOST_ASSERT(division_count <=1); \
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
|
||||
if(!used_){ \
|
||||
new(containers_detail::get_pointer(&*p))T \
|
||||
(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
|
||||
used_ = true; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
virtual void copy_some_and_update \
|
||||
(Iterator p, difference_type division_count, bool first_n) \
|
||||
{ \
|
||||
BOOST_ASSERT(division_count <=1); \
|
||||
if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
|
||||
if(!used_){ \
|
||||
T v(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
|
||||
*p = BOOST_CONTAINER_MOVE_NAMESPACE::move(v); \
|
||||
used_ = true; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool used_; \
|
||||
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
//!
|
||||
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
}}} //namespace boost { namespace container { namespace containers_detail {
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_ADVANCED_INSERT_INT_HPP
|
||||
@@ -1,215 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/get_pointer.hpp>
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
||||
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
template<class T>
|
||||
struct has_own_construct_from_it
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
namespace containers_detail {
|
||||
|
||||
template<class T, class InpIt>
|
||||
inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::true_)
|
||||
{
|
||||
T::construct(dest, *source);
|
||||
}
|
||||
|
||||
template<class T, class InpIt>
|
||||
inline void construct_in_place_impl(T* dest, const InpIt &source, containers_detail::false_)
|
||||
{
|
||||
new((void*)dest)T(*source);
|
||||
}
|
||||
|
||||
} //namespace containers_detail {
|
||||
|
||||
template<class T, class InpIt>
|
||||
inline void construct_in_place(T* dest, InpIt source)
|
||||
{
|
||||
typedef containers_detail::bool_<has_own_construct_from_it<T>::value> boolean_t;
|
||||
containers_detail::construct_in_place_impl(dest, source, boolean_t());
|
||||
}
|
||||
|
||||
#else
|
||||
template<class T, class InpIt>
|
||||
inline void construct_in_place(T* dest, InpIt source)
|
||||
{ ::new((void*)dest)T(*source); }
|
||||
#endif
|
||||
|
||||
template<class T, class U, class D>
|
||||
inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
|
||||
{
|
||||
::new((void*)dest)T();
|
||||
}
|
||||
|
||||
template<class T, class U, class E>
|
||||
inline void construct_in_place(T *dest, emplace_iterator<U, E> ei)
|
||||
{
|
||||
ei.construct_in_place(dest);
|
||||
}
|
||||
|
||||
template<class InIt, class OutIt>
|
||||
struct optimize_assign
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct optimize_assign<const T*, T*>
|
||||
{
|
||||
static const bool value = boost::has_trivial_assign<T>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct optimize_assign<T*, T*>
|
||||
: public optimize_assign<const T*, T*>
|
||||
{};
|
||||
|
||||
template<class InIt, class OutIt>
|
||||
struct optimize_copy
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct optimize_copy<const T*, T*>
|
||||
{
|
||||
static const bool value = boost::has_trivial_copy<T>::value;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct optimize_copy<T*, T*>
|
||||
: public optimize_copy<const T*, T*>
|
||||
{};
|
||||
|
||||
template<class InIt, class OutIt> inline
|
||||
OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, containers_detail::bool_<false>)
|
||||
{
|
||||
for (; length--; ++dest, ++first)
|
||||
*dest = *first;
|
||||
return dest;
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
|
||||
{
|
||||
std::size_t size = length*sizeof(T);
|
||||
return (static_cast<T*>(std::memmove(dest, first, size))) + size;
|
||||
}
|
||||
|
||||
template<class InIt, class OutIt> inline
|
||||
OutIt copy_n(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest)
|
||||
{
|
||||
const bool do_optimized_assign = optimize_assign<InIt, OutIt>::value;
|
||||
return copy_n_dispatch(first, length, dest, containers_detail::bool_<do_optimized_assign>());
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt> inline
|
||||
FwdIt uninitialized_copy_n_dispatch
|
||||
(InIt first,
|
||||
typename std::iterator_traits<InIt>::difference_type count,
|
||||
FwdIt dest, containers_detail::bool_<false>)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
//Save initial destination position
|
||||
FwdIt dest_init = dest;
|
||||
typename std::iterator_traits<InIt>::difference_type new_count = count+1;
|
||||
|
||||
BOOST_TRY{
|
||||
//Try to build objects
|
||||
for (; --new_count; ++dest, ++first){
|
||||
construct_in_place(containers_detail::get_pointer(&*dest), first);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
//Call destructors
|
||||
new_count = count - new_count;
|
||||
for (; new_count--; ++dest_init){
|
||||
containers_detail::get_pointer(&*dest_init)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return dest;
|
||||
}
|
||||
template<class T> inline
|
||||
T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, containers_detail::bool_<true>)
|
||||
{
|
||||
std::size_t size = length*sizeof(T);
|
||||
return (static_cast<T*>(std::memmove(dest, first, size))) + size;
|
||||
}
|
||||
|
||||
template<class InIt, class FwdIt> inline
|
||||
FwdIt uninitialized_copy_n
|
||||
(InIt first,
|
||||
typename std::iterator_traits<InIt>::difference_type count,
|
||||
FwdIt dest)
|
||||
{
|
||||
const bool do_optimized_copy = optimize_copy<InIt, FwdIt>::value;
|
||||
return uninitialized_copy_n_dispatch(first, count, dest, containers_detail::bool_<do_optimized_copy>());
|
||||
}
|
||||
|
||||
// uninitialized_copy_copy
|
||||
// Copies [first1, last1) into [result, result + (last1 - first1)), and
|
||||
// copies [first2, last2) into
|
||||
// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
|
||||
template <class InpIt1, class InpIt2, class FwdIt>
|
||||
FwdIt uninitialized_copy_copy
|
||||
(InpIt1 first1, InpIt1 last1, InpIt2 first2, InpIt2 last2, FwdIt result)
|
||||
{
|
||||
typedef typename std::iterator_traits<FwdIt>::value_type value_type;
|
||||
FwdIt mid = std::uninitialized_copy(first1, last1, result);
|
||||
BOOST_TRY {
|
||||
return std::uninitialized_copy(first2, last2, mid);
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for(;result != mid; ++result){
|
||||
containers_detail::get_pointer(&*result)->~value_type();
|
||||
}
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
|
||||
#define BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
/// @cond
|
||||
enum allocation_type_v
|
||||
{
|
||||
// constants for allocation commands
|
||||
allocate_new_v = 0x01,
|
||||
expand_fwd_v = 0x02,
|
||||
expand_bwd_v = 0x04,
|
||||
// expand_both = expand_fwd | expand_bwd,
|
||||
// expand_or_new = allocate_new | expand_both,
|
||||
shrink_in_place_v = 0x08,
|
||||
nothrow_allocation_v = 0x10,
|
||||
zero_memory_v = 0x20,
|
||||
try_shrink_in_place_v = 0x40
|
||||
};
|
||||
|
||||
typedef int allocation_type;
|
||||
/// @endcond
|
||||
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
|
||||
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
|
||||
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
|
||||
static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v;
|
||||
static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
|
||||
static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
|
||||
static const allocation_type zero_memory = (allocation_type)zero_memory_v;
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //BOOST_CONTAINERS_ALLOCATION_TYPE_HPP
|
||||
@@ -1,145 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
|
||||
#define BOOST_CONTAINERS_CONTAINER_DETAIL_CONFIG_INCLUDED
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#define BOOST_CONTAINER_IN_INTERPROCESS
|
||||
#define BOOST_MOVE_IN_INTERPROCESS
|
||||
|
||||
#ifdef BOOST_MOVE_IN_INTERPROCESS
|
||||
|
||||
#define INCLUDE_BOOST_CONTAINER_MOVE_HPP <boost/interprocess/detail/move.hpp>
|
||||
#define BOOST_CONTAINER_MOVE_NAMESPACE boost::interprocess
|
||||
|
||||
#else
|
||||
|
||||
#define INCLUDE_BOOST_CONTAINER_MOVE_HPP <boost/move/move.hpp>
|
||||
#define BOOST_CONTAINER_MOVE_NAMESPACE boost
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_CONTAINER_IN_INTERPROCESS
|
||||
|
||||
#define INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP <boost/interprocess/containers/container/container_fwd.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DEQUE_HPP <boost/interprocess/containers/container/deque.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_FLAT_MAP_HPP <boost/interprocess/containers/container/flat_map.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_FLAT_SET_HPP <boost/interprocess/containers/container/flat_set.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_LIST_HPP <boost/interprocess/containers/container/list.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_MAP_HPP <boost/interprocess/containers/container/map.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_SET_HPP <boost/interprocess/containers/container/set.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_SLIST_HPP <boost/interprocess/containers/container/slist.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_STABLE_VECTOR_HPP <boost/interprocess/containers/container/stable_vector.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_STRING_HPP <boost/interprocess/containers/container/string.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_VECTOR_HPP <boost/interprocess/containers/container/vector.hpp>
|
||||
//detail
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP <boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ADVANCED_INSERT_INT_HPP <boost/interprocess/containers/container/detail/advanced_insert_int.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP <boost/interprocess/containers/container/detail/algorithms.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ALLOCATION_TYPE_HPP <boost/interprocess/containers/container/detail/allocation_type.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP <boost/interprocess/containers/container/detail/config_end.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_DESTROYERS_HPP <boost/interprocess/containers/container/detail/destroyers.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_FLAT_TREE_HPP <boost/interprocess/containers/container/detail/flat_tree.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ITERATORS_HPP <boost/interprocess/containers/container/detail/iterators.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP <boost/interprocess/containers/container/detail/math_functions.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP <boost/interprocess/containers/container/detail/mpl.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_NODE_ALLOC_HOLDER_HPP <boost/interprocess/containers/container/detail/node_alloc_holder.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP <boost/interprocess/containers/container/detail/node_pool_impl.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_PAIR_HPP <boost/interprocess/containers/container/detail/pair.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP <boost/interprocess/containers/container/detail/pool_common.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP <boost/interprocess/containers/container/detail/preprocessor.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATOR_HPP <boost/interprocess/containers/container/detail/transform_iterator.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_TREE_HPP <boost/interprocess/containers/container/detail/tree.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP <boost/interprocess/containers/container/detail/type_traits.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP <boost/interprocess/containers/container/detail/utilities.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP <boost/interprocess/containers/container/detail/value_init.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP <boost/interprocess/containers/container/detail/variadic_templates_tools.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP <boost/interprocess/containers/container/detail/stored_ref.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP <boost/interprocess/containers/container/detail/version_type.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP <boost/interprocess/containers/container/detail/workaround.hpp>
|
||||
|
||||
#else //BOOST_CONTAINER_IN_INTERPROCESS
|
||||
|
||||
#define INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP <boost/container/container_fwd.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DEQUE_HPP <boost/container/deque.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_FLAT_MAP_HPP <boost/container/flat_map.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_FLAT_SET_HPP <boost/container/flat_set.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_LIST_HPP <boost/container/list.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_MAP_HPP <boost/container/map.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_SET_HPP <boost/container/set.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_SLIST_HPP <boost/container/slist.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_STABLE_VECTOR_HPP <boost/container/stable_vector.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_STRING_HPP <boost/container/string.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_VECTOR_HPP <boost/container/vector.hpp>
|
||||
//detail
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP <boost/container/detail/adaptive_node_pool_impl.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ADVANCED_INSERT_INT_HPP <boost/container/detail/advanced_insert_int.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP <boost/container/detail/algorithms.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ALLOCATION_TYPE_HPP <boost/container/detail/allocation_type.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_BEGIN_HPP <boost/container/detail/config_begin.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP <boost/container/detail/config_end.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_DESTROYERS_HPP <boost/container/detail/destroyers.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_FLAT_TREE_HPP <boost/container/detail/flat_tree.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_ITERATORS_HPP <boost/container/detail/iterators.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP <boost/container/detail/math_functions.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP <boost/container/detail/mpl.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP <boost/container/detail/multiallocation_chain.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_NODE_ALLOC_HOLDER_HPP <boost/container/detail/node_alloc_holder.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP <boost/container/detail/node_pool_impl.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_PAIR_HPP <boost/container/detail/pair.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP <boost/container/detail/pool_common.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP <boost/container/detail/preprocessor.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATOR_HPP <boost/container/detail/transform_iterator.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_TREE_HPP <boost/container/detail/tree.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP <boost/container/detail/type_traits.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP <boost/container/detail/utilities.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP <boost/container/detail/value_init.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP <boost/container/detail/variadic_templates_tools.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP <boost/container/detail/version_type.hpp>
|
||||
#define INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP <boost/container/detail/workaround.hpp>
|
||||
|
||||
#endif //BOOST_CONTAINER_IN_INTERPROCESS
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4702) // unreachable code
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
||||
#pragma warning (disable : 4127) // conditional expression is constant
|
||||
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
#pragma warning (disable : 4284) // odd return type for operator->
|
||||
#pragma warning (disable : 4244) // possible loss of data
|
||||
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
|
||||
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
|
||||
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
|
||||
#pragma warning (disable : 4355) // "this" : used in base member initializer list
|
||||
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
|
||||
#pragma warning (disable : 4511) // copy constructor could not be generated
|
||||
#pragma warning (disable : 4512) // assignment operator could not be generated
|
||||
#pragma warning (disable : 4514) // unreferenced inline removed
|
||||
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
|
||||
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
|
||||
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
|
||||
#pragma warning (disable : 4710) // function not inlined
|
||||
#pragma warning (disable : 4711) // function selected for automatic inline expansion
|
||||
#pragma warning (disable : 4786) // identifier truncated in debug info
|
||||
#pragma warning (disable : 4996) // "function": was declared deprecated
|
||||
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
|
||||
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
|
||||
// with /GR-; unpredictable behavior may result
|
||||
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
|
||||
#pragma warning (disable : 4671) // the copy constructor is inaccessible
|
||||
#endif
|
||||
@@ -1,17 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#if defined BOOST_MSVC
|
||||
#pragma warning (pop)
|
||||
#ifdef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#undef BOOST_CONTAINERS_DETAIL_CRT_SECURE_NO_DEPRECATE
|
||||
#undef _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
|
||||
#define BOOST_CONTAINERS_DESTROYERS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an array of objects using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_array_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
|
||||
scoped_array_deallocator(pointer p, Allocator& a, size_type length)
|
||||
: m_ptr(p), m_alloc(a), m_length(length) {}
|
||||
|
||||
~scoped_array_deallocator()
|
||||
{ if (m_ptr) m_alloc.deallocate(m_ptr, m_length); }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
|
||||
private:
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
size_type m_length;
|
||||
};
|
||||
|
||||
template <class Allocator>
|
||||
struct null_scoped_array_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
|
||||
null_scoped_array_deallocator(pointer, Allocator&, size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_destructor_n
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef typename Allocator::value_type value_type;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
|
||||
pointer m_p;
|
||||
size_type m_n;
|
||||
|
||||
scoped_destructor_n(pointer p, size_type n)
|
||||
: m_p(p), m_n(n)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{ m_p = 0; }
|
||||
|
||||
void increment_size(size_type inc)
|
||||
{ m_n += inc; }
|
||||
|
||||
~scoped_destructor_n()
|
||||
{
|
||||
if(!m_p) return;
|
||||
value_type *raw_ptr = containers_detail::get_pointer(m_p);
|
||||
for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr)
|
||||
raw_ptr->~value_type();
|
||||
}
|
||||
};
|
||||
|
||||
//!A deleter for scoped_ptr that destroys
|
||||
//!an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct null_scoped_destructor_n
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
|
||||
null_scoped_destructor_n(pointer, size_type)
|
||||
{}
|
||||
|
||||
void increment_size(size_type)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_destroyer
|
||||
{
|
||||
typedef typename A::value_type value_type;
|
||||
typedef containers_detail::integral_constant<unsigned,
|
||||
boost::container::containers_detail::
|
||||
version<A>::value> alloc_version;
|
||||
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
|
||||
|
||||
private:
|
||||
A & a_;
|
||||
|
||||
private:
|
||||
void priv_deallocate(const typename A::pointer &p, allocator_v1)
|
||||
{ a_.deallocate(p, 1); }
|
||||
|
||||
void priv_deallocate(const typename A::pointer &p, allocator_v2)
|
||||
{ a_.deallocate_one(p); }
|
||||
|
||||
public:
|
||||
allocator_destroyer(A &a)
|
||||
: a_(a)
|
||||
{}
|
||||
|
||||
void operator()(const typename A::pointer &p)
|
||||
{
|
||||
containers_detail::get_pointer(p)->~value_type();
|
||||
priv_deallocate(p, alloc_version());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DESTROYERS_HPP
|
||||
@@ -1,875 +0,0 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The Loki Library
|
||||
// Copyright (c) 2001 by Andrei Alexandrescu
|
||||
// This code accompanies the book:
|
||||
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
|
||||
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
|
||||
// Permission to use, copy, modify, distribute and sell this software for any
|
||||
// purpose is hereby granted without fee, provided that the above copyright
|
||||
// notice appear in all copies and that both that copyright notice and this
|
||||
// permission notice appear in supporting documentation.
|
||||
// The author or Addison-Welsey Longman make no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parts of this file come from AssocVector.h file from Loki library
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_FLAT_TREE_HPP
|
||||
#define BOOST_CONTAINERS_FLAT_TREE_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_PAIR_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_VECTOR_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_DESTROYERS_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace container {
|
||||
|
||||
namespace containers_detail {
|
||||
|
||||
template<class Compare, class Value, class KeyOfValue>
|
||||
class flat_tree_value_compare
|
||||
: private Compare
|
||||
{
|
||||
typedef Value first_argument_type;
|
||||
typedef Value second_argument_type;
|
||||
typedef bool return_type;
|
||||
public:
|
||||
flat_tree_value_compare(const Compare &pred)
|
||||
: Compare(pred)
|
||||
{}
|
||||
|
||||
bool operator()(const Value& lhs, const Value& rhs) const
|
||||
{
|
||||
KeyOfValue key_extract;
|
||||
return Compare::operator()(key_extract(lhs), key_extract(rhs));
|
||||
}
|
||||
|
||||
const Compare &get_comp() const
|
||||
{ return *this; }
|
||||
|
||||
Compare &get_comp()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
template<class Pointer>
|
||||
struct get_flat_tree_iterators
|
||||
{
|
||||
typedef typename containers_detail::
|
||||
vector_iterator<Pointer> iterator;
|
||||
typedef typename containers_detail::
|
||||
vector_const_iterator<Pointer> const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
class flat_tree
|
||||
{
|
||||
typedef boost::container::vector<Value, Alloc> vector_t;
|
||||
typedef Alloc allocator_t;
|
||||
|
||||
public:
|
||||
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
|
||||
|
||||
private:
|
||||
struct Data
|
||||
//Inherit from value_compare to do EBO
|
||||
: public value_compare
|
||||
{
|
||||
private:
|
||||
BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(Data)
|
||||
public:
|
||||
Data(const Data &d)
|
||||
: value_compare(d), m_vect(d.m_vect)
|
||||
{}
|
||||
Data(const Compare &comp,
|
||||
const vector_t &vect)
|
||||
: value_compare(comp), m_vect(vect){}
|
||||
|
||||
Data(const value_compare &comp,
|
||||
const vector_t &vect)
|
||||
: value_compare(comp), m_vect(vect){}
|
||||
|
||||
Data(const Compare &comp,
|
||||
const allocator_t &alloc)
|
||||
: value_compare(comp), m_vect(alloc){}
|
||||
|
||||
Data& operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(Data) d)
|
||||
{
|
||||
this->value_compare::operator=(d);
|
||||
m_vect = d.m_vect;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data& operator=(BOOST_MOVE_MACRO_RV_REF(Data) d)
|
||||
{
|
||||
this->value_compare::operator=(BOOST_CONTAINER_MOVE_NAMESPACE::move(static_cast<value_compare &>(d)));
|
||||
m_vect = BOOST_CONTAINER_MOVE_NAMESPACE::move(d.m_vect);
|
||||
return *this;
|
||||
}
|
||||
|
||||
vector_t m_vect;
|
||||
};
|
||||
|
||||
Data m_data;
|
||||
BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(flat_tree)
|
||||
|
||||
public:
|
||||
|
||||
typedef typename vector_t::value_type value_type;
|
||||
typedef typename vector_t::pointer pointer;
|
||||
typedef typename vector_t::const_pointer const_pointer;
|
||||
typedef typename vector_t::reference reference;
|
||||
typedef typename vector_t::const_reference const_reference;
|
||||
typedef Key key_type;
|
||||
typedef Compare key_compare;
|
||||
typedef typename vector_t::allocator_type allocator_type;
|
||||
typedef allocator_type stored_allocator_type;
|
||||
typedef typename allocator_type::size_type size_type;
|
||||
typedef typename allocator_type::difference_type difference_type;
|
||||
typedef typename vector_t::iterator iterator;
|
||||
typedef typename vector_t::const_iterator const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
|
||||
// allocation/deallocation
|
||||
flat_tree(const Compare& comp = Compare(),
|
||||
const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{ }
|
||||
|
||||
flat_tree(const flat_tree& x)
|
||||
: m_data(x.m_data, x.m_data.m_vect)
|
||||
{ }
|
||||
|
||||
flat_tree(BOOST_MOVE_MACRO_RV_REF(flat_tree) x)
|
||||
: m_data(BOOST_CONTAINER_MOVE_NAMESPACE::move(x.m_data))
|
||||
{ }
|
||||
|
||||
template <class InputIterator>
|
||||
flat_tree( ordered_range_t, InputIterator first, InputIterator last
|
||||
, const Compare& comp = Compare()
|
||||
, const allocator_type& a = allocator_type())
|
||||
: m_data(comp, a)
|
||||
{ this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
|
||||
|
||||
~flat_tree()
|
||||
{ }
|
||||
|
||||
flat_tree& operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(flat_tree) x)
|
||||
{ m_data = x.m_data; return *this; }
|
||||
|
||||
flat_tree& operator=(BOOST_MOVE_MACRO_RV_REF(flat_tree) mx)
|
||||
{ m_data = BOOST_CONTAINER_MOVE_NAMESPACE::move(mx.m_data); return *this; }
|
||||
|
||||
public:
|
||||
// accessors:
|
||||
Compare key_comp() const
|
||||
{ return this->m_data.get_comp(); }
|
||||
|
||||
allocator_type get_allocator() const
|
||||
{ return this->m_data.m_vect.get_allocator(); }
|
||||
|
||||
const stored_allocator_type &get_stored_allocator() const
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
|
||||
stored_allocator_type &get_stored_allocator()
|
||||
{ return this->m_data.m_vect.get_stored_allocator(); }
|
||||
|
||||
iterator begin()
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
|
||||
const_iterator begin() const
|
||||
{ return this->cbegin(); }
|
||||
|
||||
const_iterator cbegin() const
|
||||
{ return this->m_data.m_vect.begin(); }
|
||||
|
||||
iterator end()
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
|
||||
const_iterator end() const
|
||||
{ return this->cend(); }
|
||||
|
||||
const_iterator cend() const
|
||||
{ return this->m_data.m_vect.end(); }
|
||||
|
||||
reverse_iterator rbegin()
|
||||
{ return reverse_iterator(this->end()); }
|
||||
|
||||
const_reverse_iterator rbegin() const
|
||||
{ return this->crbegin(); }
|
||||
|
||||
const_reverse_iterator crbegin() const
|
||||
{ return const_reverse_iterator(this->cend()); }
|
||||
|
||||
reverse_iterator rend()
|
||||
{ return reverse_iterator(this->begin()); }
|
||||
|
||||
const_reverse_iterator rend() const
|
||||
{ return this->crend(); }
|
||||
|
||||
const_reverse_iterator crend() const
|
||||
{ return const_reverse_iterator(this->cbegin()); }
|
||||
|
||||
bool empty() const
|
||||
{ return this->m_data.m_vect.empty(); }
|
||||
|
||||
size_type size() const
|
||||
{ return this->m_data.m_vect.size(); }
|
||||
|
||||
size_type max_size() const
|
||||
{ return this->m_data.m_vect.max_size(); }
|
||||
|
||||
void swap(flat_tree& other)
|
||||
{
|
||||
value_compare& mycomp = this->m_data;
|
||||
value_compare& othercomp = other.m_data;
|
||||
containers_detail::do_swap(mycomp, othercomp);
|
||||
vector_t & myvect = this->m_data.m_vect;
|
||||
vector_t & othervect = other.m_data.m_vect;
|
||||
myvect.swap(othervect);
|
||||
}
|
||||
|
||||
public:
|
||||
// insert/erase
|
||||
std::pair<iterator,bool> insert_unique(const value_type& val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, val);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> insert_unique(BOOST_MOVE_MACRO_RV_REF(value_type) val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
iterator insert_equal(const value_type& val)
|
||||
{
|
||||
iterator i = this->upper_bound(KeyOfValue()(val));
|
||||
i = this->m_data.m_vect.insert(i, val);
|
||||
return i;
|
||||
}
|
||||
|
||||
iterator insert_equal(BOOST_MOVE_MACRO_RV_REF(value_type) mval)
|
||||
{
|
||||
iterator i = this->upper_bound(KeyOfValue()(mval));
|
||||
i = this->m_data.m_vect.insert(i, BOOST_CONTAINER_MOVE_NAMESPACE::move(mval));
|
||||
return i;
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator pos, const value_type& val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, val);
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator pos, BOOST_MOVE_MACRO_RV_REF(value_type) mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(mval));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, const value_type& val)
|
||||
{
|
||||
insert_commit_data data;
|
||||
priv_insert_equal_prepare(pos, val, data);
|
||||
return priv_insert_commit(data, val);
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, BOOST_MOVE_MACRO_RV_REF(value_type) mval)
|
||||
{
|
||||
insert_commit_data data;
|
||||
priv_insert_equal_prepare(pos, mval, data);
|
||||
return priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(mval));
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void insert_unique(InIt first, InIt last)
|
||||
{
|
||||
for ( ; first != last; ++first)
|
||||
this->insert_unique(*first);
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void insert_equal(InIt first, InIt last)
|
||||
{
|
||||
typedef typename
|
||||
std::iterator_traits<InIt>::iterator_category ItCat;
|
||||
priv_insert_equal(first, last, ItCat());
|
||||
}
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_unique(Args&&... args)
|
||||
{
|
||||
value_type && val = value_type(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...);
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint_unique(const_iterator hint, Args&&... args)
|
||||
{
|
||||
value_type && val = value_type(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...);
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_equal(Args&&... args)
|
||||
{
|
||||
value_type &&val = value_type(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...);
|
||||
iterator i = this->upper_bound(KeyOfValue()(val));
|
||||
i = this->m_data.m_vect.insert(i, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
return i;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
|
||||
{
|
||||
value_type &&val = value_type(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...);
|
||||
insert_commit_data data;
|
||||
priv_insert_equal_prepare(hint, val, data);
|
||||
return priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
|
||||
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
iterator emplace_unique()
|
||||
{
|
||||
containers_detail::value_init<value_type> vval;
|
||||
value_type &val = vval.m_t;
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
priv_insert_unique_prepare(val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
iterator emplace_hint_unique(const_iterator hint)
|
||||
{
|
||||
containers_detail::value_init<value_type> vval;
|
||||
value_type &val = vval.m_t;
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
|
||||
if(ret.second){
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
return ret.first;
|
||||
}
|
||||
|
||||
iterator emplace_equal()
|
||||
{
|
||||
containers_detail::value_init<value_type> vval;
|
||||
value_type &val = vval.m_t;
|
||||
iterator i = this->upper_bound(KeyOfValue()(val));
|
||||
i = this->m_data.m_vect.insert(i, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
return i;
|
||||
}
|
||||
|
||||
iterator emplace_hint_equal(const_iterator hint)
|
||||
{
|
||||
containers_detail::value_init<value_type> vval;
|
||||
value_type &val = vval.m_t;
|
||||
insert_commit_data data;
|
||||
priv_insert_equal_prepare(hint, val, data);
|
||||
return priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val));
|
||||
}
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
insert_commit_data data; \
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
|
||||
if(ret.second){ \
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val)); \
|
||||
} \
|
||||
return ret.first; \
|
||||
} \
|
||||
\
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
iterator emplace_hint_unique(const_iterator hint, \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
insert_commit_data data; \
|
||||
std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
|
||||
if(ret.second){ \
|
||||
ret.first = priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val)); \
|
||||
} \
|
||||
return ret.first; \
|
||||
} \
|
||||
\
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
iterator i = this->upper_bound(KeyOfValue()(val)); \
|
||||
i = this->m_data.m_vect.insert(i, BOOST_CONTAINER_MOVE_NAMESPACE::move(val)); \
|
||||
return i; \
|
||||
} \
|
||||
\
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
iterator emplace_hint_equal(const_iterator hint, \
|
||||
BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
value_type val(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
insert_commit_data data; \
|
||||
priv_insert_equal_prepare(hint, val, data); \
|
||||
return priv_insert_commit(data, BOOST_CONTAINER_MOVE_NAMESPACE::move(val)); \
|
||||
} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{ return this->m_data.m_vect.erase(position); }
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{
|
||||
std::pair<iterator,iterator > itp = this->equal_range(k);
|
||||
size_type ret = static_cast<size_type>(itp.second-itp.first);
|
||||
if (ret){
|
||||
this->m_data.m_vect.erase(itp.first, itp.second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{ return this->m_data.m_vect.erase(first, last); }
|
||||
|
||||
void clear()
|
||||
{ this->m_data.m_vect.clear(); }
|
||||
|
||||
//! <b>Effects</b>: Tries to deallocate the excess of memory created
|
||||
// with previous allocations. The size of the vector is unchanged
|
||||
//!
|
||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to size().
|
||||
void shrink_to_fit()
|
||||
{ this->m_data.m_vect.shrink_to_fit(); }
|
||||
|
||||
// set operations:
|
||||
iterator find(const key_type& k)
|
||||
{
|
||||
const Compare &key_comp = this->m_data.get_comp();
|
||||
iterator i = this->lower_bound(k);
|
||||
|
||||
if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
|
||||
i = this->end();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
const_iterator find(const key_type& k) const
|
||||
{
|
||||
const Compare &key_comp = this->m_data.get_comp();
|
||||
const_iterator i = this->lower_bound(k);
|
||||
|
||||
if (i != this->end() && key_comp(k, KeyOfValue()(*i))){
|
||||
i = this->end();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
std::pair<const_iterator, const_iterator> p = this->equal_range(k);
|
||||
size_type n = p.second - p.first;
|
||||
return n;
|
||||
}
|
||||
|
||||
iterator lower_bound(const key_type& k)
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator lower_bound(const key_type& k) const
|
||||
{ return this->priv_lower_bound(this->begin(), this->end(), k); }
|
||||
|
||||
iterator upper_bound(const key_type& k)
|
||||
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
|
||||
|
||||
const_iterator upper_bound(const key_type& k) const
|
||||
{ return this->priv_upper_bound(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<iterator,iterator> equal_range(const key_type& k)
|
||||
{ return this->priv_equal_range(this->begin(), this->end(), k); }
|
||||
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
|
||||
{ return this->priv_equal_range(this->begin(), this->end(), k); }
|
||||
|
||||
size_type capacity() const
|
||||
{ return this->m_data.m_vect.capacity(); }
|
||||
|
||||
void reserve(size_type count)
|
||||
{ this->m_data.m_vect.reserve(count); }
|
||||
|
||||
private:
|
||||
struct insert_commit_data
|
||||
{
|
||||
const_iterator position;
|
||||
};
|
||||
|
||||
// insert/erase
|
||||
void priv_insert_equal_prepare
|
||||
(const_iterator pos, const value_type& val, insert_commit_data &data)
|
||||
{
|
||||
// N1780
|
||||
// To insert val at pos:
|
||||
// if pos == end || val <= *pos
|
||||
// if pos == begin || val >= *(pos-1)
|
||||
// insert val before pos
|
||||
// else
|
||||
// insert val before upper_bound(val)
|
||||
// else if pos+1 == end || val <= *(pos+1)
|
||||
// insert val after pos
|
||||
// else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &value_comp = this->m_data;
|
||||
|
||||
if(pos == this->cend() || !value_comp(*pos, val)){
|
||||
if (pos == this->cbegin() || !value_comp(val, pos[-1])){
|
||||
data.position = pos;
|
||||
}
|
||||
else{
|
||||
data.position =
|
||||
this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
|
||||
}
|
||||
}
|
||||
//Works, but increases code complexity
|
||||
//else if (++pos == this->end() || !value_comp(*pos, val)){
|
||||
// return this->m_data.m_vect.insert(pos, val);
|
||||
//}
|
||||
else{
|
||||
data.position =
|
||||
this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> priv_insert_unique_prepare
|
||||
(const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
|
||||
{
|
||||
const value_compare &value_comp = this->m_data;
|
||||
commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
|
||||
return std::pair<iterator,bool>
|
||||
( *reinterpret_cast<iterator*>(&commit_data.position)
|
||||
, commit_data.position == end || value_comp(val, *commit_data.position));
|
||||
}
|
||||
|
||||
std::pair<iterator,bool> priv_insert_unique_prepare
|
||||
(const value_type& val, insert_commit_data &commit_data)
|
||||
{ return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
|
||||
|
||||
std::pair<iterator,bool> priv_insert_unique_prepare
|
||||
(const_iterator pos, const value_type& val, insert_commit_data &commit_data)
|
||||
{
|
||||
//N1780. Props to Howard Hinnant!
|
||||
//To insert val at pos:
|
||||
//if pos == end || val <= *pos
|
||||
// if pos == begin || val >= *(pos-1)
|
||||
// insert val before pos
|
||||
// else
|
||||
// insert val before upper_bound(val)
|
||||
//else if pos+1 == end || val <= *(pos+1)
|
||||
// insert val after pos
|
||||
//else
|
||||
// insert val before lower_bound(val)
|
||||
const value_compare &value_comp = this->m_data;
|
||||
|
||||
if(pos == this->cend() || value_comp(val, *pos)){
|
||||
if(pos != this->cbegin() && !value_comp(val, pos[-1])){
|
||||
if(value_comp(pos[-1], val)){
|
||||
commit_data.position = pos;
|
||||
return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
|
||||
}
|
||||
else{
|
||||
return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
|
||||
}
|
||||
}
|
||||
return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
|
||||
}
|
||||
|
||||
// Works, but increases code complexity
|
||||
//Next check
|
||||
//else if (value_comp(*pos, val) && !value_comp(pos[1], val)){
|
||||
// if(value_comp(val, pos[1])){
|
||||
// commit_data.position = pos+1;
|
||||
// return std::pair<iterator,bool>(pos+1, true);
|
||||
// }
|
||||
// else{
|
||||
// return std::pair<iterator,bool>(pos+1, false);
|
||||
// }
|
||||
//}
|
||||
else{
|
||||
//[... pos ... val ... ]
|
||||
//The hint is before the insertion position, so insert it
|
||||
//in the remaining range
|
||||
return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Convertible>
|
||||
iterator priv_insert_commit
|
||||
(insert_commit_data &commit_data, BOOST_MOVE_MACRO_FWD_REF(Convertible) convertible)
|
||||
{
|
||||
return this->m_data.m_vect.insert
|
||||
( commit_data.position
|
||||
, BOOST_CONTAINER_MOVE_NAMESPACE::forward<Convertible>(convertible));
|
||||
}
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_lower_bound(RanIt first, RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_comp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
difference_type len = last - first, half;
|
||||
RanIt middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
|
||||
if (key_comp(key_extract(*middle), key)) {
|
||||
++middle;
|
||||
first = middle;
|
||||
len = len - half - 1;
|
||||
}
|
||||
else
|
||||
len = half;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class RanIt>
|
||||
RanIt priv_upper_bound(RanIt first, RanIt last,
|
||||
const key_type & key) const
|
||||
{
|
||||
const Compare &key_comp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
difference_type len = last - first, half;
|
||||
RanIt middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
|
||||
if (key_comp(key, key_extract(*middle))) {
|
||||
len = half;
|
||||
}
|
||||
else{
|
||||
first = ++middle;
|
||||
len = len - half - 1;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class RanIt>
|
||||
std::pair<RanIt, RanIt>
|
||||
priv_equal_range(RanIt first, RanIt last, const key_type& key) const
|
||||
{
|
||||
const Compare &key_comp = this->m_data.get_comp();
|
||||
KeyOfValue key_extract;
|
||||
difference_type len = last - first, half;
|
||||
RanIt middle, left, right;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
middle += half;
|
||||
|
||||
if (key_comp(key_extract(*middle), key)){
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
else if (key_comp(key, key_extract(*middle))){
|
||||
len = half;
|
||||
}
|
||||
else {
|
||||
left = this->priv_lower_bound(first, middle, key);
|
||||
first += len;
|
||||
right = this->priv_upper_bound(++middle, first, key);
|
||||
return std::pair<RanIt, RanIt>(left, right);
|
||||
}
|
||||
}
|
||||
return std::pair<RanIt, RanIt>(first, first);
|
||||
}
|
||||
|
||||
template <class FwdIt>
|
||||
void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
|
||||
{
|
||||
size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
this->reserve(this->size()+len);
|
||||
this->priv_insert_equal(first, last, std::input_iterator_tag());
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
|
||||
{
|
||||
for ( ; first != last; ++first)
|
||||
this->insert_equal(*first);
|
||||
}
|
||||
|
||||
/*
|
||||
template <class FwdIt>
|
||||
void priv_insert_unique(FwdIt first, FwdIt last, std::forward_iterator_tag)
|
||||
{
|
||||
size_type len = static_cast<size_type>(std::distance(first, last));
|
||||
this->reserve(this->size()+len);
|
||||
priv_insert_unique(first, last, std::input_iterator_tag());
|
||||
}
|
||||
|
||||
template <class InIt>
|
||||
void priv_insert_unique(InIt first, InIt last, std::input_iterator_tag)
|
||||
{
|
||||
for ( ; first != last; ++first)
|
||||
this->insert_unique(*first);
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline bool
|
||||
operator==(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{
|
||||
return x.size() == y.size() &&
|
||||
std::equal(x.begin(), x.end(), y.begin());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline bool
|
||||
operator<(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{
|
||||
return std::lexicographical_compare(x.begin(), x.end(),
|
||||
y.begin(), y.end());
|
||||
}
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline bool
|
||||
operator!=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline bool
|
||||
operator>(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline bool
|
||||
operator<=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{ return !(y < x); }
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline bool
|
||||
operator>=(const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
const flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{ return !(x < y); }
|
||||
|
||||
|
||||
template <class Key, class Value, class KeyOfValue,
|
||||
class Compare, class Alloc>
|
||||
inline void
|
||||
swap(flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& x,
|
||||
flat_tree<Key,Value,KeyOfValue,Compare,Alloc>& y)
|
||||
{ x.swap(y); }
|
||||
|
||||
} //namespace containers_detail {
|
||||
|
||||
} //namespace container {
|
||||
/*
|
||||
//!has_trivial_destructor_after_move<> == true_type
|
||||
//!specialization for optimizations
|
||||
template <class K, class V, class KOV,
|
||||
class C, class A>
|
||||
struct has_trivial_destructor_after_move<boost::container::containers_detail::flat_tree<K, V, KOV, C, A> >
|
||||
{
|
||||
static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
|
||||
};
|
||||
*/
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif // BOOST_CONTAINERS_FLAT_TREE_HPP
|
||||
@@ -1,545 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP
|
||||
#else
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
|
||||
#endif
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class constant_iterator
|
||||
: public std::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef constant_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit constant_iterator(const T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
constant_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
constant_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
constant_iterator operator++(int)
|
||||
{
|
||||
constant_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
constant_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
constant_iterator operator--(int)
|
||||
{
|
||||
constant_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
constant_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
constant_iterator operator+(Difference off) const
|
||||
{
|
||||
constant_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend constant_iterator operator+(Difference off, const constant_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
constant_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
constant_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
const T& operator[] (Difference n) const
|
||||
{ return dereference(); }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
private:
|
||||
const T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class default_construct_iterator
|
||||
: public std::iterator
|
||||
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
||||
{
|
||||
typedef default_construct_iterator<T, Difference> this_type;
|
||||
|
||||
public:
|
||||
explicit default_construct_iterator(Difference range_size)
|
||||
: m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
default_construct_iterator()
|
||||
: m_num(0){}
|
||||
|
||||
default_construct_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
default_construct_iterator operator++(int)
|
||||
{
|
||||
default_construct_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
default_construct_iterator& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
default_construct_iterator operator--(int)
|
||||
{
|
||||
default_construct_iterator result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
default_construct_iterator& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
default_construct_iterator operator+(Difference off) const
|
||||
{
|
||||
default_construct_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
default_construct_iterator& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
default_construct_iterator operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
const T& operator[] (Difference n) const
|
||||
{ return dereference(); }
|
||||
|
||||
private:
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class Difference = std::ptrdiff_t>
|
||||
class repeat_iterator
|
||||
: public std::iterator
|
||||
<std::random_access_iterator_tag, T, Difference>
|
||||
{
|
||||
typedef repeat_iterator<T, Difference> this_type;
|
||||
public:
|
||||
explicit repeat_iterator(T &ref, Difference range_size)
|
||||
: m_ptr(&ref), m_num(range_size){}
|
||||
|
||||
//Constructors
|
||||
repeat_iterator()
|
||||
: m_ptr(0), m_num(0){}
|
||||
|
||||
this_type& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator++(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
this_type& operator--()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator--(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const this_type& i, const this_type& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const this_type& i, const this_type& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const this_type& i, const this_type& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const this_type& i, const this_type& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const this_type& i, const this_type& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const this_type& i, const this_type& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend Difference operator- (const this_type& i, const this_type& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
this_type& operator+=(Difference off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
this_type operator+(Difference off) const
|
||||
{
|
||||
this_type other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend this_type operator+(Difference off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
this_type& operator-=(Difference off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
this_type operator-(Difference off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
T& operator[] (Difference n) const
|
||||
{ return dereference(); }
|
||||
|
||||
T *operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
Difference m_num;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
T & dereference() const
|
||||
{ return *m_ptr; }
|
||||
|
||||
void advance(Difference n)
|
||||
{ m_num -= n; }
|
||||
|
||||
Difference distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
template <class T, class E>
|
||||
class emplace_iterator
|
||||
: public std::iterator
|
||||
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
|
||||
{
|
||||
typedef emplace_iterator this_type;
|
||||
|
||||
public:
|
||||
explicit emplace_iterator(E&e)
|
||||
: m_num(1), m_pe(&e){}
|
||||
|
||||
emplace_iterator()
|
||||
: m_num(0), m_pe(0){}
|
||||
|
||||
this_type& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
this_type operator++(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
this_type& operator--()
|
||||
{ decrement(); return *this; }
|
||||
|
||||
this_type operator--(int)
|
||||
{
|
||||
this_type result (*this);
|
||||
decrement();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const this_type& i, const this_type& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const this_type& i, const this_type& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
friend bool operator< (const this_type& i, const this_type& i2)
|
||||
{ return i.less(i2); }
|
||||
|
||||
friend bool operator> (const this_type& i, const this_type& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const this_type& i, const this_type& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const this_type& i, const this_type& i2)
|
||||
{ return !(i < i2); }
|
||||
|
||||
friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
this_type& operator+=(std::ptrdiff_t off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
this_type operator+(std::ptrdiff_t off) const
|
||||
{
|
||||
this_type other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend this_type operator+(std::ptrdiff_t off, const this_type& right)
|
||||
{ return right + off; }
|
||||
|
||||
this_type& operator-=(std::ptrdiff_t off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
this_type operator-(std::ptrdiff_t off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
const T& operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
const T& operator[](std::ptrdiff_t) const
|
||||
{ return dereference(); }
|
||||
|
||||
const T* operator->() const
|
||||
{ return &(dereference()); }
|
||||
|
||||
void construct_in_place(T* ptr)
|
||||
{ (*m_pe)(ptr); }
|
||||
|
||||
private:
|
||||
std::ptrdiff_t m_num;
|
||||
E * m_pe;
|
||||
|
||||
void increment()
|
||||
{ --m_num; }
|
||||
|
||||
void decrement()
|
||||
{ ++m_num; }
|
||||
|
||||
bool equal(const this_type &other) const
|
||||
{ return m_num == other.m_num; }
|
||||
|
||||
bool less(const this_type &other) const
|
||||
{ return other.m_num < m_num; }
|
||||
|
||||
const T & dereference() const
|
||||
{
|
||||
static T dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void advance(std::ptrdiff_t n)
|
||||
{ m_num -= n; }
|
||||
|
||||
std::ptrdiff_t distance_to(const this_type &other)const
|
||||
{ return m_num - other.m_num; }
|
||||
};
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
template<class T, class ...Args>
|
||||
struct emplace_functor
|
||||
{
|
||||
typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
emplace_functor(Args&&... args)
|
||||
: args_(args...)
|
||||
{}
|
||||
|
||||
void operator()(T *ptr)
|
||||
{ emplace_functor::inplace_impl(ptr, index_tuple_t()); }
|
||||
|
||||
template<int ...IdxPack>
|
||||
void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
|
||||
{ ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); }
|
||||
|
||||
containers_detail::tuple<Args&...> args_;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T>
|
||||
struct emplace_functor
|
||||
{
|
||||
emplace_functor()
|
||||
{}
|
||||
void operator()(T *ptr)
|
||||
{ new(ptr) T(); }
|
||||
};
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
{ \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
||||
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \
|
||||
: BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \
|
||||
\
|
||||
void operator()(T *ptr) \
|
||||
{ \
|
||||
new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \
|
||||
} \
|
||||
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
// This file is a slightly modified file from Boost.Pool
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
// Greatest common divisor and least common multiple
|
||||
|
||||
//
|
||||
// gcd is an algorithm that calculates the greatest common divisor of two
|
||||
// integers, using Euclid's algorithm.
|
||||
//
|
||||
// Pre: A > 0 && B > 0
|
||||
// Recommended: A > B
|
||||
template <typename Integer>
|
||||
inline Integer gcd(Integer A, Integer B)
|
||||
{
|
||||
do
|
||||
{
|
||||
const Integer tmp(B);
|
||||
B = A % B;
|
||||
A = tmp;
|
||||
} while (B != 0);
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
//
|
||||
// lcm is an algorithm that calculates the least common multiple of two
|
||||
// integers.
|
||||
//
|
||||
// Pre: A > 0 && B > 0
|
||||
// Recommended: A > B
|
||||
template <typename Integer>
|
||||
inline Integer lcm(const Integer & A, const Integer & B)
|
||||
{
|
||||
Integer ret = A;
|
||||
ret /= gcd(A, B);
|
||||
ret *= B;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline Integer log2_ceil(const Integer & A)
|
||||
{
|
||||
Integer i = 0;
|
||||
Integer power_of_2 = 1;
|
||||
|
||||
while(power_of_2 < A){
|
||||
power_of_2 <<= 1;
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline Integer upper_power_of_2(const Integer & A)
|
||||
{
|
||||
Integer power_of_2 = 1;
|
||||
|
||||
while(power_of_2 < A){
|
||||
power_of_2 <<= 1;
|
||||
}
|
||||
return power_of_2;
|
||||
}
|
||||
|
||||
//This function uses binary search to discover the
|
||||
//highest set bit of the integer
|
||||
inline std::size_t floor_log2 (std::size_t x)
|
||||
{
|
||||
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
|
||||
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
|
||||
BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
|
||||
|
||||
std::size_t n = x;
|
||||
std::size_t log2 = 0;
|
||||
|
||||
for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
|
||||
std::size_t tmp = n >> shift;
|
||||
if (tmp)
|
||||
log2 += shift, n = tmp;
|
||||
}
|
||||
|
||||
return log2;
|
||||
}
|
||||
|
||||
} // namespace containers_detail
|
||||
} // namespace container
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -1,152 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
|
||||
#define BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template <class T, T val>
|
||||
struct integral_constant
|
||||
{
|
||||
static const T value = val;
|
||||
typedef integral_constant<T,val> type;
|
||||
};
|
||||
|
||||
template< bool C_ >
|
||||
struct bool_ : integral_constant<bool, C_>
|
||||
{
|
||||
static const bool value = C_;
|
||||
};
|
||||
|
||||
typedef bool_<true> true_;
|
||||
typedef bool_<false> false_;
|
||||
|
||||
typedef true_ true_type;
|
||||
typedef false_ false_type;
|
||||
|
||||
typedef char yes_type;
|
||||
struct no_type
|
||||
{
|
||||
char padding[8];
|
||||
};
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct enable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct disable_if : public enable_if_c<!Cond::value, T> {};
|
||||
|
||||
template <class T, class U>
|
||||
class is_convertible
|
||||
{
|
||||
typedef char true_t;
|
||||
class false_t { char dummy[2]; };
|
||||
static true_t dispatch(U);
|
||||
static false_t dispatch(...);
|
||||
static T trigger();
|
||||
public:
|
||||
enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
|
||||
};
|
||||
|
||||
template<
|
||||
bool C
|
||||
, typename T1
|
||||
, typename T2
|
||||
>
|
||||
struct if_c
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename T1
|
||||
, typename T2
|
||||
>
|
||||
struct if_c<false,T1,T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
template<
|
||||
typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
>
|
||||
struct if_
|
||||
{
|
||||
typedef typename if_c<0 != T1::value, T2, T3>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <class Pair>
|
||||
struct select1st
|
||||
// : public std::unary_function<Pair, typename Pair::first_type>
|
||||
{
|
||||
template<class OtherPair>
|
||||
const typename Pair::first_type& operator()(const OtherPair& x) const
|
||||
{ return x.first; }
|
||||
|
||||
const typename Pair::first_type& operator()(const typename Pair::first_type& x) const
|
||||
{ return x; }
|
||||
};
|
||||
|
||||
// identity is an extension: it is not part of the standard.
|
||||
template <class T>
|
||||
struct identity
|
||||
// : public std::unary_function<T,T>
|
||||
{
|
||||
typedef T type;
|
||||
const T& operator()(const T& x) const
|
||||
{ return x; }
|
||||
};
|
||||
|
||||
template<std::size_t S>
|
||||
struct ls_zeros
|
||||
{
|
||||
static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ls_zeros<0>
|
||||
{
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ls_zeros<1>
|
||||
{
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATOR_HPP
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template<class VoidPointer>
|
||||
class basic_multiallocation_chain
|
||||
{
|
||||
private:
|
||||
typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
|
||||
,bi::link_mode<bi::normal_link>
|
||||
> node;
|
||||
|
||||
typedef bi::slist< node
|
||||
, bi::linear<true>
|
||||
, bi::cache_last<true>
|
||||
> slist_impl_t;
|
||||
slist_impl_t slist_impl_;
|
||||
|
||||
static node & to_node(VoidPointer p)
|
||||
{ return *static_cast<node*>(static_cast<void*>(containers_detail::get_pointer(p))); }
|
||||
|
||||
BOOST_MOVE_MACRO_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
|
||||
|
||||
public:
|
||||
|
||||
|
||||
typedef VoidPointer void_pointer;
|
||||
typedef typename slist_impl_t::iterator iterator;
|
||||
|
||||
basic_multiallocation_chain()
|
||||
: slist_impl_()
|
||||
{}
|
||||
|
||||
basic_multiallocation_chain(BOOST_MOVE_MACRO_RV_REF(basic_multiallocation_chain) other)
|
||||
: slist_impl_()
|
||||
{ slist_impl_.swap(other.slist_impl_); }
|
||||
|
||||
basic_multiallocation_chain& operator=(BOOST_MOVE_MACRO_RV_REF(basic_multiallocation_chain) other)
|
||||
{
|
||||
basic_multiallocation_chain tmp(BOOST_CONTAINER_MOVE_NAMESPACE::move(other));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{ return slist_impl_.empty(); }
|
||||
|
||||
std::size_t size() const
|
||||
{ return slist_impl_.size(); }
|
||||
|
||||
iterator before_begin()
|
||||
{ return slist_impl_.before_begin(); }
|
||||
|
||||
iterator begin()
|
||||
{ return slist_impl_.begin(); }
|
||||
|
||||
iterator end()
|
||||
{ return slist_impl_.end(); }
|
||||
|
||||
iterator last()
|
||||
{ return slist_impl_.last(); }
|
||||
|
||||
void clear()
|
||||
{ slist_impl_.clear(); }
|
||||
|
||||
iterator insert_after(iterator it, void_pointer m)
|
||||
{ return slist_impl_.insert_after(it, to_node(m)); }
|
||||
|
||||
void push_front(void_pointer m)
|
||||
{ return slist_impl_.push_front(to_node(m)); }
|
||||
|
||||
void push_back(void_pointer m)
|
||||
{ return slist_impl_.push_back(to_node(m)); }
|
||||
|
||||
void pop_front()
|
||||
{ return slist_impl_.pop_front(); }
|
||||
|
||||
void *front()
|
||||
{ return &*slist_impl_.begin(); }
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); }
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end, n); }
|
||||
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x)
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
|
||||
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end)); }
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, std::size_t n)
|
||||
{ slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n); }
|
||||
|
||||
void swap(basic_multiallocation_chain &x)
|
||||
{ slist_impl_.swap(x.slist_impl_); }
|
||||
|
||||
static iterator iterator_to(void_pointer p)
|
||||
{ return slist_impl_t::s_iterator_to(to_node(p)); }
|
||||
|
||||
std::pair<void_pointer, void_pointer> extract_data()
|
||||
{
|
||||
std::pair<void_pointer, void_pointer> ret
|
||||
(slist_impl_.begin().operator->()
|
||||
,slist_impl_.last().operator->());
|
||||
slist_impl_.clear();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct cast_functor
|
||||
{
|
||||
typedef typename containers_detail::add_reference<T>::type result_type;
|
||||
template<class U>
|
||||
result_type operator()(U &ptr) const
|
||||
{ return *static_cast<T*>(static_cast<void*>(&ptr)); }
|
||||
};
|
||||
|
||||
template<class MultiallocationChain, class T>
|
||||
class transform_multiallocation_chain
|
||||
{
|
||||
private:
|
||||
BOOST_MOVE_MACRO_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
|
||||
|
||||
MultiallocationChain holder_;
|
||||
typedef typename MultiallocationChain::void_pointer void_pointer;
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_pointer, T>::type pointer;
|
||||
|
||||
static pointer cast(void_pointer p)
|
||||
{
|
||||
return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
|
||||
}
|
||||
|
||||
public:
|
||||
typedef transform_iterator
|
||||
< typename MultiallocationChain::iterator
|
||||
, containers_detail::cast_functor <T> > iterator;
|
||||
|
||||
transform_multiallocation_chain()
|
||||
: holder_()
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain(BOOST_MOVE_MACRO_RV_REF(transform_multiallocation_chain) other)
|
||||
: holder_()
|
||||
{ this->swap(other); }
|
||||
|
||||
transform_multiallocation_chain(BOOST_MOVE_MACRO_RV_REF(MultiallocationChain) other)
|
||||
: holder_(BOOST_CONTAINER_MOVE_NAMESPACE::move(other))
|
||||
{}
|
||||
|
||||
transform_multiallocation_chain& operator=(BOOST_MOVE_MACRO_RV_REF(transform_multiallocation_chain) other)
|
||||
{
|
||||
transform_multiallocation_chain tmp(BOOST_CONTAINER_MOVE_NAMESPACE::move(other));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void push_front(pointer mem)
|
||||
{ holder_.push_front(mem); }
|
||||
|
||||
void swap(transform_multiallocation_chain &other_chain)
|
||||
{ holder_.swap(other_chain.holder_); }
|
||||
|
||||
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
|
||||
{ holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
|
||||
|
||||
void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, std::size_t n)
|
||||
{ holder_.incorporate_after(after_this.base(), begin, before_end, n); }
|
||||
|
||||
void pop_front()
|
||||
{ holder_.pop_front(); }
|
||||
|
||||
pointer front()
|
||||
{ return cast(holder_.front()); }
|
||||
|
||||
bool empty() const
|
||||
{ return holder_.empty(); }
|
||||
|
||||
iterator before_begin()
|
||||
{ return iterator(holder_.before_begin()); }
|
||||
|
||||
iterator begin()
|
||||
{ return iterator(holder_.begin()); }
|
||||
|
||||
iterator end()
|
||||
{ return iterator(holder_.end()); }
|
||||
|
||||
iterator last()
|
||||
{ return iterator(holder_.last()); }
|
||||
|
||||
std::size_t size() const
|
||||
{ return holder_.size(); }
|
||||
|
||||
void clear()
|
||||
{ holder_.clear(); }
|
||||
|
||||
iterator insert_after(iterator it, pointer m)
|
||||
{ return iterator(holder_.insert_after(it.base(), m)); }
|
||||
|
||||
static iterator iterator_to(pointer p)
|
||||
{ return iterator(MultiallocationChain::iterator_to(p)); }
|
||||
|
||||
std::pair<void_pointer, void_pointer> extract_data()
|
||||
{ return holder_.extract_data(); }
|
||||
|
||||
MultiallocationChain extract_multiallocation_chain()
|
||||
{
|
||||
return MultiallocationChain(BOOST_CONTAINER_MOVE_NAMESPACE::move(holder_));
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
// namespace containers_detail {
|
||||
// namespace container {
|
||||
// namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
||||
@@ -1,501 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
|
||||
#define BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
#include <boost/intrusive/options.hpp>
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_DESTROYERS_HPP
|
||||
|
||||
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
|
||||
#endif
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
||||
//!allocated for an object using a STL allocator.
|
||||
template <class Allocator>
|
||||
struct scoped_deallocator
|
||||
{
|
||||
typedef typename Allocator::pointer pointer;
|
||||
typedef containers_detail::integral_constant<unsigned,
|
||||
boost::container::containers_detail::
|
||||
version<Allocator>::value> alloc_version;
|
||||
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
|
||||
|
||||
private:
|
||||
void priv_deallocate(allocator_v1)
|
||||
{ m_alloc.deallocate(m_ptr, 1); }
|
||||
|
||||
void priv_deallocate(allocator_v2)
|
||||
{ m_alloc.deallocate_one(m_ptr); }
|
||||
|
||||
BOOST_MOVE_MACRO_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
|
||||
|
||||
public:
|
||||
|
||||
pointer m_ptr;
|
||||
Allocator& m_alloc;
|
||||
|
||||
scoped_deallocator(pointer p, Allocator& a)
|
||||
: m_ptr(p), m_alloc(a)
|
||||
{}
|
||||
|
||||
~scoped_deallocator()
|
||||
{ if (m_ptr)priv_deallocate(alloc_version()); }
|
||||
|
||||
scoped_deallocator(BOOST_MOVE_MACRO_RV_REF(scoped_deallocator) o)
|
||||
: m_ptr(o.m_ptr), m_alloc(o.m_alloc)
|
||||
{ o.release(); }
|
||||
|
||||
pointer get() const
|
||||
{ return m_ptr; }
|
||||
|
||||
void release()
|
||||
{ m_ptr = 0; }
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_destroyer_and_chain_builder
|
||||
{
|
||||
typedef typename A::value_type value_type;
|
||||
typedef typename A::multiallocation_chain multiallocation_chain;
|
||||
|
||||
A & a_;
|
||||
multiallocation_chain &c_;
|
||||
|
||||
public:
|
||||
allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
|
||||
: a_(a), c_(c)
|
||||
{}
|
||||
|
||||
void operator()(const typename A::pointer &p)
|
||||
{
|
||||
value_type *vp = containers_detail::get_pointer(p);
|
||||
vp->~value_type();
|
||||
c_.push_front(vp);
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
class allocator_multialloc_chain_node_deallocator
|
||||
{
|
||||
typedef typename A::value_type value_type;
|
||||
typedef typename A::multiallocation_chain multiallocation_chain;
|
||||
typedef allocator_destroyer_and_chain_builder<A> chain_builder;
|
||||
|
||||
A & a_;
|
||||
multiallocation_chain c_;
|
||||
|
||||
public:
|
||||
allocator_multialloc_chain_node_deallocator(A &a)
|
||||
: a_(a), c_()
|
||||
{}
|
||||
|
||||
chain_builder get_chain_builder()
|
||||
{ return chain_builder(a_, c_); }
|
||||
|
||||
~allocator_multialloc_chain_node_deallocator()
|
||||
{
|
||||
if(!c_.empty())
|
||||
a_.deallocate_individual(BOOST_CONTAINER_MOVE_NAMESPACE::move(c_));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class ValueCompare, class Node>
|
||||
struct node_compare
|
||||
: private ValueCompare
|
||||
{
|
||||
typedef typename ValueCompare::key_type key_type;
|
||||
typedef typename ValueCompare::value_type value_type;
|
||||
typedef typename ValueCompare::key_of_value key_of_value;
|
||||
|
||||
node_compare(const ValueCompare &pred)
|
||||
: ValueCompare(pred)
|
||||
{}
|
||||
|
||||
ValueCompare &value_comp()
|
||||
{ return static_cast<ValueCompare &>(*this); }
|
||||
|
||||
ValueCompare &value_comp() const
|
||||
{ return static_cast<const ValueCompare &>(*this); }
|
||||
|
||||
bool operator()(const Node &a, const Node &b) const
|
||||
{ return ValueCompare::operator()(a.get_data(), b.get_data()); }
|
||||
};
|
||||
|
||||
template<class A, class ICont>
|
||||
struct node_alloc_holder
|
||||
{
|
||||
typedef node_alloc_holder<A, ICont> self_t;
|
||||
typedef typename A::value_type value_type;
|
||||
typedef typename ICont::value_type Node;
|
||||
typedef typename A::template rebind<Node>::other NodeAlloc;
|
||||
typedef A ValAlloc;
|
||||
typedef typename NodeAlloc::pointer NodePtr;
|
||||
typedef containers_detail::scoped_deallocator<NodeAlloc> Deallocator;
|
||||
typedef typename NodeAlloc::size_type size_type;
|
||||
typedef typename NodeAlloc::difference_type difference_type;
|
||||
typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
|
||||
typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
|
||||
typedef containers_detail::integral_constant<unsigned,
|
||||
boost::container::containers_detail::
|
||||
version<NodeAlloc>::value> alloc_version;
|
||||
typedef typename ICont::iterator icont_iterator;
|
||||
typedef typename ICont::const_iterator icont_citerator;
|
||||
typedef allocator_destroyer<NodeAlloc> Destroyer;
|
||||
|
||||
private:
|
||||
BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(node_alloc_holder)
|
||||
|
||||
public:
|
||||
|
||||
node_alloc_holder(const ValAlloc &a)
|
||||
: members_(a)
|
||||
{}
|
||||
|
||||
node_alloc_holder(const node_alloc_holder &other)
|
||||
: members_(other.node_alloc())
|
||||
{}
|
||||
|
||||
node_alloc_holder(BOOST_MOVE_MACRO_RV_REF(node_alloc_holder) other)
|
||||
: members_(BOOST_CONTAINER_MOVE_NAMESPACE::move(other.node_alloc()))
|
||||
{ this->swap(other); }
|
||||
|
||||
node_alloc_holder & operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(node_alloc_holder) other)
|
||||
{ members_.assign(other.node_alloc()); }
|
||||
|
||||
node_alloc_holder & operator=(BOOST_MOVE_MACRO_RV_REF(node_alloc_holder) other)
|
||||
{ members_.assign(other.node_alloc()); }
|
||||
|
||||
template<class Pred>
|
||||
node_alloc_holder(const ValAlloc &a, const Pred &c)
|
||||
: members_(a, typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
template<class Pred>
|
||||
node_alloc_holder(BOOST_MOVE_MACRO_RV_REF(ValAlloc) a, const Pred &c)
|
||||
: members_(a, typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
template<class Pred>
|
||||
node_alloc_holder(const node_alloc_holder &other, const Pred &c)
|
||||
: members_(other.node_alloc(), typename ICont::value_compare(c))
|
||||
{}
|
||||
|
||||
~node_alloc_holder()
|
||||
{ this->clear(alloc_version()); }
|
||||
|
||||
size_type max_size() const
|
||||
{ return this->node_alloc().max_size(); }
|
||||
|
||||
NodePtr allocate_one()
|
||||
{ return this->allocate_one(alloc_version()); }
|
||||
|
||||
NodePtr allocate_one(allocator_v1)
|
||||
{ return this->node_alloc().allocate(1); }
|
||||
|
||||
NodePtr allocate_one(allocator_v2)
|
||||
{ return this->node_alloc().allocate_one(); }
|
||||
|
||||
void deallocate_one(NodePtr p)
|
||||
{ return this->deallocate_one(p, alloc_version()); }
|
||||
|
||||
void deallocate_one(NodePtr p, allocator_v1)
|
||||
{ this->node_alloc().deallocate(p, 1); }
|
||||
|
||||
void deallocate_one(NodePtr p, allocator_v2)
|
||||
{ this->node_alloc().deallocate_one(p); }
|
||||
|
||||
template<class Convertible1, class Convertible2>
|
||||
static void construct(const NodePtr &ptr,
|
||||
BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
|
||||
{
|
||||
typedef typename Node::hook_type hook_type;
|
||||
typedef typename Node::value_type::first_type first_type;
|
||||
typedef typename Node::value_type::second_type second_type;
|
||||
Node *nodeptr = containers_detail::get_pointer(ptr);
|
||||
|
||||
//Hook constructor does not throw
|
||||
new(static_cast<hook_type*>(nodeptr))hook_type();
|
||||
//Now construct pair members_holder
|
||||
value_type *valueptr = &nodeptr->get_data();
|
||||
new((void*)&valueptr->first) first_type(BOOST_CONTAINER_MOVE_NAMESPACE::move(value.first));
|
||||
BOOST_TRY{
|
||||
new((void*)&valueptr->second) second_type(BOOST_CONTAINER_MOVE_NAMESPACE::move(value.second));
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
valueptr->first.~first_type();
|
||||
static_cast<hook_type*>(nodeptr)->~hook_type();
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
static void destroy(const NodePtr &ptr)
|
||||
{ containers_detail::get_pointer(ptr)->~Node(); }
|
||||
|
||||
Deallocator create_node_and_deallocator()
|
||||
{
|
||||
return Deallocator(this->allocate_one(), this->node_alloc());
|
||||
}
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
template<class ...Args>
|
||||
static void construct(const NodePtr &ptr, Args &&...args)
|
||||
{ new((void*)containers_detail::get_pointer(ptr)) Node(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...); }
|
||||
|
||||
template<class ...Args>
|
||||
NodePtr create_node(Args &&...args)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
self_t::construct(p, BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...);
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
|
||||
#else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
static void construct(const NodePtr &ptr)
|
||||
{ new((void*)containers_detail::get_pointer(ptr)) Node(); }
|
||||
|
||||
NodePtr create_node()
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
self_t::construct(p);
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
new((void*)containers_detail::get_pointer(ptr)) \
|
||||
Node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
{ \
|
||||
NodePtr p = this->allocate_one(); \
|
||||
Deallocator node_deallocator(p, this->node_alloc()); \
|
||||
self_t::construct(p, BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)); \
|
||||
node_deallocator.release(); \
|
||||
return (p); \
|
||||
} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
template<class It>
|
||||
NodePtr create_node_from_it(It it)
|
||||
{
|
||||
NodePtr p = this->allocate_one();
|
||||
Deallocator node_deallocator(p, this->node_alloc());
|
||||
::boost::container::construct_in_place(containers_detail::get_pointer(p), it);
|
||||
node_deallocator.release();
|
||||
return (p);
|
||||
}
|
||||
|
||||
void destroy_node(NodePtr node)
|
||||
{
|
||||
self_t::destroy(node);
|
||||
this->deallocate_one(node);
|
||||
}
|
||||
|
||||
void swap(node_alloc_holder &x)
|
||||
{
|
||||
NodeAlloc& this_alloc = this->node_alloc();
|
||||
NodeAlloc& other_alloc = x.node_alloc();
|
||||
|
||||
if (this_alloc != other_alloc){
|
||||
containers_detail::do_swap(this_alloc, other_alloc);
|
||||
}
|
||||
|
||||
this->icont().swap(x.icont());
|
||||
}
|
||||
|
||||
template<class FwdIterator, class Inserter>
|
||||
FwdIterator allocate_many_and_construct
|
||||
(FwdIterator beg, difference_type n, Inserter inserter)
|
||||
{
|
||||
if(n){
|
||||
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
|
||||
|
||||
//Try to allocate memory in a single block
|
||||
multiallocation_chain mem(this->node_alloc().allocate_individual(n));
|
||||
int constructed = 0;
|
||||
Node *p = 0;
|
||||
BOOST_TRY{
|
||||
for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
|
||||
p = containers_detail::get_pointer(mem.front());
|
||||
mem.pop_front();
|
||||
//This can throw
|
||||
constructed = 0;
|
||||
boost::container::construct_in_place(p, beg);
|
||||
++constructed;
|
||||
//This can throw in some containers (predicate might throw)
|
||||
inserter(*p);
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
if(constructed){
|
||||
this->destroy(p);
|
||||
}
|
||||
this->node_alloc().deallocate_individual(BOOST_CONTAINER_MOVE_NAMESPACE::move(mem));
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
return beg;
|
||||
}
|
||||
|
||||
void clear(allocator_v1)
|
||||
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
|
||||
|
||||
void clear(allocator_v2)
|
||||
{
|
||||
typename NodeAlloc::multiallocation_chain chain;
|
||||
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
|
||||
this->icont().clear_and_dispose(builder);
|
||||
BOOST_STATIC_ASSERT((::BOOST_CONTAINER_MOVE_NAMESPACE::is_movable<typename NodeAlloc::multiallocation_chain>::value == true));
|
||||
if(!chain.empty())
|
||||
this->node_alloc().deallocate_individual(BOOST_CONTAINER_MOVE_NAMESPACE::move(chain));
|
||||
}
|
||||
|
||||
icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
|
||||
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
|
||||
|
||||
icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
|
||||
{
|
||||
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
|
||||
return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
|
||||
}
|
||||
|
||||
template<class Key, class Comparator>
|
||||
size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
|
||||
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
|
||||
|
||||
template<class Key, class Comparator>
|
||||
size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
|
||||
{
|
||||
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
|
||||
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
|
||||
}
|
||||
|
||||
protected:
|
||||
struct cloner
|
||||
{
|
||||
cloner(node_alloc_holder &holder)
|
||||
: m_holder(holder)
|
||||
{}
|
||||
|
||||
NodePtr operator()(const Node &other) const
|
||||
{ return m_holder.create_node(other.get_data()); }
|
||||
|
||||
node_alloc_holder &m_holder;
|
||||
};
|
||||
|
||||
struct destroyer
|
||||
{
|
||||
destroyer(node_alloc_holder &holder)
|
||||
: m_holder(holder)
|
||||
{}
|
||||
|
||||
void operator()(NodePtr n) const
|
||||
{ m_holder.destroy_node(n); }
|
||||
|
||||
node_alloc_holder &m_holder;
|
||||
};
|
||||
|
||||
struct members_holder
|
||||
: public NodeAlloc
|
||||
{
|
||||
private:
|
||||
members_holder(const members_holder&);
|
||||
|
||||
public:
|
||||
template<class ConvertibleToAlloc>
|
||||
members_holder(const ConvertibleToAlloc &c2alloc)
|
||||
: NodeAlloc(c2alloc)
|
||||
{}
|
||||
|
||||
template<class ConvertibleToAlloc, class Pred>
|
||||
members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
|
||||
: NodeAlloc(c2alloc), m_icont(c)
|
||||
{}
|
||||
|
||||
template<class ConvertibleToAlloc>
|
||||
void assign (const ConvertibleToAlloc &c2alloc)
|
||||
{
|
||||
NodeAlloc::operator=(c2alloc);
|
||||
}
|
||||
|
||||
//The intrusive container
|
||||
ICont m_icont;
|
||||
} members_;
|
||||
|
||||
ICont &non_const_icont() const
|
||||
{ return const_cast<ICont&>(this->members_.m_icont); }
|
||||
|
||||
ICont &icont()
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
const ICont &icont() const
|
||||
{ return this->members_.m_icont; }
|
||||
|
||||
NodeAlloc &node_alloc()
|
||||
{ return static_cast<NodeAlloc &>(this->members_); }
|
||||
|
||||
const NodeAlloc &node_alloc() const
|
||||
{ return static_cast<const NodeAlloc &>(this->members_); }
|
||||
};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif // BOOST_CONTAINERS_DETAIL_NODE_ALLOC_HPP_
|
||||
@@ -1,366 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_CONTAINER_FWD_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_UTILITIES_HPP
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional> //std::unary_function
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template<class SegmentManagerBase>
|
||||
class private_node_pool_impl
|
||||
{
|
||||
//Non-copyable
|
||||
private_node_pool_impl();
|
||||
private_node_pool_impl(const private_node_pool_impl &);
|
||||
private_node_pool_impl &operator=(const private_node_pool_impl &);
|
||||
|
||||
//A node object will hold node_t when it's not allocated
|
||||
public:
|
||||
typedef typename SegmentManagerBase::void_pointer void_pointer;
|
||||
typedef typename node_slist<void_pointer>::slist_hook_t slist_hook_t;
|
||||
typedef typename node_slist<void_pointer>::node_t node_t;
|
||||
typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
|
||||
typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
|
||||
|
||||
private:
|
||||
typedef typename bi::make_slist
|
||||
< node_t, bi::base_hook<slist_hook_t>
|
||||
, bi::linear<true>
|
||||
, bi::constant_time_size<false> >::type blockslist_t;
|
||||
public:
|
||||
|
||||
//!Segment manager typedef
|
||||
typedef SegmentManagerBase segment_manager_base_type;
|
||||
|
||||
//!Constructor from a segment manager. Never throws
|
||||
private_node_pool_impl(segment_manager_base_type *segment_mngr_base, std::size_t node_size, std::size_t nodes_per_block)
|
||||
: m_nodes_per_block(nodes_per_block)
|
||||
, m_real_node_size(lcm(node_size, std::size_t(alignment_of<node_t>::value)))
|
||||
//General purpose allocator
|
||||
, mp_segment_mngr_base(segment_mngr_base)
|
||||
, m_blocklist()
|
||||
, m_freelist()
|
||||
//Debug node count
|
||||
, m_allocated(0)
|
||||
{}
|
||||
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
||||
~private_node_pool_impl()
|
||||
{ this->purge_blocks(); }
|
||||
|
||||
std::size_t get_real_num_node() const
|
||||
{ return m_nodes_per_block; }
|
||||
|
||||
//!Returns the segment manager. Never throws
|
||||
segment_manager_base_type* get_segment_manager_base()const
|
||||
{ return containers_detail::get_pointer(mp_segment_mngr_base); }
|
||||
|
||||
void *allocate_node()
|
||||
{ return priv_alloc_node(); }
|
||||
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
||||
void deallocate_node(void *ptr)
|
||||
{ priv_dealloc_node(ptr); }
|
||||
|
||||
//!Allocates a singly linked list of n nodes ending in null pointer.
|
||||
multiallocation_chain allocate_nodes(const std::size_t n)
|
||||
{
|
||||
//Preallocate all needed blocks to fulfill the request
|
||||
std::size_t cur_nodes = m_freelist.size();
|
||||
if(cur_nodes < n){
|
||||
priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
|
||||
}
|
||||
|
||||
//We just iterate the needed nodes to get the last we'll erase
|
||||
typedef typename free_nodes_t::iterator free_iterator;
|
||||
free_iterator before_last_new_it = m_freelist.before_begin();
|
||||
for(std::size_t j = 0; j != n; ++j){
|
||||
++before_last_new_it;
|
||||
}
|
||||
|
||||
//Cache the first node of the allocated range before erasing
|
||||
free_iterator first_node(m_freelist.begin());
|
||||
free_iterator last_node (before_last_new_it);
|
||||
|
||||
//Erase the range. Since we already have the distance, this is O(1)
|
||||
m_freelist.erase_after( m_freelist.before_begin()
|
||||
, ++free_iterator(before_last_new_it)
|
||||
, n);
|
||||
|
||||
//Now take the last erased node and just splice it in the end
|
||||
//of the intrusive list that will be traversed by the multialloc iterator.
|
||||
multiallocation_chain chain;
|
||||
chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
|
||||
m_allocated += n;
|
||||
return BOOST_CONTAINER_MOVE_NAMESPACE::move(chain);
|
||||
}
|
||||
|
||||
void deallocate_nodes(multiallocation_chain chain)
|
||||
{
|
||||
typedef typename multiallocation_chain::iterator iterator;
|
||||
iterator it(chain.begin()), itend(chain.end());
|
||||
while(it != itend){
|
||||
void *pElem = &*it;
|
||||
++it;
|
||||
priv_dealloc_node(pElem);
|
||||
}
|
||||
}
|
||||
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
||||
void deallocate_free_blocks()
|
||||
{
|
||||
typedef typename free_nodes_t::iterator nodelist_iterator;
|
||||
typename blockslist_t::iterator bit(m_blocklist.before_begin()),
|
||||
it(m_blocklist.begin()),
|
||||
itend(m_blocklist.end());
|
||||
free_nodes_t backup_list;
|
||||
nodelist_iterator backup_list_last = backup_list.before_begin();
|
||||
|
||||
//Execute the algorithm and get an iterator to the last value
|
||||
std::size_t blocksize = get_rounded_size
|
||||
(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
|
||||
|
||||
while(it != itend){
|
||||
//Collect all the nodes from the block pointed by it
|
||||
//and push them in the list
|
||||
free_nodes_t free_nodes;
|
||||
nodelist_iterator last_it = free_nodes.before_begin();
|
||||
const void *addr = get_block_from_hook(&*it, blocksize);
|
||||
|
||||
m_freelist.remove_and_dispose_if
|
||||
(is_between(addr, blocksize), push_in_list(free_nodes, last_it));
|
||||
|
||||
//If the number of nodes is equal to m_nodes_per_block
|
||||
//this means that the block can be deallocated
|
||||
if(free_nodes.size() == m_nodes_per_block){
|
||||
//Unlink the nodes
|
||||
free_nodes.clear();
|
||||
it = m_blocklist.erase_after(bit);
|
||||
mp_segment_mngr_base->deallocate((void*)addr);
|
||||
}
|
||||
//Otherwise, insert them in the backup list, since the
|
||||
//next "remove_if" does not need to check them again.
|
||||
else{
|
||||
//Assign the iterator to the last value if necessary
|
||||
if(backup_list.empty() && !m_freelist.empty()){
|
||||
backup_list_last = last_it;
|
||||
}
|
||||
//Transfer nodes. This is constant time.
|
||||
backup_list.splice_after
|
||||
( backup_list.before_begin()
|
||||
, free_nodes
|
||||
, free_nodes.before_begin()
|
||||
, last_it
|
||||
, free_nodes.size());
|
||||
bit = it;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
//We should have removed all the nodes from the free list
|
||||
BOOST_ASSERT(m_freelist.empty());
|
||||
|
||||
//Now pass all the node to the free list again
|
||||
m_freelist.splice_after
|
||||
( m_freelist.before_begin()
|
||||
, backup_list
|
||||
, backup_list.before_begin()
|
||||
, backup_list_last
|
||||
, backup_list.size());
|
||||
}
|
||||
|
||||
std::size_t num_free_nodes()
|
||||
{ return m_freelist.size(); }
|
||||
|
||||
//!Deallocates all used memory. Precondition: all nodes allocated from this pool should
|
||||
//!already be deallocated. Otherwise, undefined behaviour. Never throws
|
||||
void purge_blocks()
|
||||
{
|
||||
//check for memory leaks
|
||||
BOOST_ASSERT(m_allocated==0);
|
||||
std::size_t blocksize = get_rounded_size
|
||||
(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
|
||||
typename blockslist_t::iterator
|
||||
it(m_blocklist.begin()), itend(m_blocklist.end()), aux;
|
||||
|
||||
//We iterate though the NodeBlock list to free the memory
|
||||
while(!m_blocklist.empty()){
|
||||
void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
|
||||
m_blocklist.pop_front();
|
||||
mp_segment_mngr_base->deallocate((void*)addr);
|
||||
}
|
||||
//Just clear free node list
|
||||
m_freelist.clear();
|
||||
}
|
||||
|
||||
void swap(private_node_pool_impl &other)
|
||||
{
|
||||
BOOST_ASSERT(m_nodes_per_block == other.m_nodes_per_block);
|
||||
BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
|
||||
std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
|
||||
m_blocklist.swap(other.m_blocklist);
|
||||
m_freelist.swap(other.m_freelist);
|
||||
std::swap(m_allocated, other.m_allocated);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
struct push_in_list
|
||||
{
|
||||
push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
|
||||
: slist_(l), last_it_(it)
|
||||
{}
|
||||
|
||||
void operator()(typename free_nodes_t::pointer p) const
|
||||
{
|
||||
slist_.push_front(*p);
|
||||
if(slist_.size() == 1){ //Cache last element
|
||||
++last_it_ = slist_.begin();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
free_nodes_t &slist_;
|
||||
typename free_nodes_t::iterator &last_it_;
|
||||
};
|
||||
|
||||
struct is_between
|
||||
: std::unary_function<typename free_nodes_t::value_type, bool>
|
||||
{
|
||||
is_between(const void *addr, std::size_t size)
|
||||
: beg_(static_cast<const char *>(addr)), end_(beg_+size)
|
||||
{}
|
||||
|
||||
bool operator()(typename free_nodes_t::const_reference v) const
|
||||
{
|
||||
return (beg_ <= reinterpret_cast<const char *>(&v) &&
|
||||
end_ > reinterpret_cast<const char *>(&v));
|
||||
}
|
||||
private:
|
||||
const char * beg_;
|
||||
const char * end_;
|
||||
};
|
||||
|
||||
//!Allocates one node, using single segregated storage algorithm.
|
||||
//!Never throws
|
||||
node_t *priv_alloc_node()
|
||||
{
|
||||
//If there are no free nodes we allocate a new block
|
||||
if (m_freelist.empty())
|
||||
priv_alloc_block();
|
||||
//We take the first free node
|
||||
node_t *n = (node_t*)&m_freelist.front();
|
||||
m_freelist.pop_front();
|
||||
++m_allocated;
|
||||
return n;
|
||||
}
|
||||
|
||||
//!Deallocates one node, using single segregated storage algorithm.
|
||||
//!Never throws
|
||||
void priv_dealloc_node(void *pElem)
|
||||
{
|
||||
//We put the node at the beginning of the free node list
|
||||
node_t * to_deallocate = static_cast<node_t*>(pElem);
|
||||
m_freelist.push_front(*to_deallocate);
|
||||
BOOST_ASSERT(m_allocated>0);
|
||||
--m_allocated;
|
||||
}
|
||||
|
||||
//!Allocates several blocks of nodes. Can throw
|
||||
void priv_alloc_block(std::size_t num_blocks = 1)
|
||||
{
|
||||
if(!num_blocks)
|
||||
return;
|
||||
std::size_t blocksize =
|
||||
get_rounded_size(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
|
||||
|
||||
try{
|
||||
for(std::size_t i = 0; i != num_blocks; ++i){
|
||||
//We allocate a new NodeBlock and put it as first
|
||||
//element in the free Node list
|
||||
char *pNode = reinterpret_cast<char*>
|
||||
(mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
|
||||
char *pBlock = pNode;
|
||||
m_blocklist.push_front(get_block_hook(pBlock, blocksize));
|
||||
|
||||
//We initialize all Nodes in Node Block to insert
|
||||
//them in the free Node list
|
||||
for(std::size_t i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
|
||||
m_freelist.push_front(*new (pNode) node_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
//to-do: if possible, an efficient way to deallocate allocated blocks
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
//!Deprecated, use deallocate_free_blocks
|
||||
void deallocate_free_chunks()
|
||||
{ this->deallocate_free_blocks(); }
|
||||
|
||||
//!Deprecated, use purge_blocks
|
||||
void purge_chunks()
|
||||
{ this->purge_blocks(); }
|
||||
|
||||
private:
|
||||
//!Returns a reference to the block hook placed in the end of the block
|
||||
static node_t & get_block_hook (void *block, std::size_t blocksize)
|
||||
{
|
||||
return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
|
||||
}
|
||||
|
||||
//!Returns the starting address of the block reference to the block hook placed in the end of the block
|
||||
void *get_block_from_hook (node_t *hook, std::size_t blocksize)
|
||||
{
|
||||
return (reinterpret_cast<char*>(hook) - blocksize);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename boost::pointer_to_other
|
||||
<void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
|
||||
|
||||
const std::size_t m_nodes_per_block;
|
||||
const std::size_t m_real_node_size;
|
||||
segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
|
||||
blockslist_t m_blocklist; //Intrusive container of blocks
|
||||
free_nodes_t m_freelist; //Intrusive container of free nods
|
||||
std::size_t m_allocated; //Used nodes for debugging
|
||||
};
|
||||
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
@@ -1,212 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
|
||||
#define BOOST_CONTAINERS_CONTAINERS_DETAIL_PAIR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <utility> //std::pair
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
|
||||
#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template <class T1, class T2>
|
||||
struct pair
|
||||
{
|
||||
private:
|
||||
BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(pair)
|
||||
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
|
||||
//std::pair compatibility
|
||||
template <class D, class S>
|
||||
pair(const std::pair<D, S>& p)
|
||||
: first(p.first), second(p.second)
|
||||
{}
|
||||
|
||||
//To resolve ambiguity with the variadic constructor of 1 argument
|
||||
//and the previous constructor
|
||||
pair(std::pair<T1, T2>& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
|
||||
: first(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first)), second(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second))
|
||||
{}
|
||||
|
||||
pair()
|
||||
: first(), second()
|
||||
{}
|
||||
|
||||
pair(const pair<T1, T2>& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
|
||||
//To resolve ambiguity with the variadic constructor of 1 argument
|
||||
//and the copy constructor
|
||||
pair(pair<T1, T2>& x)
|
||||
: first(x.first), second(x.second)
|
||||
{}
|
||||
|
||||
pair(BOOST_MOVE_MACRO_RV_REF(pair) p)
|
||||
: first(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first)), second(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second))
|
||||
{}
|
||||
|
||||
template <class D, class S>
|
||||
pair(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
|
||||
: first(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first)), second(BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second))
|
||||
{}
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
template<class U, class ...Args>
|
||||
pair(U &&u, Args &&... args)
|
||||
: first(BOOST_CONTAINER_MOVE_NAMESPACE::forward<U>(u))
|
||||
, second(BOOST_CONTAINER_MOVE_NAMESPACE::forward<Args>(args)...)
|
||||
{}
|
||||
|
||||
#else
|
||||
|
||||
template<class U>
|
||||
pair( BOOST_CONTAINERS_PARAM(U, u)
|
||||
#ifdef BOOST_NO_RVALUE_REFERENCES
|
||||
, typename containers_detail::disable_if
|
||||
< containers_detail::is_same<U, ::BOOST_CONTAINER_MOVE_NAMESPACE::rv<pair> > >::type* = 0
|
||||
#endif
|
||||
)
|
||||
: first(BOOST_CONTAINER_MOVE_NAMESPACE::forward<U>(const_cast<U&>(u)))
|
||||
{}
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
|
||||
pair(BOOST_CONTAINERS_PARAM(U, u) \
|
||||
,BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _)) \
|
||||
: first(BOOST_CONTAINER_MOVE_NAMESPACE::forward<U>(const_cast<U&>(u))) \
|
||||
, second(BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_FORWARD, _)) \
|
||||
{} \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
#endif
|
||||
|
||||
pair& operator=(BOOST_MOVE_MACRO_COPY_ASSIGN_REF(pair) p)
|
||||
{
|
||||
first = p.first;
|
||||
second = p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
pair& operator=(BOOST_MOVE_MACRO_RV_REF(pair) p)
|
||||
{
|
||||
first = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first);
|
||||
second = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pair& operator=(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
|
||||
{
|
||||
first = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first);
|
||||
second = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class D, class S>
|
||||
pair& operator=(BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
|
||||
{
|
||||
first = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.first);
|
||||
second = BOOST_CONTAINER_MOVE_NAMESPACE::move(p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(pair& p)
|
||||
{ std::swap(*this, p); }
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(x.first == y.first && x.second == y.second); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(x.first < y.first ||
|
||||
(!(y.first < x.first) && x.second < y.second)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(!(x == y)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return y < x; }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(!(x < y)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
|
||||
{ return static_cast<bool>(!(y < x)); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline pair<T1, T2> make_pair(T1 x, T2 y)
|
||||
{ return pair<T1, T2>(x, y); }
|
||||
|
||||
template <class T1, class T2>
|
||||
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
|
||||
{
|
||||
swap(x.first, y.first);
|
||||
swap(x.second, y.second);
|
||||
}
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
|
||||
|
||||
//Without this specialization recursive flat_(multi)map instantiation fails
|
||||
//because is_enum needs to instantiate the recursive pair, leading to a compilation error).
|
||||
//This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
|
||||
template<class T>
|
||||
struct is_enum;
|
||||
|
||||
template<class T, class U>
|
||||
struct is_enum< ::boost::container::containers_detail::pair<T, U> >
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_PAIR_HPP
|
||||
@@ -1,52 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/intrusive/slist.hpp>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template<class VoidPointer>
|
||||
struct node_slist
|
||||
{
|
||||
//This hook will be used to chain the individual nodes
|
||||
typedef typename bi::make_slist_base_hook
|
||||
<bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type slist_hook_t;
|
||||
|
||||
//A node object will hold node_t when it's not allocated
|
||||
typedef slist_hook_t node_t;
|
||||
|
||||
typedef typename bi::make_slist
|
||||
<node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_stateless_segment_manager
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
|
||||
@@ -1,141 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP
|
||||
#endif
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#error "This file is not needed when perfect forwarding is available"
|
||||
#endif
|
||||
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
|
||||
#define BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS 10
|
||||
|
||||
//Note:
|
||||
//We define template parameters as const references to
|
||||
//be able to bind temporaries. After that we will un-const them.
|
||||
//This cast is ugly but it is necessary until "perfect forwarding"
|
||||
//is achieved in C++0x. Meanwhile, if we want to be able to
|
||||
//bind rvalues with non-const references, we have to be ugly
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
|
||||
//!
|
||||
#else
|
||||
#define BOOST_CONTAINERS_PP_PARAM_LIST(z, n, data) \
|
||||
const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
|
||||
//!
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#define BOOST_CONTAINERS_PARAM(U, u) \
|
||||
U && u \
|
||||
//!
|
||||
#else
|
||||
#define BOOST_CONTAINERS_PARAM(U, u) \
|
||||
const U & u \
|
||||
//!
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (BOOST_CONTAINER_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
|
||||
//!
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
|
||||
//!
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
|
||||
//!
|
||||
#endif
|
||||
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_INC(z, n, data) \
|
||||
BOOST_PP_CAT(++m_p, n) \
|
||||
//!
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
|
||||
#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
|
||||
#else
|
||||
#define BOOST_CONTAINERS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
#endif
|
||||
|
||||
#define BOOST_CONTAINERS_PP_PARAM_FORWARD(z, n, data) \
|
||||
BOOST_CONTAINER_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
|
||||
//!
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
|
||||
::boost::container::containers_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
|
||||
//!
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CONTAINERS_PP_MEMBER_FORWARD(z, n, data) \
|
||||
BOOST_CONTAINER_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
|
||||
//!
|
||||
|
||||
#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_CONTAINERS_PP_MEMBER_IT_FORWARD(z, n, data) \
|
||||
BOOST_PP_CAT(*m_p, n) \
|
||||
//!
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#else
|
||||
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
#error "This file is not needed when perfect forwarding is available"
|
||||
#endif
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_PREPROCESSOR_HPP
|
||||
@@ -1,92 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
namespace boost{
|
||||
namespace container{
|
||||
namespace containers_detail{
|
||||
|
||||
template<class T>
|
||||
struct stored_ref
|
||||
{
|
||||
|
||||
static T && forward(T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return BOOST_CONTAINER_MOVE_NAMESPACE::move(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<const T>
|
||||
{
|
||||
static const T && forward(const T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return static_cast<const T&&>(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<T&&>
|
||||
{
|
||||
static T && forward(T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return BOOST_CONTAINER_MOVE_NAMESPACE::move(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<const T&&>
|
||||
{
|
||||
static const T && forward(const T &t)
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
{ return t; }
|
||||
#else
|
||||
{ return static_cast<const T &&>(t); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<const T&>
|
||||
{
|
||||
static const T & forward(const T &t)
|
||||
{ return t; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct stored_ref<T&>
|
||||
{
|
||||
static T & forward(T &t)
|
||||
{ return t; }
|
||||
};
|
||||
|
||||
} //namespace containers_detail{
|
||||
} //namespace container{
|
||||
} //namespace boost{
|
||||
|
||||
#else
|
||||
#error "This header can be included only for compiler with rvalue references"
|
||||
#endif //BOOST_NO_RVALUE_REFERENCES
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //BOOST_CONTAINERS_DETAIL_STORED_REF_HPP
|
||||
@@ -1,176 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
template <class PseudoReference>
|
||||
struct operator_arrow_proxy
|
||||
{
|
||||
operator_arrow_proxy(const PseudoReference &px)
|
||||
: m_value(px)
|
||||
{}
|
||||
|
||||
PseudoReference* operator->() const { return &m_value; }
|
||||
// This function is needed for MWCW and BCC, which won't call operator->
|
||||
// again automatically per 13.3.1.2 para 8
|
||||
// operator T*() const { return &m_value; }
|
||||
mutable PseudoReference m_value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct operator_arrow_proxy<T&>
|
||||
{
|
||||
operator_arrow_proxy(T &px)
|
||||
: m_value(px)
|
||||
{}
|
||||
|
||||
T* operator->() const { return const_cast<T*>(&m_value); }
|
||||
// This function is needed for MWCW and BCC, which won't call operator->
|
||||
// again automatically per 13.3.1.2 para 8
|
||||
// operator T*() const { return &m_value; }
|
||||
T &m_value;
|
||||
};
|
||||
|
||||
template <class Iterator, class UnaryFunction>
|
||||
class transform_iterator
|
||||
: public UnaryFunction
|
||||
, public std::iterator
|
||||
< typename Iterator::iterator_category
|
||||
, typename containers_detail::remove_reference<typename UnaryFunction::result_type>::type
|
||||
, typename Iterator::difference_type
|
||||
, operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
, typename UnaryFunction::result_type>
|
||||
{
|
||||
public:
|
||||
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
|
||||
: UnaryFunction(f), m_it(it)
|
||||
{}
|
||||
|
||||
explicit transform_iterator()
|
||||
: UnaryFunction(), m_it()
|
||||
{}
|
||||
|
||||
//Constructors
|
||||
transform_iterator& operator++()
|
||||
{ increment(); return *this; }
|
||||
|
||||
transform_iterator operator++(int)
|
||||
{
|
||||
transform_iterator result (*this);
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
|
||||
friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i.equal(i2); }
|
||||
|
||||
friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i == i2); }
|
||||
|
||||
/*
|
||||
friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2 < i; }
|
||||
|
||||
friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i > i2); }
|
||||
|
||||
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return !(i < i2); }
|
||||
*/
|
||||
friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
|
||||
{ return i2.distance_to(i); }
|
||||
|
||||
//Arithmetic
|
||||
transform_iterator& operator+=(typename Iterator::difference_type off)
|
||||
{ this->advance(off); return *this; }
|
||||
|
||||
transform_iterator operator+(typename Iterator::difference_type off) const
|
||||
{
|
||||
transform_iterator other(*this);
|
||||
other.advance(off);
|
||||
return other;
|
||||
}
|
||||
|
||||
friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
|
||||
{ return right + off; }
|
||||
|
||||
transform_iterator& operator-=(typename Iterator::difference_type off)
|
||||
{ this->advance(-off); return *this; }
|
||||
|
||||
transform_iterator operator-(typename Iterator::difference_type off) const
|
||||
{ return *this + (-off); }
|
||||
|
||||
typename UnaryFunction::result_type operator*() const
|
||||
{ return dereference(); }
|
||||
|
||||
operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
operator->() const
|
||||
{ return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
|
||||
|
||||
Iterator & base()
|
||||
{ return m_it; }
|
||||
|
||||
const Iterator & base() const
|
||||
{ return m_it; }
|
||||
|
||||
private:
|
||||
Iterator m_it;
|
||||
|
||||
void increment()
|
||||
{ ++m_it; }
|
||||
|
||||
void decrement()
|
||||
{ --m_it; }
|
||||
|
||||
bool equal(const transform_iterator &other) const
|
||||
{ return m_it == other.m_it; }
|
||||
|
||||
bool less(const transform_iterator &other) const
|
||||
{ return other.m_it < m_it; }
|
||||
|
||||
typename UnaryFunction::result_type dereference() const
|
||||
{ return UnaryFunction::operator()(*m_it); }
|
||||
|
||||
void advance(typename Iterator::difference_type n)
|
||||
{ std::advance(m_it, n); }
|
||||
|
||||
typename Iterator::difference_type distance_to(const transform_iterator &other)const
|
||||
{ return std::distance(other.m_it, m_it); }
|
||||
};
|
||||
|
||||
template <class Iterator, class UnaryFunc>
|
||||
transform_iterator<Iterator, UnaryFunc>
|
||||
make_transform_iterator(Iterator it, UnaryFunc fun)
|
||||
{
|
||||
return transform_iterator<Iterator, UnaryFunc>(it, fun);
|
||||
}
|
||||
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_TRANSFORM_ITERATORS_HPP
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,166 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
// The alignment_of implementation comes from John Maddock's boost::alignment_of code
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#define BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
struct nat{};
|
||||
|
||||
//boost::alignment_of yields to 10K lines of preprocessed code, so we
|
||||
//need an alternative
|
||||
template <typename T> struct alignment_of;
|
||||
|
||||
template <typename T>
|
||||
struct alignment_of_hack
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
alignment_of_hack();
|
||||
};
|
||||
|
||||
template <unsigned A, unsigned S>
|
||||
struct alignment_logic
|
||||
{
|
||||
enum{ value = A < S ? A : S };
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct alignment_of
|
||||
{
|
||||
enum{ value = alignment_logic
|
||||
< sizeof(alignment_of_hack<T>) - sizeof(T)
|
||||
, sizeof(T)>::value };
|
||||
};
|
||||
|
||||
//This is not standard, but should work with all compilers
|
||||
union max_align
|
||||
{
|
||||
char char_;
|
||||
short short_;
|
||||
int int_;
|
||||
long long_;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
long long long_long_;
|
||||
#endif
|
||||
float float_;
|
||||
double double_;
|
||||
long double long_double_;
|
||||
void * void_ptr_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_reference
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_reference<T&>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_reference
|
||||
{
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_reference<T&>
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_pointer
|
||||
{
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_pointer<T*>
|
||||
{
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct add_reference
|
||||
{
|
||||
typedef T& type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct add_reference<T&>
|
||||
{
|
||||
typedef T& type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct add_reference<void>
|
||||
{
|
||||
typedef nat &type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct add_reference<const void>
|
||||
{
|
||||
typedef const nat &type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct add_const_reference
|
||||
{ typedef const T &type; };
|
||||
|
||||
template <class T>
|
||||
struct add_const_reference<T&>
|
||||
{ typedef T& type; };
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same
|
||||
{
|
||||
typedef char yes_type;
|
||||
struct no_type
|
||||
{
|
||||
char padding[8];
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
static yes_type is_same_tester(V*, V*);
|
||||
static no_type is_same_tester(...);
|
||||
|
||||
static T *t;
|
||||
static U *u;
|
||||
|
||||
static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
|
||||
};
|
||||
|
||||
} // namespace containers_detail
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <cstdio>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_member_pointer.hpp>
|
||||
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template<class T>
|
||||
const T &max_value(const T &a, const T &b)
|
||||
{ return a > b ? a : b; }
|
||||
|
||||
template<class T>
|
||||
const T &min_value(const T &a, const T &b)
|
||||
{ return a < b ? a : b; }
|
||||
|
||||
template <class SizeType>
|
||||
SizeType
|
||||
get_next_capacity(const SizeType max_size
|
||||
,const SizeType capacity
|
||||
,const SizeType n)
|
||||
{
|
||||
// if (n > max_size - capacity)
|
||||
// throw std::length_error("get_next_capacity");
|
||||
|
||||
const SizeType m3 = max_size/3;
|
||||
|
||||
if (capacity < m3)
|
||||
return capacity + max_value(3*(capacity+1)/5, n);
|
||||
|
||||
if (capacity < m3*2)
|
||||
return capacity + max_value((capacity+1)/2, n);
|
||||
|
||||
return max_size;
|
||||
}
|
||||
|
||||
template<class SmartPtr>
|
||||
struct smart_ptr_type
|
||||
{
|
||||
typedef typename SmartPtr::value_type value_type;
|
||||
typedef value_type *pointer;
|
||||
static pointer get (const SmartPtr &smartptr)
|
||||
{ return smartptr.get();}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct smart_ptr_type<T*>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef value_type *pointer;
|
||||
static pointer get (pointer ptr)
|
||||
{ return ptr;}
|
||||
};
|
||||
|
||||
//!Overload for smart pointers to avoid ADL problems with get_pointer
|
||||
template<class Ptr>
|
||||
inline typename smart_ptr_type<Ptr>::pointer
|
||||
get_pointer(const Ptr &ptr)
|
||||
{ return smart_ptr_type<Ptr>::get(ptr); }
|
||||
|
||||
//!To avoid ADL problems with swap
|
||||
template <class T>
|
||||
inline void do_swap(T& x, T& y)
|
||||
{
|
||||
using std::swap;
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
//Rounds "orig_size" by excess to round_to bytes
|
||||
inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
|
||||
{
|
||||
return ((orig_size-1)/round_to+1)*round_to;
|
||||
}
|
||||
|
||||
template <std::size_t OrigSize, std::size_t RoundTo>
|
||||
struct ct_rounded_size
|
||||
{
|
||||
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
|
||||
};
|
||||
|
||||
template <class _TypeT>
|
||||
struct __rw_is_enum
|
||||
{
|
||||
struct _C_no { };
|
||||
struct _C_yes { int _C_dummy [2]; };
|
||||
|
||||
struct _C_indirect {
|
||||
// prevent classes with user-defined conversions from matching
|
||||
|
||||
// use double to prevent float->int gcc conversion warnings
|
||||
_C_indirect (double);
|
||||
};
|
||||
|
||||
// nested struct gets rid of bogus gcc errors
|
||||
struct _C_nest {
|
||||
// supply first argument to prevent HP aCC warnings
|
||||
static _C_no _C_is (int, ...);
|
||||
static _C_yes _C_is (int, _C_indirect);
|
||||
|
||||
static _TypeT _C_make_T ();
|
||||
};
|
||||
|
||||
enum {
|
||||
_C_val = sizeof (_C_yes)
|
||||
== sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ()))
|
||||
&& !::boost::is_fundamental<_TypeT>::value
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct move_const_ref_type
|
||||
: if_c
|
||||
< ::boost::is_fundamental<T>::value || ::boost::is_pointer<T>::value ||
|
||||
::boost::is_member_pointer<T>::value || ::boost::is_enum<T>::value
|
||||
,const T &
|
||||
,BOOST_MOVE_MACRO_CATCH_CONST_RLVALUE(T)
|
||||
>
|
||||
{};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_UTILITIES_HPP
|
||||
@@ -1,43 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
//
|
||||
// Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template<class T>
|
||||
struct value_init
|
||||
{
|
||||
value_init()
|
||||
: m_t()
|
||||
{}
|
||||
|
||||
T m_t;
|
||||
};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_VALUE_INIT_HPP
|
||||
@@ -1,153 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
#include <cstddef> //std::size_t
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
template<typename... Values>
|
||||
class tuple;
|
||||
|
||||
template<> class tuple<>
|
||||
{};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
class tuple<Head, Tail...>
|
||||
: private tuple<Tail...>
|
||||
{
|
||||
typedef tuple<Tail...> inherited;
|
||||
|
||||
public:
|
||||
tuple() { }
|
||||
|
||||
// implicit copy-constructor is okay
|
||||
// Construct tuple from separate arguments.
|
||||
tuple(typename add_const_reference<Head>::type v,
|
||||
typename add_const_reference<Tail>::type... vtail)
|
||||
: inherited(vtail...), m_head(v)
|
||||
{}
|
||||
|
||||
// Construct tuple from another tuple.
|
||||
template<typename... VValues>
|
||||
tuple(const tuple<VValues...>& other)
|
||||
: m_head(other.head()), inherited(other.tail())
|
||||
{}
|
||||
|
||||
template<typename... VValues>
|
||||
tuple& operator=(const tuple<VValues...>& other)
|
||||
{
|
||||
m_head = other.head();
|
||||
tail() = other.tail();
|
||||
return this;
|
||||
}
|
||||
|
||||
typename add_reference<Head>::type head() { return m_head; }
|
||||
typename add_reference<const Head>::type head() const { return m_head; }
|
||||
|
||||
inherited& tail() { return *this; }
|
||||
const inherited& tail() const { return *this; }
|
||||
|
||||
protected:
|
||||
Head m_head;
|
||||
};
|
||||
|
||||
|
||||
template<typename... Values>
|
||||
tuple<Values&&...> tie_forward(Values&&... values)
|
||||
{ return tuple<Values&&...>(values...); }
|
||||
|
||||
template<int I, typename Tuple>
|
||||
struct tuple_element;
|
||||
|
||||
template<int I, typename Head, typename... Tail>
|
||||
struct tuple_element<I, tuple<Head, Tail...> >
|
||||
{
|
||||
typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
|
||||
};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
struct tuple_element<0, tuple<Head, Tail...> >
|
||||
{
|
||||
typedef Head type;
|
||||
};
|
||||
|
||||
template<int I, typename Tuple>
|
||||
class get_impl;
|
||||
|
||||
template<int I, typename Head, typename... Values>
|
||||
class get_impl<I, tuple<Head, Values...> >
|
||||
{
|
||||
typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
|
||||
typedef get_impl<I-1, tuple<Values...> > Next;
|
||||
|
||||
public:
|
||||
typedef typename add_reference<Element>::type type;
|
||||
typedef typename add_const_reference<Element>::type const_type;
|
||||
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
||||
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
||||
};
|
||||
|
||||
template<typename Head, typename... Values>
|
||||
class get_impl<0, tuple<Head, Values...> >
|
||||
{
|
||||
public:
|
||||
typedef typename add_reference<Head>::type type;
|
||||
typedef typename add_const_reference<Head>::type const_type;
|
||||
static type get(tuple<Head, Values...>& t) { return t.head(); }
|
||||
static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
|
||||
};
|
||||
|
||||
template<int I, typename... Values>
|
||||
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); }
|
||||
|
||||
template<int I, typename... Values>
|
||||
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); }
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
|
||||
// be used to "unpack" into comma-separated values
|
||||
// in a function call.
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
template<int... Indexes>
|
||||
struct index_tuple{};
|
||||
|
||||
template<std::size_t Num, typename Tuple = index_tuple<> >
|
||||
struct build_number_seq;
|
||||
|
||||
template<std::size_t Num, int... Indexes>
|
||||
struct build_number_seq<Num, index_tuple<Indexes...> >
|
||||
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
||||
{};
|
||||
|
||||
template<int... Indexes>
|
||||
struct build_number_seq<0, index_tuple<Indexes...> >
|
||||
{ typedef index_tuple<Indexes...> type; };
|
||||
|
||||
|
||||
}}} //namespace boost { namespace container { namespace containers_detail {
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
||||
@@ -1,91 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This code comes from N1953 document by Howard E. Hinnant
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_MPL_HPP
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
|
||||
namespace boost{
|
||||
namespace container {
|
||||
namespace containers_detail {
|
||||
|
||||
//using namespace boost;
|
||||
|
||||
template <class T, unsigned V>
|
||||
struct version_type
|
||||
: public containers_detail::integral_constant<unsigned, V>
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
version_type(const version_type<T, 0>&);
|
||||
};
|
||||
|
||||
namespace impl{
|
||||
|
||||
template <class T,
|
||||
bool = containers_detail::is_convertible<version_type<T, 0>, typename T::version>::value>
|
||||
struct extract_version
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct extract_version<T, true>
|
||||
{
|
||||
static const unsigned value = T::version::value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct has_version
|
||||
{
|
||||
private:
|
||||
struct two {char _[2];};
|
||||
template <class U> static two test(...);
|
||||
template <class U> static char test(const typename U::version*);
|
||||
public:
|
||||
static const bool value = sizeof(test<T>(0)) == 1;
|
||||
void dummy(){}
|
||||
};
|
||||
|
||||
template <class T, bool = has_version<T>::value>
|
||||
struct version
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct version<T, true>
|
||||
{
|
||||
static const unsigned value = extract_version<T>::value;
|
||||
};
|
||||
|
||||
} //namespace impl
|
||||
|
||||
template <class T>
|
||||
struct version
|
||||
: public containers_detail::integral_constant<unsigned, impl::version<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
} //namespace containers_detail {
|
||||
} //namespace container {
|
||||
} //namespace boost{
|
||||
|
||||
#endif //#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP
|
||||
@@ -1,24 +0,0 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/container for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
|
||||
#define BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#include "config_begin.hpp"
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
|
||||
&& !defined(BOOST_MOVE_MACRO_DISABLE_VARIADIC_TMPL)
|
||||
#define BOOST_CONTAINERS_PERFECT_FORWARDING
|
||||
|
||||
#endif
|
||||
|
||||
#include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINERS_DETAIL_WORKAROUND_HPP
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/container_fwd.hpp>
|
||||
#include <boost/container/container_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
@@ -35,4 +35,6 @@ using boost::container::ordered_unique_range;
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
/// @endcond
|
||||
|
||||
#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_CONTAINERS_FWD_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/deque.hpp>
|
||||
#include <boost/container/deque.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/flat_map.hpp>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/flat_set.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/list.hpp>
|
||||
#include <boost/container/list.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/map.hpp>
|
||||
#include <boost/container/map.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,13 +16,14 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/pair.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
using boost::container::containers_detail::pair;
|
||||
using boost::container::container_detail::pair;
|
||||
using boost::container::container_detail::piecewise_construct;
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/set.hpp>
|
||||
#include <boost/container/set.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/slist.hpp>
|
||||
#include <boost/container/slist.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/stable_vector.hpp>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/string.hpp>
|
||||
#include <boost/container/string.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,7 +16,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/vector.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <boost/interprocess/containers/containers_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -16,13 +16,13 @@
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/containers/container/detail/version_type.hpp>
|
||||
#include <boost/container/detail/version_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
using boost::container::containers_detail::version_type;
|
||||
using boost::container::containers_detail::version;
|
||||
using boost::container::container_detail::version_type;
|
||||
using boost::container::container_detail::version;
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -61,12 +61,12 @@ static const open_or_create_t open_or_create = open_or_create_t();
|
||||
//!be only opened for reading
|
||||
static const open_copy_on_write_t open_copy_on_write = open_copy_on_write_t();
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
enum create_enum_t
|
||||
{ DoCreate, DoOpen, DoOpenOrCreate };
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2009
|
||||
// (C) Copyright Ion Gaztanaga 2006-2011
|
||||
// (C) Copyright Markus Schoepflin 2007
|
||||
// (C) Copyright Bryce Lelbach 2010
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Atomically increment an boost::uint32_t by 1
|
||||
//! "mem": pointer to the object
|
||||
@@ -44,7 +45,7 @@ inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val);
|
||||
inline boost::uint32_t atomic_cas32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp);
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
@@ -54,7 +55,7 @@ inline boost::uint32_t atomic_cas32
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
||||
//! "mem": pointer to the atomic value
|
||||
@@ -88,7 +89,7 @@ inline boost::uint32_t atomic_cas32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
|
||||
{ return winapi::interlocked_compare_exchange(reinterpret_cast<volatile long*>(mem), with, cmp); }
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
@@ -96,7 +97,7 @@ inline boost::uint32_t atomic_cas32
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
||||
//! If they are the same swap the value with "with"
|
||||
@@ -108,12 +109,21 @@ inline boost::uint32_t atomic_cas32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
|
||||
{
|
||||
boost::uint32_t prev = cmp;
|
||||
// This version by Mans Rullgard of Pathscale
|
||||
__asm__ __volatile__ ( "lock\n\t"
|
||||
"cmpxchg %2,%0"
|
||||
: "+m"(*mem), "+a"(prev)
|
||||
: "r"(with)
|
||||
: "cc");
|
||||
|
||||
return prev;
|
||||
/*
|
||||
asm volatile( "lock\n\t"
|
||||
"cmpxchg %3,%1"
|
||||
: "=a" (prev), "=m" (*(mem))
|
||||
: "0" (prev), "r" (with)
|
||||
: "memory", "cc");
|
||||
return prev;
|
||||
*/
|
||||
/*
|
||||
boost::uint32_t prev;
|
||||
|
||||
@@ -180,7 +190,7 @@ inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ *mem = val; }
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
@@ -188,7 +198,7 @@ inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
||||
//! "mem": pointer to the object
|
||||
@@ -261,15 +271,15 @@ inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ *mem = val; }
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined(ANDROID)
|
||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
||||
//! "mem": pointer to the object
|
||||
@@ -311,7 +321,7 @@ inline boost::uint32_t atomic_cas32
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ *mem = val; }
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
@@ -321,7 +331,7 @@ inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
||||
//! "mem": pointer to the object
|
||||
@@ -362,7 +372,7 @@ inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ *mem = val; }
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
@@ -373,7 +383,7 @@ inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//! Atomically decrement a uint32_t by 1
|
||||
//! "mem": pointer to the atomic value
|
||||
@@ -457,7 +467,7 @@ inline boost::uint32_t atomic_cas32(
|
||||
mem, with, cmp);
|
||||
}
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
@@ -467,7 +477,7 @@ inline boost::uint32_t atomic_cas32(
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
|
||||
//all the functions with casts
|
||||
@@ -549,7 +559,7 @@ inline boost::uint32_t atomic_cas32
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
{ *mem = val; }
|
||||
|
||||
} //namespace detail
|
||||
} //namespace ipcdetail
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
|
||||
@@ -561,7 +571,7 @@ inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
inline bool atomic_add_unless32
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t value, boost::uint32_t unless_this)
|
||||
@@ -573,7 +583,7 @@ inline bool atomic_add_unless32
|
||||
return c != unless_this;
|
||||
}
|
||||
|
||||
} //namespace detail
|
||||
} //namespace ipcdetail
|
||||
} //namespace interprocess
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -14,14 +14,14 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace interprocess { namespace detail {
|
||||
namespace boost { namespace interprocess { namespace ipcdetail {
|
||||
|
||||
struct static_cast_tag {};
|
||||
struct const_cast_tag {};
|
||||
struct dynamic_cast_tag {};
|
||||
struct reinterpret_cast_tag {};
|
||||
|
||||
}}} //namespace boost { namespace interprocess { namespace detail {
|
||||
}}} //namespace boost { namespace interprocess { namespace ipcdetail {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
|
||||
@@ -15,17 +15,17 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
class file_wrapper
|
||||
{
|
||||
/// @cond
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(file_wrapper)
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(file_wrapper)
|
||||
/// @endcond
|
||||
public:
|
||||
|
||||
@@ -36,31 +36,32 @@ class file_wrapper
|
||||
//!Creates a file object with name "name" and mode "mode", with the access mode "mode"
|
||||
//!If the file previously exists, throws an error.
|
||||
file_wrapper(create_only_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
||||
{ this->priv_open_or_create(detail::DoCreate, name, mode, perm); }
|
||||
{ this->priv_open_or_create(ipcdetail::DoCreate, name, mode, perm); }
|
||||
|
||||
//!Tries to create a file with name "name" and mode "mode", with the
|
||||
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
|
||||
//!Otherwise throws an error.
|
||||
file_wrapper(open_or_create_t, const char *name, mode_t mode, const permissions &perm = permissions())
|
||||
{ this->priv_open_or_create(detail::DoOpenOrCreate, name, mode, perm); }
|
||||
{ this->priv_open_or_create(ipcdetail::DoOpenOrCreate, name, mode, perm); }
|
||||
|
||||
//!Tries to open a file with name "name", with the access mode "mode".
|
||||
//!If the file does not previously exist, it throws an error.
|
||||
file_wrapper(open_only_t, const char *name, mode_t mode)
|
||||
{ this->priv_open_or_create(detail::DoOpen, name, mode, permissions()); }
|
||||
{ this->priv_open_or_create(ipcdetail::DoOpen, name, mode, permissions()); }
|
||||
|
||||
//!Moves the ownership of "moved"'s file to *this.
|
||||
//!After the call, "moved" does not represent any file.
|
||||
//!Does not throw
|
||||
file_wrapper(BOOST_INTERPROCESS_RV_REF(file_wrapper) moved)
|
||||
file_wrapper(BOOST_RV_REF(file_wrapper) moved)
|
||||
: m_handle(file_handle_t(ipcdetail::invalid_file()))
|
||||
{ this->swap(moved); }
|
||||
|
||||
//!Moves the ownership of "moved"'s file to *this.
|
||||
//!After the call, "moved" does not represent any file.
|
||||
//!Does not throw
|
||||
file_wrapper &operator=(BOOST_INTERPROCESS_RV_REF(file_wrapper) moved)
|
||||
file_wrapper &operator=(BOOST_RV_REF(file_wrapper) moved)
|
||||
{
|
||||
file_wrapper tmp(boost::interprocess::move(moved));
|
||||
file_wrapper tmp(boost::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
@@ -100,7 +101,7 @@ class file_wrapper
|
||||
//!Closes a previously opened file mapping. Never throws.
|
||||
void priv_close();
|
||||
//!Closes a previously opened file mapping. Never throws.
|
||||
bool priv_open_or_create(detail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
|
||||
bool priv_open_or_create(ipcdetail::create_enum_t type, const char *filename, mode_t mode, const permissions &perm);
|
||||
|
||||
file_handle_t m_handle;
|
||||
mode_t m_mode;
|
||||
@@ -108,7 +109,7 @@ class file_wrapper
|
||||
};
|
||||
|
||||
inline file_wrapper::file_wrapper()
|
||||
: m_handle(file_handle_t(detail::invalid_file()))
|
||||
: m_handle(file_handle_t(ipcdetail::invalid_file()))
|
||||
{}
|
||||
|
||||
inline file_wrapper::~file_wrapper()
|
||||
@@ -134,7 +135,7 @@ inline mode_t file_wrapper::get_mode() const
|
||||
{ return m_mode; }
|
||||
|
||||
inline bool file_wrapper::priv_open_or_create
|
||||
(detail::create_enum_t type,
|
||||
(ipcdetail::create_enum_t type,
|
||||
const char *filename,
|
||||
mode_t mode,
|
||||
const permissions &perm = permissions())
|
||||
@@ -148,13 +149,13 @@ inline bool file_wrapper::priv_open_or_create
|
||||
|
||||
//Open file existing native API to obtain the handle
|
||||
switch(type){
|
||||
case detail::DoOpen:
|
||||
case ipcdetail::DoOpen:
|
||||
m_handle = open_existing_file(filename, mode);
|
||||
break;
|
||||
case detail::DoCreate:
|
||||
case ipcdetail::DoCreate:
|
||||
m_handle = create_new_file(filename, mode, perm);
|
||||
break;
|
||||
case detail::DoOpenOrCreate:
|
||||
case ipcdetail::DoOpenOrCreate:
|
||||
m_handle = create_or_open_file(filename, mode, perm);
|
||||
break;
|
||||
default:
|
||||
@@ -192,7 +193,7 @@ inline void file_wrapper::priv_close()
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <typeinfo> //typeid
|
||||
|
||||
//!\file
|
||||
@@ -25,7 +26,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
struct in_place_interface
|
||||
{
|
||||
@@ -46,7 +47,7 @@ template<class T>
|
||||
struct placement_destroy : public in_place_interface
|
||||
{
|
||||
placement_destroy()
|
||||
: in_place_interface(detail::alignment_of<T>::value, sizeof(T), typeid(T).name())
|
||||
: in_place_interface(::boost::alignment_of<T>::value, sizeof(T), typeid(T).name())
|
||||
{}
|
||||
|
||||
virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed)
|
||||
@@ -65,7 +66,7 @@ struct placement_destroy : public in_place_interface
|
||||
|
||||
}
|
||||
}
|
||||
} //namespace boost { namespace interprocess { namespace detail {
|
||||
} //namespace boost { namespace interprocess { namespace ipcdetail {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,15 +18,29 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
||||
#include <boost/interprocess/managed_windows_shared_memory.hpp>
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
#include <boost/interprocess/windows_shared_memory.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/shared_memory_object.hpp>
|
||||
|
||||
#include <boost/interprocess/offset_ptr.hpp>
|
||||
#include <boost/interprocess/sync/spin/mutex.hpp>
|
||||
#include <boost/interprocess/sync/spin/recursive_mutex.hpp>
|
||||
#include <boost/interprocess/detail/managed_memory_impl.hpp>
|
||||
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
|
||||
#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
|
||||
#include <boost/interprocess/indexes/iset_index.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/permissions.hpp>
|
||||
|
||||
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include <boost/interprocess/detail/os_thread_functions.hpp>
|
||||
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
@@ -37,7 +51,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
||||
@@ -50,7 +64,133 @@
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
struct intermodule_singleton_mutex_family
|
||||
{
|
||||
typedef boost::interprocess::ipcdetail::spin_mutex mutex_type;
|
||||
typedef boost::interprocess::ipcdetail::spin_recursive_mutex recursive_mutex_type;
|
||||
};
|
||||
|
||||
struct intermodule_types
|
||||
{
|
||||
//We must use offset_ptr since a loaded DLL can map the singleton holder shared memory
|
||||
//at a different address than other DLLs/main executables
|
||||
typedef rbtree_best_fit<intermodule_singleton_mutex_family, offset_ptr<void> > mem_algo;
|
||||
template<class Device, bool FileBased>
|
||||
struct open_or_create
|
||||
{
|
||||
typedef managed_open_or_create_impl
|
||||
<Device, mem_algo::Alignment, FileBased> type;
|
||||
};
|
||||
};
|
||||
|
||||
template<class Device, bool FileBased>
|
||||
class basic_managed_global_memory
|
||||
: public basic_managed_memory_impl
|
||||
< char
|
||||
, intermodule_types::mem_algo
|
||||
, iset_index
|
||||
, intermodule_types::open_or_create<Device, FileBased>::type::ManagedOpenOrCreateUserOffset
|
||||
>
|
||||
, private intermodule_types::open_or_create<Device, FileBased>::type
|
||||
{
|
||||
/// @cond
|
||||
typedef typename intermodule_types::template open_or_create<Device, FileBased>::type base2_t;
|
||||
|
||||
typedef basic_managed_memory_impl
|
||||
< char
|
||||
, intermodule_types::mem_algo
|
||||
, iset_index
|
||||
, base2_t::ManagedOpenOrCreateUserOffset
|
||||
> base_t;
|
||||
|
||||
typedef create_open_func<base_t> create_open_func_t;
|
||||
|
||||
basic_managed_global_memory *get_this_pointer()
|
||||
{ return this; }
|
||||
|
||||
public:
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
private:
|
||||
typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_managed_global_memory)
|
||||
/// @endcond
|
||||
|
||||
public: //functions
|
||||
/*
|
||||
basic_managed_global_memory()
|
||||
{}
|
||||
|
||||
basic_managed_global_memory(create_only_t create_only, const char *name,
|
||||
size_type size, const void *addr = 0, const permissions& perm = permissions())
|
||||
: base_t()
|
||||
, base2_t(create_only, name, size, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(), DoCreate), perm)
|
||||
{}
|
||||
*/
|
||||
basic_managed_global_memory (open_or_create_t open_or_create,
|
||||
const char *name, size_type size,
|
||||
const void *addr = 0, const permissions& perm = permissions())
|
||||
: base_t()
|
||||
, base2_t(open_or_create, name, size, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
DoOpenOrCreate), perm)
|
||||
{}
|
||||
|
||||
basic_managed_global_memory (open_only_t open_only, const char* name,
|
||||
const void *addr = 0)
|
||||
: base_t()
|
||||
, base2_t(open_only, name, read_write, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
DoOpen))
|
||||
{}
|
||||
|
||||
/*
|
||||
basic_managed_global_memory (open_copy_on_write_t, const char* name,
|
||||
const void *addr = 0)
|
||||
: base_t()
|
||||
, base2_t(open_only, name, copy_on_write, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
DoOpen))
|
||||
{}
|
||||
|
||||
//!Connects to a created shared memory and its segment manager.
|
||||
//!in read-only mode.
|
||||
//!This can throw.
|
||||
basic_managed_global_memory (open_read_only_t, const char* name,
|
||||
const void *addr = 0)
|
||||
: base_t()
|
||||
, base2_t(open_only, name, read_only, addr,
|
||||
create_open_func_t(get_this_pointer(),
|
||||
DoOpen))
|
||||
{}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this.
|
||||
//!Does not throw
|
||||
basic_managed_global_memory(BOOST_RV_REF(basic_managed_global_memory) moved)
|
||||
{
|
||||
basic_managed_global_memory tmp;
|
||||
this->swap(moved);
|
||||
tmp.swap(moved);
|
||||
}
|
||||
|
||||
//!Moves the ownership of "moved"'s managed memory to *this.
|
||||
//!Does not throw
|
||||
basic_managed_global_memory &operator=(BOOST_RV_REF(basic_managed_global_memory) moved)
|
||||
{
|
||||
basic_managed_global_memory tmp(boost::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}*/
|
||||
};
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
typedef basic_managed_global_memory<windows_shared_memory, false> windows_managed_global_memory;
|
||||
#endif
|
||||
|
||||
typedef basic_managed_global_memory<shared_memory_object, true> managed_global_memory;
|
||||
|
||||
namespace file_locking_helpers {
|
||||
|
||||
@@ -171,10 +311,10 @@ struct managed_sh_dependant
|
||||
}
|
||||
};
|
||||
|
||||
#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
template<>
|
||||
struct managed_sh_dependant<managed_windows_shared_memory>
|
||||
struct managed_sh_dependant<windows_managed_global_memory>
|
||||
{
|
||||
static void apply_gmem_erase_logic(const char *, const char *){}
|
||||
|
||||
@@ -580,12 +720,12 @@ struct lock_file_logic
|
||||
bool retry_with_new_shm;
|
||||
};
|
||||
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
template<>
|
||||
struct lock_file_logic<managed_windows_shared_memory>
|
||||
struct lock_file_logic<windows_managed_global_memory>
|
||||
{
|
||||
lock_file_logic(managed_windows_shared_memory &)
|
||||
lock_file_logic(windows_managed_global_memory &)
|
||||
: retry_with_new_shm(false)
|
||||
{}
|
||||
|
||||
@@ -633,11 +773,9 @@ class intermodule_singleton_common
|
||||
private:
|
||||
static ManagedShMem &get_shm()
|
||||
{
|
||||
return *static_cast<ManagedShMem *>(static_cast<void *>(&shm_mem));
|
||||
return *static_cast<ManagedShMem *>(static_cast<void *>(&mem_holder.shm_mem));
|
||||
}
|
||||
|
||||
enum { MemSize = ((sizeof(ManagedShMem)-1)/sizeof(max_align))+1u };
|
||||
|
||||
static void initialize_shm();
|
||||
static void destroy_shm();
|
||||
//Static data, zero-initalized without any dependencies
|
||||
@@ -645,7 +783,11 @@ class intermodule_singleton_common
|
||||
static volatile boost::uint32_t this_module_singleton_count;
|
||||
//this_module_shm_initialized is the state of this module's shm class object
|
||||
static volatile boost::uint32_t this_module_shm_initialized;
|
||||
static max_align shm_mem[MemSize];
|
||||
static struct mem_holder_t
|
||||
{
|
||||
::boost::detail::max_align aligner;
|
||||
char shm_mem [sizeof(ManagedShMem)];
|
||||
} mem_holder;
|
||||
};
|
||||
|
||||
template<class ManagedShMem>
|
||||
@@ -655,16 +797,14 @@ template<class ManagedShMem>
|
||||
volatile boost::uint32_t intermodule_singleton_common<ManagedShMem>::this_module_shm_initialized;
|
||||
|
||||
template<class ManagedShMem>
|
||||
max_align intermodule_singleton_common<ManagedShMem>::shm_mem[intermodule_singleton_common<ManagedShMem>::MemSize];
|
||||
typename intermodule_singleton_common<ManagedShMem>::mem_holder_t
|
||||
intermodule_singleton_common<ManagedShMem>::mem_holder;
|
||||
|
||||
template<class ManagedShMem>
|
||||
void intermodule_singleton_common<ManagedShMem>::initialize_shm()
|
||||
{
|
||||
//Obtain unique shm name and size
|
||||
std::string s;
|
||||
intermodule_singleton_helpers::get_shm_name(s);
|
||||
const char *ShmName = s.c_str();
|
||||
const std::size_t ShmSize = intermodule_singleton_helpers::get_shm_size();;
|
||||
while(1){
|
||||
//Try to pass shm state to initializing
|
||||
::boost::uint32_t tmp = atomic_cas32(&this_module_shm_initialized, Initializing, Uninitialized);
|
||||
@@ -680,6 +820,13 @@ void intermodule_singleton_common<ManagedShMem>::initialize_shm()
|
||||
try{
|
||||
//Remove old shared memory from the system
|
||||
intermodule_singleton_helpers::managed_sh_dependant<ManagedShMem>::remove_old_gmem();
|
||||
//
|
||||
if(s.empty()){
|
||||
intermodule_singleton_helpers::get_shm_name(s);
|
||||
}
|
||||
const char *ShmName = s.c_str();
|
||||
const std::size_t ShmSize = intermodule_singleton_helpers::get_shm_size();;
|
||||
|
||||
//in-place construction of the shared memory class
|
||||
::new (&get_shm())ManagedShMem(open_or_create, ShmName, ShmSize);
|
||||
//Use shared memory internal lock to initialize the lock file
|
||||
@@ -733,12 +880,12 @@ struct unlink_shmlogic
|
||||
ManagedShMem &mshm_;
|
||||
};
|
||||
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
template<>
|
||||
struct unlink_shmlogic<managed_windows_shared_memory>
|
||||
struct unlink_shmlogic<windows_managed_global_memory>
|
||||
{
|
||||
unlink_shmlogic(managed_windows_shared_memory &)
|
||||
unlink_shmlogic(windows_managed_global_memory &)
|
||||
{}
|
||||
void operator()(){}
|
||||
};
|
||||
@@ -822,7 +969,7 @@ void intermodule_singleton_common<ManagedShMem>::initialize_singleton_logic
|
||||
break;
|
||||
}
|
||||
else if(previous_module_singleton_initialized == Initializing){
|
||||
detail::thread_yield();
|
||||
thread_yield();
|
||||
}
|
||||
else{
|
||||
//This can't be happening!
|
||||
@@ -984,14 +1131,14 @@ class intermodule_singleton_impl
|
||||
};
|
||||
|
||||
template <typename C, bool L, class ManagedShMem>
|
||||
volatile int intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type_lazy::m_dummy;
|
||||
volatile int intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type_lazy::m_dummy = 0;
|
||||
|
||||
//These will be zero-initialized by the loader
|
||||
template <typename C, bool L, class ManagedShMem>
|
||||
void *intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_ptr;
|
||||
void *intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_ptr = 0;
|
||||
|
||||
template <typename C, bool L, class ManagedShMem>
|
||||
volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_initialized;
|
||||
volatile boost::uint32_t intermodule_singleton_impl<C, L, ManagedShMem>::this_module_singleton_initialized = 0;
|
||||
|
||||
template <typename C, bool L, class ManagedShMem>
|
||||
typename intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type
|
||||
@@ -999,14 +1146,18 @@ typename intermodule_singleton_impl<C, L, ManagedShMem>::lifetime_type
|
||||
|
||||
template<typename C, bool LazyInit = false>
|
||||
class portable_intermodule_singleton
|
||||
: public intermodule_singleton_impl<C, LazyInit, managed_shared_memory>
|
||||
: public intermodule_singleton_impl<C, LazyInit, managed_global_memory>
|
||||
{};
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
template<typename C, bool LazyInit = false>
|
||||
class windows_intermodule_singleton
|
||||
: public intermodule_singleton_impl<C, LazyInit, managed_windows_shared_memory>
|
||||
: public intermodule_singleton_impl
|
||||
< C
|
||||
, LazyInit
|
||||
, windows_managed_global_memory
|
||||
>
|
||||
{};
|
||||
|
||||
#endif
|
||||
@@ -1018,14 +1169,13 @@ template<typename C, bool LazyInit = false>
|
||||
class intermodule_singleton
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
||||
: public windows_intermodule_singleton<C, LazyInit>
|
||||
// : public portable_intermodule_singleton<C, LazyInit>
|
||||
#else
|
||||
: public portable_intermodule_singleton<C, LazyInit>
|
||||
#endif
|
||||
{};
|
||||
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2007-2011. Distributed under 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)
|
||||
//
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
class interprocess_tester
|
||||
{
|
||||
@@ -23,7 +23,7 @@ class interprocess_tester
|
||||
{ t.dont_close_on_destruction(); }
|
||||
};
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -97,7 +97,7 @@ struct intersegment_base
|
||||
std::size_t pow : pow_size_bits;
|
||||
std::size_t frc : frc_size_bits;
|
||||
std::size_t beg : begin_bits;
|
||||
std::ptrdiff_t off : sizeof(ptrdiff_t)*CHAR_BIT - 2;
|
||||
std::ptrdiff_t off : sizeof(std::ptrdiff_t)*CHAR_BIT - 2;
|
||||
std::ptrdiff_t bits : 2;
|
||||
};
|
||||
|
||||
@@ -153,13 +153,13 @@ struct intersegment_base
|
||||
{
|
||||
if(orig_size < align)
|
||||
orig_size = align;
|
||||
orig_size = detail::get_rounded_size_po2(orig_size, align);
|
||||
pow = detail::floor_log2(orig_size);
|
||||
orig_size = ipcdetail::get_rounded_size_po2(orig_size, align);
|
||||
pow = ipcdetail::floor_log2(orig_size);
|
||||
std::size_t low_size = (std::size_t(1) << pow);
|
||||
std::size_t diff = orig_size - low_size;
|
||||
BOOST_ASSERT(pow >= frc_size_bits);
|
||||
std::size_t rounded = detail::get_rounded_size_po2
|
||||
(diff, (1u << (pow - frc_size_bits)));
|
||||
std::size_t rounded = ipcdetail::get_rounded_size_po2
|
||||
(diff, (std::size_t)(1u << (pow - frc_size_bits)));
|
||||
if(rounded == low_size){
|
||||
++pow;
|
||||
frc = 0;
|
||||
@@ -226,7 +226,7 @@ struct flat_map_intersegment
|
||||
|
||||
//!Obtains the address pointed
|
||||
//!by the object
|
||||
void *get_pointer() const
|
||||
void *to_raw_pointer() const
|
||||
{
|
||||
if(is_null()){
|
||||
return 0;
|
||||
@@ -259,23 +259,23 @@ struct flat_map_intersegment
|
||||
//!This only works with two basic_intersegment_ptr pointing
|
||||
//!to the same segment. Otherwise undefined
|
||||
std::ptrdiff_t diff(const self_t &other) const
|
||||
{ return static_cast<char*>(this->get_pointer()) - static_cast<char*>(other.get_pointer()); }
|
||||
{ return static_cast<char*>(this->to_raw_pointer()) - static_cast<char*>(other.to_raw_pointer()); }
|
||||
|
||||
//!Returns true if both point to
|
||||
//!the same object
|
||||
bool equal(const self_t &y) const
|
||||
{ return this->get_pointer() == y.get_pointer(); }
|
||||
{ return this->to_raw_pointer() == y.to_raw_pointer(); }
|
||||
|
||||
//!Returns true if *this is less than other.
|
||||
//!This only works with two basic_intersegment_ptr pointing
|
||||
//!to the same segment group. Otherwise undefined. Never throws
|
||||
bool less(const self_t &y) const
|
||||
{ return this->get_pointer() < y.get_pointer(); }
|
||||
{ return this->to_raw_pointer() < y.to_raw_pointer(); }
|
||||
|
||||
void swap(self_t &other)
|
||||
{
|
||||
void *ptr_this = this->get_pointer();
|
||||
void *ptr_other = other.get_pointer();
|
||||
void *ptr_this = this->to_raw_pointer();
|
||||
void *ptr_other = other.to_raw_pointer();
|
||||
other.set_from_pointer(ptr_this);
|
||||
this->set_from_pointer(ptr_other);
|
||||
}
|
||||
@@ -344,21 +344,21 @@ struct flat_map_intersegment
|
||||
//!by another flat_map_intersegment
|
||||
void set_from_other(const self_t &other)
|
||||
{
|
||||
this->set_from_pointer(other.get_pointer());
|
||||
this->set_from_pointer(other.to_raw_pointer());
|
||||
}
|
||||
|
||||
//!Increments internal
|
||||
//!offset
|
||||
void inc_offset(std::ptrdiff_t bytes)
|
||||
{
|
||||
this->set_from_pointer(static_cast<char*>(this->get_pointer()) + bytes);
|
||||
this->set_from_pointer(static_cast<char*>(this->to_raw_pointer()) + bytes);
|
||||
}
|
||||
|
||||
//!Decrements internal
|
||||
//!offset
|
||||
void dec_offset(std::ptrdiff_t bytes)
|
||||
{
|
||||
this->set_from_pointer(static_cast<char*>(this->get_pointer()) - bytes);
|
||||
this->set_from_pointer(static_cast<char*>(this->to_raw_pointer()) - bytes);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
@@ -604,7 +604,7 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
|
||||
|
||||
public:
|
||||
typedef T * pointer;
|
||||
typedef typename detail::add_reference<T>::type reference;
|
||||
typedef typename ipcdetail::add_reference<T>::type reference;
|
||||
typedef T value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
@@ -635,31 +635,31 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
|
||||
//!Emulates static_cast operator.
|
||||
//!Never throws.
|
||||
template<class U>
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, detail::static_cast_tag)
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::static_cast_tag)
|
||||
{ base_t::set_from_pointer(static_cast<T*>(r.get())); }
|
||||
|
||||
//!Emulates const_cast operator.
|
||||
//!Never throws.
|
||||
template<class U>
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, detail::const_cast_tag)
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::const_cast_tag)
|
||||
{ base_t::set_from_pointer(const_cast<T*>(r.get())); }
|
||||
|
||||
//!Emulates dynamic_cast operator.
|
||||
//!Never throws.
|
||||
template<class U>
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, detail::dynamic_cast_tag)
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::dynamic_cast_tag)
|
||||
{ base_t::set_from_pointer(dynamic_cast<T*>(r.get())); }
|
||||
|
||||
//!Emulates reinterpret_cast operator.
|
||||
//!Never throws.
|
||||
template<class U>
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, detail::reinterpret_cast_tag)
|
||||
intersegment_ptr(const intersegment_ptr<U> &r, ipcdetail::reinterpret_cast_tag)
|
||||
{ base_t::set_from_pointer(reinterpret_cast<T*>(r.get())); }
|
||||
|
||||
//!Obtains raw pointer from offset.
|
||||
//!Never throws.
|
||||
pointer get()const
|
||||
{ return static_cast<pointer>(base_t::get_pointer()); }
|
||||
{ return static_cast<pointer>(base_t::to_raw_pointer()); }
|
||||
|
||||
//!Pointer-like -> operator. It can return 0 pointer.
|
||||
//!Never throws.
|
||||
@@ -762,7 +762,7 @@ class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>
|
||||
//!This only works with two basic_intersegment_ptr pointing
|
||||
//!to the same segment. Otherwise undefined
|
||||
template <class T2>
|
||||
ptrdiff_t _diff(const intersegment_ptr<T2> &other) const
|
||||
std::ptrdiff_t _diff(const intersegment_ptr<T2> &other) const
|
||||
{ return base_t::diff(other); }
|
||||
|
||||
//!Returns true if both point to the
|
||||
@@ -865,35 +865,35 @@ void swap (boost::interprocess::intersegment_ptr<T> &pt,
|
||||
boost::interprocess::intersegment_ptr<T> &pt2)
|
||||
{ pt.swap(pt2); }
|
||||
|
||||
//!get_pointer() enables boost::mem_fn to recognize intersegment_ptr.
|
||||
//!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
|
||||
//!Never throws.
|
||||
template<class T> inline
|
||||
T * get_pointer(boost::interprocess::intersegment_ptr<T> const & p)
|
||||
T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
|
||||
{ return p.get(); }
|
||||
|
||||
//!Simulation of static_cast between pointers.
|
||||
//!Never throws.
|
||||
template<class T, class U> inline
|
||||
boost::interprocess::intersegment_ptr<T> static_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::static_cast_tag()); }
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::static_cast_tag()); }
|
||||
|
||||
//!Simulation of const_cast between pointers.
|
||||
//!Never throws.
|
||||
template<class T, class U> inline
|
||||
boost::interprocess::intersegment_ptr<T> const_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::const_cast_tag()); }
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::const_cast_tag()); }
|
||||
|
||||
//!Simulation of dynamic_cast between pointers.
|
||||
//!Never throws.
|
||||
template<class T, class U> inline
|
||||
boost::interprocess::intersegment_ptr<T> dynamic_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::dynamic_cast_tag()); }
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::dynamic_cast_tag()); }
|
||||
|
||||
//!Simulation of reinterpret_cast between pointers.
|
||||
//!Never throws.
|
||||
template<class T, class U> inline
|
||||
boost::interprocess::intersegment_ptr<T> reinterpret_pointer_cast(const boost::interprocess::intersegment_ptr<U> &r)
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::detail::reinterpret_cast_tag()); }
|
||||
{ return boost::interprocess::intersegment_ptr<T>(r, boost::interprocess::ipcdetail::reinterpret_cast_tag()); }
|
||||
|
||||
//!Trait class to detect if an smart pointer has
|
||||
//!multi-segment addressing capabilities.
|
||||
@@ -907,10 +907,10 @@ struct is_multisegment_ptr
|
||||
} //namespace interprocess {
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
//!get_pointer() enables boost::mem_fn to recognize intersegment_ptr.
|
||||
//!to_raw_pointer() enables boost::mem_fn to recognize intersegment_ptr.
|
||||
//!Never throws.
|
||||
template<class T> inline
|
||||
T * get_pointer(boost::interprocess::intersegment_ptr<T> const & p)
|
||||
T * to_raw_pointer(boost::interprocess::intersegment_ptr<T> const & p)
|
||||
{ return p.get(); }
|
||||
#endif
|
||||
|
||||
@@ -930,8 +930,6 @@ struct has_trivial_destructor
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#if 0
|
||||
|
||||
//bits
|
||||
@@ -982,7 +980,7 @@ struct has_trivial_destructor
|
||||
|
||||
//!Obtains the address pointed by the
|
||||
//!object
|
||||
void *get_pointer() const
|
||||
void *to_raw_pointer() const
|
||||
{
|
||||
if(this->is_pointee_outside() || this->is_in_stack()){
|
||||
return raw_address();
|
||||
@@ -1033,9 +1031,10 @@ void set_from_pointer(const void *ptr)
|
||||
}
|
||||
|
||||
void set_from_other(const self_t &other)
|
||||
{ this->set_from_pointer(other.get_pointer()); }
|
||||
{ this->set_from_pointer(other.to_raw_pointer()); }
|
||||
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_INTERSEGMENT_PTR_HPP
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_INTERSEGMENT_PTR_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -19,14 +19,10 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
|
||||
#include <boost/interprocess/sync/mutex_family.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/offset_ptr.hpp>
|
||||
#include <boost/interprocess/segment_manager.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
//
|
||||
@@ -43,7 +39,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template<class BasicManagedMemoryImpl>
|
||||
class create_open_func;
|
||||
@@ -86,7 +82,9 @@ class basic_managed_memory_impl
|
||||
typedef MemoryAlgorithm memory_algorithm;
|
||||
typedef typename MemoryAlgorithm::mutex_family mutex_family;
|
||||
typedef CharType char_t;
|
||||
typedef std::ptrdiff_t handle_t;
|
||||
typedef typename MemoryAlgorithm::size_type size_type;
|
||||
typedef typename MemoryAlgorithm::difference_type difference_type;
|
||||
typedef difference_type handle_t;
|
||||
typedef typename segment_manager::
|
||||
const_named_iterator const_named_iterator;
|
||||
typedef typename segment_manager::
|
||||
@@ -102,14 +100,14 @@ class basic_managed_memory_impl
|
||||
|
||||
/// @endcond
|
||||
|
||||
static const std::size_t PayloadPerAllocation = segment_manager::PayloadPerAllocation;
|
||||
static const size_type PayloadPerAllocation = segment_manager::PayloadPerAllocation;
|
||||
|
||||
private:
|
||||
typedef basic_managed_memory_impl
|
||||
<CharType, MemoryAlgorithm, IndexType, Offset> self_t;
|
||||
protected:
|
||||
template<class ManagedMemory>
|
||||
static bool grow(const char *filename, std::size_t extra_bytes)
|
||||
static bool grow(const char *filename, size_type extra_bytes)
|
||||
{
|
||||
typedef typename ManagedMemory::device_type device_type;
|
||||
//Increase file size
|
||||
@@ -135,10 +133,10 @@ class basic_managed_memory_impl
|
||||
static bool shrink_to_fit(const char *filename)
|
||||
{
|
||||
typedef typename ManagedMemory::device_type device_type;
|
||||
std::size_t new_size, old_size;
|
||||
size_type new_size;
|
||||
try{
|
||||
ManagedMemory managed_memory(open_only, filename);
|
||||
old_size = managed_memory.get_size();
|
||||
managed_memory.get_size();
|
||||
managed_memory.self_t::shrink_to_fit();
|
||||
new_size = managed_memory.get_size();
|
||||
}
|
||||
@@ -163,7 +161,7 @@ class basic_managed_memory_impl
|
||||
{ this->close_impl(); }
|
||||
|
||||
//!Places segment manager in the reserved space. This can throw.
|
||||
bool create_impl (void *addr, std::size_t size)
|
||||
bool create_impl (void *addr, size_type size)
|
||||
{
|
||||
if(mp_header) return false;
|
||||
|
||||
@@ -185,7 +183,7 @@ class basic_managed_memory_impl
|
||||
}
|
||||
|
||||
//!Connects to a segment manager in the reserved buffer. Never throws.
|
||||
bool open_impl (void *addr, std::size_t)
|
||||
bool open_impl (void *addr, size_type)
|
||||
{
|
||||
if(mp_header) return false;
|
||||
mp_header = static_cast<segment_manager*>(addr);
|
||||
@@ -211,7 +209,7 @@ class basic_managed_memory_impl
|
||||
}
|
||||
|
||||
//!
|
||||
void grow(std::size_t extra_bytes)
|
||||
void grow(size_type extra_bytes)
|
||||
{ mp_header->grow(extra_bytes); }
|
||||
|
||||
void shrink_to_fit()
|
||||
@@ -228,12 +226,12 @@ class basic_managed_memory_impl
|
||||
{ return reinterpret_cast<char*>(mp_header) - Offset; }
|
||||
|
||||
//!Returns the size of memory segment. Never throws.
|
||||
std::size_t get_size () const
|
||||
size_type get_size () const
|
||||
{ return mp_header->get_size() + Offset; }
|
||||
|
||||
//!Returns the number of free bytes of the memory
|
||||
//!segment
|
||||
std::size_t get_free_memory() const
|
||||
size_type get_free_memory() const
|
||||
{ return mp_header->get_free_memory(); }
|
||||
|
||||
//!Returns the result of "all_memory_deallocated()" function
|
||||
@@ -255,8 +253,8 @@ class basic_managed_memory_impl
|
||||
//!The address must belong to the memory segment. Never throws.
|
||||
handle_t get_handle_from_address (const void *ptr) const
|
||||
{
|
||||
return reinterpret_cast<const char*>(ptr) -
|
||||
reinterpret_cast<const char*>(this->get_address());
|
||||
return (handle_t)(reinterpret_cast<const char*>(ptr) -
|
||||
reinterpret_cast<const char*>(this->get_address()));
|
||||
}
|
||||
|
||||
//!Returns true if the address belongs to the managed memory segment
|
||||
@@ -274,25 +272,25 @@ class basic_managed_memory_impl
|
||||
//!Searches for nbytes of free memory in the segment, marks the
|
||||
//!memory as used and return the pointer to the memory. If no
|
||||
//!memory is available throws a boost::interprocess::bad_alloc exception
|
||||
void* allocate (std::size_t nbytes)
|
||||
void* allocate (size_type nbytes)
|
||||
{ return mp_header->allocate(nbytes); }
|
||||
|
||||
//!Searches for nbytes of free memory in the segment, marks the
|
||||
//!memory as used and return the pointer to the memory. If no memory
|
||||
//!is available returns 0. Never throws.
|
||||
void* allocate (std::size_t nbytes, std::nothrow_t nothrow)
|
||||
void* allocate (size_type nbytes, std::nothrow_t nothrow)
|
||||
{ return mp_header->allocate(nbytes, nothrow); }
|
||||
|
||||
//!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
|
||||
//!must be power of two. If no memory
|
||||
//!is available returns 0. Never throws.
|
||||
void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t nothrow)
|
||||
void * allocate_aligned (size_type nbytes, size_type alignment, std::nothrow_t nothrow)
|
||||
{ return mp_header->allocate_aligned(nbytes, alignment, nothrow); }
|
||||
|
||||
template<class T>
|
||||
std::pair<T *, bool>
|
||||
allocation_command (boost::interprocess::allocation_type command, std::size_t limit_size,
|
||||
std::size_t preferred_size,std::size_t &received_size,
|
||||
allocation_command (boost::interprocess::allocation_type command, size_type limit_size,
|
||||
size_type preferred_size,size_type &received_size,
|
||||
T *reuse_ptr = 0)
|
||||
{
|
||||
return mp_header->allocation_command
|
||||
@@ -302,7 +300,7 @@ class basic_managed_memory_impl
|
||||
//!Allocates nbytes bytes aligned to "alignment" bytes. "alignment"
|
||||
//!must be power of two. If no
|
||||
//!memory is available throws a boost::interprocess::bad_alloc exception
|
||||
void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
|
||||
void * allocate_aligned(size_type nbytes, size_type alignment)
|
||||
{ return mp_header->allocate_aligned(nbytes, alignment); }
|
||||
|
||||
/// @cond
|
||||
@@ -310,24 +308,24 @@ class basic_managed_memory_impl
|
||||
//Experimental. Don't use.
|
||||
|
||||
//!Allocates n_elements of elem_size bytes.
|
||||
multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements)
|
||||
multiallocation_chain allocate_many(size_type elem_bytes, size_type num_elements)
|
||||
{ return mp_header->allocate_many(elem_bytes, num_elements); }
|
||||
|
||||
//!Allocates n_elements, each one of elem_sizes[i] bytes.
|
||||
multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements)
|
||||
multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements)
|
||||
{ return mp_header->allocate_many(elem_sizes, n_elements); }
|
||||
|
||||
//!Allocates n_elements of elem_size bytes.
|
||||
multiallocation_chain allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t nothrow)
|
||||
multiallocation_chain allocate_many(size_type elem_bytes, size_type num_elements, std::nothrow_t nothrow)
|
||||
{ return mp_header->allocate_many(elem_bytes, num_elements, nothrow); }
|
||||
|
||||
//!Allocates n_elements, each one of elem_sizes[i] bytes.
|
||||
multiallocation_chain allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow)
|
||||
multiallocation_chain allocate_many(const size_type *elem_sizes, size_type n_elements, std::nothrow_t nothrow)
|
||||
{ return mp_header->allocate_many(elem_sizes, n_elements, nothrow); }
|
||||
|
||||
//!Allocates n_elements, each one of elem_sizes[i] bytes.
|
||||
void deallocate_many(multiallocation_chain chain)
|
||||
{ return mp_header->deallocate_many(boost::interprocess::move(chain)); }
|
||||
{ return mp_header->deallocate_many(boost::move(chain)); }
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -339,7 +337,7 @@ class basic_managed_memory_impl
|
||||
//!buffer and the object count. If not found returned pointer is 0.
|
||||
//!Never throws.
|
||||
template <class T>
|
||||
std::pair<T*, std::size_t> find (char_ptr_holder_t name)
|
||||
std::pair<T*, size_type> find (char_ptr_holder_t name)
|
||||
{ return mp_header->template find<T>(name); }
|
||||
|
||||
//!Creates a named object or array in memory
|
||||
@@ -581,7 +579,7 @@ class basic_managed_memory_impl
|
||||
//!For all theses reasons, classes with throwing destructors are not
|
||||
//!recommended for memory.
|
||||
template <class T>
|
||||
bool destroy(const detail::unique_instance_t *const )
|
||||
bool destroy(const unique_instance_t *const )
|
||||
{ return mp_header->template destroy<T>(unique_instance); }
|
||||
|
||||
//!Destroys the object (named, unique, or anonymous)
|
||||
@@ -619,19 +617,19 @@ class basic_managed_memory_impl
|
||||
//!Returns the length of an object created with construct/find_or_construct
|
||||
//!functions (1 if is a single element, >=1 if it's an array). Does not throw.
|
||||
template<class T>
|
||||
static std::size_t get_instance_length(const T *ptr)
|
||||
static size_type get_instance_length(const T *ptr)
|
||||
{ return segment_manager::get_instance_length(ptr); }
|
||||
|
||||
//!Preallocates needed index resources to optimize the
|
||||
//!creation of "num" named objects in the memory segment.
|
||||
//!Can throw boost::interprocess::bad_alloc if there is no enough memory.
|
||||
void reserve_named_objects(std::size_t num)
|
||||
void reserve_named_objects(size_type num)
|
||||
{ mp_header->reserve_named_objects(num); }
|
||||
|
||||
//!Preallocates needed index resources to optimize the
|
||||
//!creation of "num" unique objects in the memory segment.
|
||||
//!Can throw boost::interprocess::bad_alloc if there is no enough memory.
|
||||
void reserve_unique_objects(std::size_t num)
|
||||
void reserve_unique_objects(size_type num)
|
||||
{ mp_header->reserve_unique_objects(num); }
|
||||
|
||||
//!Calls shrink_to_fit in both named and unique object indexes
|
||||
@@ -641,12 +639,12 @@ class basic_managed_memory_impl
|
||||
|
||||
//!Returns the number of named objects stored
|
||||
//!in the managed segment.
|
||||
std::size_t get_num_named_objects()
|
||||
size_type get_num_named_objects()
|
||||
{ return mp_header->get_num_named_objects(); }
|
||||
|
||||
//!Returns the number of unique objects stored
|
||||
//!in the managed segment.
|
||||
std::size_t get_num_unique_objects()
|
||||
size_type get_num_unique_objects()
|
||||
{ return mp_header->get_num_unique_objects(); }
|
||||
|
||||
//!Returns a constant iterator to the index storing the
|
||||
@@ -704,7 +702,7 @@ class basic_managed_memory_impl
|
||||
//!buffer and the object count. If not found returned pointer is 0.
|
||||
//!Never throws.
|
||||
template <class T>
|
||||
std::pair<T*, std::size_t> find_no_lock (char_ptr_holder_t name)
|
||||
std::pair<T*, size_type> find_no_lock (char_ptr_holder_t name)
|
||||
{ return mp_header->template find_no_lock<T>(name); }
|
||||
/// @endcond
|
||||
|
||||
@@ -722,13 +720,13 @@ template<class BasicManagedMemoryImpl>
|
||||
class create_open_func
|
||||
{
|
||||
public:
|
||||
create_open_func(BasicManagedMemoryImpl * const frontend, detail::create_enum_t type)
|
||||
create_open_func(BasicManagedMemoryImpl * const frontend, create_enum_t type)
|
||||
: m_frontend(frontend), m_type(type){}
|
||||
|
||||
bool operator()(void *addr, std::size_t size, bool created) const
|
||||
bool operator()(void *addr, typename BasicManagedMemoryImpl::size_type size, bool created) const
|
||||
{
|
||||
if(((m_type == detail::DoOpen) && created) ||
|
||||
((m_type == detail::DoCreate) && !created))
|
||||
if(((m_type == DoOpen) && created) ||
|
||||
((m_type == DoCreate) && !created))
|
||||
return false;
|
||||
|
||||
if(created)
|
||||
@@ -739,10 +737,10 @@ class create_open_func
|
||||
|
||||
private:
|
||||
BasicManagedMemoryImpl *m_frontend;
|
||||
detail::create_enum_t m_type;
|
||||
create_enum_t m_type;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -34,6 +34,10 @@
|
||||
#include <boost/interprocess/streams/vectorstream.hpp>
|
||||
#include <memory>
|
||||
#include <boost/assert.hpp>
|
||||
//These includes needed to fulfill default template parameters of
|
||||
//predeclarations in interprocess_fwd.hpp
|
||||
#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
|
||||
#include <boost/interprocess/sync/mutex_family.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes a named shared memory object allocation user class.
|
||||
@@ -57,16 +61,21 @@ template
|
||||
template<class IndexConfig> class IndexType
|
||||
>
|
||||
class basic_managed_multi_shared_memory
|
||||
: public detail::basic_managed_memory_impl
|
||||
: public ipcdetail::basic_managed_memory_impl
|
||||
<CharType, MemoryAlgorithm, IndexType>
|
||||
{
|
||||
|
||||
typedef basic_managed_multi_shared_memory
|
||||
<CharType, MemoryAlgorithm, IndexType> self_t;
|
||||
typedef ipcdetail::basic_managed_memory_impl
|
||||
<CharType, MemoryAlgorithm, IndexType> base_t;
|
||||
|
||||
typedef typename MemoryAlgorithm::void_pointer void_pointer;
|
||||
typedef typename detail::
|
||||
managed_open_or_create_impl<shared_memory_object> managed_impl;
|
||||
typedef typename ipcdetail::
|
||||
managed_open_or_create_impl<shared_memory_object, MemoryAlgorithm::Alignment> managed_impl;
|
||||
typedef typename void_pointer::segment_group_id segment_group_id;
|
||||
typedef typename base_t::size_type size_type;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Some internal helper structs/functors
|
||||
@@ -86,7 +95,7 @@ class basic_managed_multi_shared_memory
|
||||
// const void *addr)
|
||||
// : m_shmem(shmem), m_mem_name(mem_name), m_addr(addr){}
|
||||
//
|
||||
// void *operator()(std::size_t size)
|
||||
// void *operator()(size_type size)
|
||||
// {
|
||||
// if(!m_shmem.create(m_mem_name, size, m_addr))
|
||||
// return 0;
|
||||
@@ -102,7 +111,7 @@ class basic_managed_multi_shared_memory
|
||||
: public multi_segment_services
|
||||
{
|
||||
public:
|
||||
typedef std::pair<void *, std::size_t> result_type;
|
||||
typedef std::pair<void *, size_type> result_type;
|
||||
typedef basic_managed_multi_shared_memory frontend_t;
|
||||
typedef typename
|
||||
basic_managed_multi_shared_memory::void_pointer void_pointer;
|
||||
@@ -110,8 +119,9 @@ class basic_managed_multi_shared_memory
|
||||
group_services(frontend_t *const frontend)
|
||||
: mp_frontend(frontend), m_group(0), m_min_segment_size(0){}
|
||||
|
||||
virtual std::pair<void *, std::size_t> create_new_segment(std::size_t alloc_size)
|
||||
{
|
||||
virtual std::pair<void *, size_type> create_new_segment(size_type alloc_size)
|
||||
{ (void)alloc_size;
|
||||
/*
|
||||
//We should allocate an extra byte so that the
|
||||
//[base_addr + alloc_size] byte belongs to this segment
|
||||
alloc_size += 1;
|
||||
@@ -121,9 +131,9 @@ class basic_managed_multi_shared_memory
|
||||
m_min_segment_size : alloc_size;
|
||||
if(mp_frontend->priv_new_segment(create_open_func::DoCreate,
|
||||
alloc_size, 0, permissions())){
|
||||
shmem_list_t::value_type &m_impl = *mp_frontend->m_shmem_list.rbegin();
|
||||
typename shmem_list_t::value_type &m_impl = *mp_frontend->m_shmem_list.rbegin();
|
||||
return result_type(m_impl.get_real_address(), m_impl.get_real_size()-1);
|
||||
}
|
||||
}*/
|
||||
return result_type(static_cast<void *>(0), 0);
|
||||
}
|
||||
|
||||
@@ -138,17 +148,17 @@ class basic_managed_multi_shared_memory
|
||||
segment_group_id get_group() const
|
||||
{ return m_group; }
|
||||
|
||||
void set_min_segment_size(std::size_t min_segment_size)
|
||||
void set_min_segment_size(size_type min_segment_size)
|
||||
{ m_min_segment_size = min_segment_size; }
|
||||
|
||||
std::size_t get_min_segment_size() const
|
||||
size_type get_min_segment_size() const
|
||||
{ return m_min_segment_size; }
|
||||
|
||||
private:
|
||||
|
||||
frontend_t * const mp_frontend;
|
||||
segment_group_id m_group;
|
||||
std::size_t m_min_segment_size;
|
||||
size_type m_min_segment_size;
|
||||
};
|
||||
|
||||
//!Functor to execute atomically when opening or creating a shared memory
|
||||
@@ -160,10 +170,10 @@ class basic_managed_multi_shared_memory
|
||||
basic_managed_multi_shared_memory::void_pointer void_pointer;
|
||||
|
||||
create_open_func(self_t * const frontend,
|
||||
type_t type, std::size_t segment_number)
|
||||
type_t type, size_type segment_number)
|
||||
: mp_frontend(frontend), m_type(type), m_segment_number(segment_number){}
|
||||
|
||||
bool operator()(void *addr, std::size_t size, bool created) const
|
||||
bool operator()(void *addr, size_type size, bool created) const
|
||||
{
|
||||
if(((m_type == DoOpen) && created) ||
|
||||
((m_type == DoCreate) && !created))
|
||||
@@ -203,7 +213,7 @@ class basic_managed_multi_shared_memory
|
||||
}
|
||||
self_t * const mp_frontend;
|
||||
type_t m_type;
|
||||
std::size_t m_segment_number;
|
||||
size_type m_segment_number;
|
||||
};
|
||||
|
||||
//!Functor to execute atomically when closing a shared memory segment.
|
||||
@@ -223,9 +233,6 @@ class basic_managed_multi_shared_memory
|
||||
self_t * const mp_frontend;
|
||||
};
|
||||
|
||||
typedef detail::basic_managed_memory_impl
|
||||
<CharType, MemoryAlgorithm, IndexType> base_t;
|
||||
|
||||
//Friend declarations
|
||||
friend struct basic_managed_multi_shared_memory::create_open_func;
|
||||
friend struct basic_managed_multi_shared_memory::close_func;
|
||||
@@ -240,7 +247,7 @@ class basic_managed_multi_shared_memory
|
||||
|
||||
basic_managed_multi_shared_memory(create_only_t,
|
||||
const char *name,
|
||||
std::size_t size,
|
||||
size_type size,
|
||||
const permissions &perm = permissions())
|
||||
: m_group_services(get_this_pointer())
|
||||
{
|
||||
@@ -249,7 +256,7 @@ class basic_managed_multi_shared_memory
|
||||
|
||||
basic_managed_multi_shared_memory(open_or_create_t,
|
||||
const char *name,
|
||||
std::size_t size,
|
||||
size_type size,
|
||||
const permissions &perm = permissions())
|
||||
: m_group_services(get_this_pointer())
|
||||
{
|
||||
@@ -268,7 +275,7 @@ class basic_managed_multi_shared_memory
|
||||
private:
|
||||
bool priv_open_or_create(typename create_open_func::type_t type,
|
||||
const char *name,
|
||||
std::size_t size,
|
||||
size_type size,
|
||||
const permissions &perm)
|
||||
{
|
||||
if(!m_shmem_list.empty())
|
||||
@@ -298,17 +305,17 @@ class basic_managed_multi_shared_memory
|
||||
}
|
||||
|
||||
bool priv_new_segment(typename create_open_func::type_t type,
|
||||
std::size_t size,
|
||||
size_type size,
|
||||
const void *addr,
|
||||
const permissions &perm)
|
||||
{
|
||||
BOOST_TRY{
|
||||
//Get the number of groups of this multi_segment group
|
||||
std::size_t segment_id = m_shmem_list.size();
|
||||
size_type segment_id = m_shmem_list.size();
|
||||
//Format the name of the shared memory: append segment number.
|
||||
boost::interprocess::basic_ovectorstream<boost::interprocess::string> formatter;
|
||||
//Pre-reserve string size
|
||||
std::size_t str_size = m_root_name.length()+10;
|
||||
size_type str_size = m_root_name.length()+10;
|
||||
if(formatter.vector().size() < str_size){
|
||||
//This can throw.
|
||||
formatter.reserve(str_size);
|
||||
@@ -326,21 +333,21 @@ class basic_managed_multi_shared_memory
|
||||
case create_open_func::DoCreate:
|
||||
{
|
||||
managed_impl shm(create_only, name, size, read_write, addr, func, perm);
|
||||
mshm = boost::interprocess::move(shm);
|
||||
mshm = boost::move(shm);
|
||||
}
|
||||
break;
|
||||
|
||||
case create_open_func::DoOpen:
|
||||
{
|
||||
managed_impl shm(open_only, name,read_write, addr, func);
|
||||
mshm = boost::interprocess::move(shm);
|
||||
mshm = boost::move(shm);
|
||||
}
|
||||
break;
|
||||
|
||||
case create_open_func::DoOpenOrCreate:
|
||||
{
|
||||
managed_impl shm(open_or_create, name, size, read_write, addr, func, perm);
|
||||
mshm = boost::interprocess::move(shm);
|
||||
mshm = boost::move(shm);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -350,7 +357,7 @@ class basic_managed_multi_shared_memory
|
||||
}
|
||||
|
||||
//This can throw.
|
||||
m_shmem_list.push_back(boost::interprocess::move(mshm));
|
||||
m_shmem_list.push_back(boost::move(mshm));
|
||||
return true;
|
||||
}
|
||||
BOOST_CATCH(const std::bad_alloc&){
|
||||
@@ -367,12 +374,13 @@ class basic_managed_multi_shared_memory
|
||||
//Obtain group identifier
|
||||
segment_group_id group = m_group_services.get_group();
|
||||
//Erase main segment and its resources
|
||||
shmem_list_t::iterator itbeg = m_shmem_list.begin(),
|
||||
itend = m_shmem_list.end(),
|
||||
it = itbeg;
|
||||
//typename shmem_list_t::iterator itbeg = m_shmem_list.begin(),
|
||||
// itend = m_shmem_list.end(),
|
||||
// it = itbeg;
|
||||
//(*itbeg)->close_with_func(close_func(this));
|
||||
//Delete group. All mappings are erased too.
|
||||
ret = void_pointer::delete_group(group);
|
||||
(void)ret;
|
||||
BOOST_ASSERT(ret);
|
||||
m_shmem_list.clear();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#ifndef BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL
|
||||
#define BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/os_thread_functions.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
@@ -21,25 +22,77 @@
|
||||
#include <boost/interprocess/detail/interprocess_tester.hpp>
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/interprocess/permissions.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
/// @cond
|
||||
namespace detail{ class interprocess_tester; }
|
||||
namespace ipcdetail{ class interprocess_tester; }
|
||||
|
||||
|
||||
template<class DeviceAbstraction>
|
||||
struct managed_open_or_create_impl_device_id_t
|
||||
{
|
||||
typedef const char *type;
|
||||
};
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
|
||||
|
||||
class xsi_shared_memory_file_wrapper;
|
||||
class xsi_key;
|
||||
|
||||
template<>
|
||||
struct managed_open_or_create_impl_device_id_t<xsi_shared_memory_file_wrapper>
|
||||
{
|
||||
typedef xsi_key type;
|
||||
};
|
||||
|
||||
#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
|
||||
|
||||
/// @endcond
|
||||
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template<class DeviceAbstraction, bool FileBased = true>
|
||||
|
||||
template <bool StoreDevice, class DeviceAbstraction>
|
||||
class managed_open_or_create_impl_device_holder
|
||||
{
|
||||
public:
|
||||
DeviceAbstraction &get_device()
|
||||
{ static DeviceAbstraction dev; return dev; }
|
||||
|
||||
const DeviceAbstraction &get_device() const
|
||||
{ static DeviceAbstraction dev; return dev; }
|
||||
};
|
||||
|
||||
template <class DeviceAbstraction>
|
||||
class managed_open_or_create_impl_device_holder<true, DeviceAbstraction>
|
||||
{
|
||||
public:
|
||||
DeviceAbstraction &get_device()
|
||||
{ return dev; }
|
||||
|
||||
const DeviceAbstraction &get_device() const
|
||||
{ return dev; }
|
||||
|
||||
private:
|
||||
DeviceAbstraction dev;
|
||||
};
|
||||
|
||||
template<class DeviceAbstraction, std::size_t MemAlignment = 0, bool FileBased = true, bool StoreDevice = true>
|
||||
class managed_open_or_create_impl
|
||||
: public managed_open_or_create_impl_device_holder<StoreDevice, DeviceAbstraction>
|
||||
{
|
||||
//Non-copyable
|
||||
BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(managed_open_or_create_impl)
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(managed_open_or_create_impl)
|
||||
|
||||
typedef typename managed_open_or_create_impl_device_id_t<DeviceAbstraction>::type device_id_t;
|
||||
typedef managed_open_or_create_impl_device_holder<StoreDevice, DeviceAbstraction> DevHolder;
|
||||
enum
|
||||
{
|
||||
UninitializedSegment,
|
||||
@@ -51,23 +104,25 @@ class managed_open_or_create_impl
|
||||
public:
|
||||
static const std::size_t
|
||||
ManagedOpenOrCreateUserOffset =
|
||||
detail::ct_rounded_size
|
||||
ct_rounded_size
|
||||
< sizeof(boost::uint32_t)
|
||||
, detail::alignment_of<detail::max_align>::value>::value;
|
||||
, MemAlignment ? (MemAlignment) :
|
||||
(::boost::alignment_of< ::boost::detail::max_align >::value)
|
||||
>::value;
|
||||
|
||||
managed_open_or_create_impl()
|
||||
{}
|
||||
|
||||
managed_open_or_create_impl(create_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoCreate
|
||||
( DoCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -76,13 +131,13 @@ class managed_open_or_create_impl
|
||||
}
|
||||
|
||||
managed_open_or_create_impl(open_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
mode_t mode,
|
||||
const void *addr)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpen
|
||||
( DoOpen
|
||||
, id
|
||||
, 0
|
||||
, mode
|
||||
, addr
|
||||
@@ -92,15 +147,15 @@ class managed_open_or_create_impl
|
||||
|
||||
|
||||
managed_open_or_create_impl(open_or_create_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpenOrCreate
|
||||
( DoOpenOrCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -110,16 +165,16 @@ class managed_open_or_create_impl
|
||||
|
||||
template <class ConstructFunc>
|
||||
managed_open_or_create_impl(create_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const ConstructFunc &construct_func,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
(detail::DoCreate
|
||||
(DoCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -129,14 +184,14 @@ class managed_open_or_create_impl
|
||||
|
||||
template <class ConstructFunc>
|
||||
managed_open_or_create_impl(open_only_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const ConstructFunc &construct_func)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpen
|
||||
( DoOpen
|
||||
, id
|
||||
, 0
|
||||
, mode
|
||||
, addr
|
||||
@@ -146,16 +201,16 @@ class managed_open_or_create_impl
|
||||
|
||||
template <class ConstructFunc>
|
||||
managed_open_or_create_impl(open_or_create_t,
|
||||
const char *name,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode,
|
||||
const void *addr,
|
||||
const ConstructFunc &construct_func,
|
||||
const permissions &perm)
|
||||
{
|
||||
m_name = name;
|
||||
priv_open_or_create
|
||||
( detail::DoOpenOrCreate
|
||||
( DoOpenOrCreate
|
||||
, id
|
||||
, size
|
||||
, mode
|
||||
, addr
|
||||
@@ -163,12 +218,12 @@ class managed_open_or_create_impl
|
||||
, construct_func);
|
||||
}
|
||||
|
||||
managed_open_or_create_impl(BOOST_INTERPROCESS_RV_REF(managed_open_or_create_impl) moved)
|
||||
managed_open_or_create_impl(BOOST_RV_REF(managed_open_or_create_impl) moved)
|
||||
{ this->swap(moved); }
|
||||
|
||||
managed_open_or_create_impl &operator=(BOOST_INTERPROCESS_RV_REF(managed_open_or_create_impl) moved)
|
||||
managed_open_or_create_impl &operator=(BOOST_RV_REF(managed_open_or_create_impl) moved)
|
||||
{
|
||||
managed_open_or_create_impl tmp(boost::interprocess::move(moved));
|
||||
managed_open_or_create_impl tmp(boost::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
@@ -190,54 +245,69 @@ class managed_open_or_create_impl
|
||||
|
||||
void swap(managed_open_or_create_impl &other)
|
||||
{
|
||||
this->m_name.swap(other.m_name);
|
||||
this->m_mapped_region.swap(other.m_mapped_region);
|
||||
}
|
||||
|
||||
const char *get_name() const
|
||||
{ return m_name.c_str(); }
|
||||
|
||||
bool flush()
|
||||
{ return m_mapped_region.flush(); }
|
||||
|
||||
|
||||
const mapped_region &get_mapped_region() const
|
||||
{ return m_mapped_region; }
|
||||
|
||||
|
||||
DeviceAbstraction &get_device()
|
||||
{ return this->DevHolder::get_device(); }
|
||||
|
||||
const DeviceAbstraction &get_device() const
|
||||
{ return this->DevHolder::get_device(); }
|
||||
|
||||
private:
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
template<bool dummy>
|
||||
static void truncate_device(DeviceAbstraction &, std::size_t, detail::false_)
|
||||
static void truncate_device(DeviceAbstraction &, offset_t, false_)
|
||||
{} //Empty
|
||||
|
||||
template<bool dummy>
|
||||
static void truncate_device(DeviceAbstraction &dev, std::size_t size, detail::true_)
|
||||
static void truncate_device(DeviceAbstraction &dev, offset_t size, true_)
|
||||
{ dev.truncate(size); }
|
||||
|
||||
|
||||
template<bool dummy>
|
||||
static bool check_offset_t_size(std::size_t , false_)
|
||||
{ return true; } //Empty
|
||||
|
||||
template<bool dummy>
|
||||
static bool check_offset_t_size(std::size_t size, true_)
|
||||
{ return size == std::size_t(offset_t(size)); }
|
||||
|
||||
//These are templatized to allow explicit instantiations
|
||||
template<bool dummy>
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t size, const permissions &perm, detail::false_)
|
||||
static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t size, const permissions &perm, false_ file_like)
|
||||
{
|
||||
DeviceAbstraction tmp(create_only, name, read_write, size, perm);
|
||||
(void)file_like;
|
||||
DeviceAbstraction tmp(create_only, id, read_write, size, perm);
|
||||
tmp.swap(dev);
|
||||
}
|
||||
|
||||
template<bool dummy>
|
||||
static void create_device(DeviceAbstraction &dev, const char *name, std::size_t, const permissions &perm, detail::true_)
|
||||
static void create_device(DeviceAbstraction &dev, const device_id_t & id, std::size_t, const permissions &perm, true_ file_like)
|
||||
{
|
||||
DeviceAbstraction tmp(create_only, name, read_write, perm);
|
||||
(void)file_like;
|
||||
DeviceAbstraction tmp(create_only, id, read_write, perm);
|
||||
tmp.swap(dev);
|
||||
}
|
||||
|
||||
template <class ConstructFunc> inline
|
||||
void priv_open_or_create
|
||||
(detail::create_enum_t type, std::size_t size,
|
||||
(create_enum_t type,
|
||||
const device_id_t & id,
|
||||
std::size_t size,
|
||||
mode_t mode, const void *addr,
|
||||
const permissions &perm,
|
||||
ConstructFunc construct_func)
|
||||
{
|
||||
typedef detail::bool_<FileBased> file_like_t;
|
||||
typedef bool_<FileBased> file_like_t;
|
||||
(void)mode;
|
||||
error_info err;
|
||||
bool created = false;
|
||||
@@ -245,32 +315,35 @@ class managed_open_or_create_impl
|
||||
bool cow = false;
|
||||
DeviceAbstraction dev;
|
||||
|
||||
if(type != detail::DoOpen && size < ManagedOpenOrCreateUserOffset){
|
||||
if(type != DoOpen && size < ManagedOpenOrCreateUserOffset){
|
||||
throw interprocess_exception(error_info(size_error));
|
||||
}
|
||||
|
||||
if(type == detail::DoOpen && mode == read_write){
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_write);
|
||||
//Check size can be represented by offset_t (used by truncate)
|
||||
if(type != DoOpen && !check_offset_t_size<FileBased>(size, file_like_t())){
|
||||
throw interprocess_exception(error_info(size_error));
|
||||
}
|
||||
if(type == DoOpen && mode == read_write){
|
||||
DeviceAbstraction tmp(open_only, id, read_write);
|
||||
tmp.swap(dev);
|
||||
created = false;
|
||||
}
|
||||
else if(type == detail::DoOpen && mode == read_only){
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_only);
|
||||
else if(type == DoOpen && mode == read_only){
|
||||
DeviceAbstraction tmp(open_only, id, read_only);
|
||||
tmp.swap(dev);
|
||||
created = false;
|
||||
ronly = true;
|
||||
}
|
||||
else if(type == detail::DoOpen && mode == copy_on_write){
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_only);
|
||||
else if(type == DoOpen && mode == copy_on_write){
|
||||
DeviceAbstraction tmp(open_only, id, read_only);
|
||||
tmp.swap(dev);
|
||||
created = false;
|
||||
cow = true;
|
||||
}
|
||||
else if(type == detail::DoCreate){
|
||||
create_device<FileBased>(dev, m_name.c_str(), size, perm, file_like_t());
|
||||
else if(type == DoCreate){
|
||||
create_device<FileBased>(dev, id, size, perm, file_like_t());
|
||||
created = true;
|
||||
}
|
||||
else if(type == detail::DoOpenOrCreate){
|
||||
else if(type == DoOpenOrCreate){
|
||||
//This loop is very ugly, but brute force is sometimes better
|
||||
//than diplomacy. If someone knows how to open or create a
|
||||
//file and know if we have really created it or just open it
|
||||
@@ -278,7 +351,7 @@ class managed_open_or_create_impl
|
||||
bool completed = false;
|
||||
while(!completed){
|
||||
try{
|
||||
create_device<FileBased>(dev, m_name.c_str(), size, perm, file_like_t());
|
||||
create_device<FileBased>(dev, id, size, perm, file_like_t());
|
||||
created = true;
|
||||
completed = true;
|
||||
}
|
||||
@@ -288,7 +361,7 @@ class managed_open_or_create_impl
|
||||
}
|
||||
else{
|
||||
try{
|
||||
DeviceAbstraction tmp(open_only, m_name.c_str(), read_write);
|
||||
DeviceAbstraction tmp(open_only, id, read_write);
|
||||
dev.swap(tmp);
|
||||
created = false;
|
||||
completed = true;
|
||||
@@ -298,9 +371,15 @@ class managed_open_or_create_impl
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
detail::thread_yield();
|
||||
catch(...){
|
||||
throw;
|
||||
}
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +392,7 @@ class managed_open_or_create_impl
|
||||
mapped_region region(dev, read_write, 0, 0, addr);
|
||||
boost::uint32_t *patomic_word = 0; //avoid gcc warning
|
||||
patomic_word = static_cast<boost::uint32_t*>(region.get_address());
|
||||
boost::uint32_t previous = detail::atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment);
|
||||
boost::uint32_t previous = atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment);
|
||||
|
||||
if(previous == UninitializedSegment){
|
||||
try{
|
||||
@@ -322,10 +401,10 @@ class managed_open_or_create_impl
|
||||
m_mapped_region.swap(region);
|
||||
}
|
||||
catch(...){
|
||||
detail::atomic_write32(patomic_word, CorruptedSegment);
|
||||
atomic_write32(patomic_word, CorruptedSegment);
|
||||
throw;
|
||||
}
|
||||
detail::atomic_write32(patomic_word, InitializedSegment);
|
||||
atomic_write32(patomic_word, InitializedSegment);
|
||||
}
|
||||
else if(previous == InitializingSegment || previous == InitializedSegment){
|
||||
throw interprocess_exception(error_info(already_exists_error));
|
||||
@@ -347,10 +426,10 @@ class managed_open_or_create_impl
|
||||
if(FileBased){
|
||||
offset_t filesize = 0;
|
||||
while(filesize == 0){
|
||||
if(!detail::get_file_size(detail::file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){
|
||||
if(!get_file_size(file_handle_from_mapping_handle(dev.get_mapping_handle()), filesize)){
|
||||
throw interprocess_exception(error_info(system_error_code()));
|
||||
}
|
||||
detail::thread_yield();
|
||||
thread_yield();
|
||||
}
|
||||
if(filesize == 1){
|
||||
throw interprocess_exception(error_info(corrupted_error));
|
||||
@@ -360,11 +439,11 @@ class managed_open_or_create_impl
|
||||
mapped_region region(dev, ronly ? read_only : (cow ? copy_on_write : read_write), 0, 0, addr);
|
||||
|
||||
boost::uint32_t *patomic_word = static_cast<boost::uint32_t*>(region.get_address());
|
||||
boost::uint32_t value = detail::atomic_read32(patomic_word);
|
||||
boost::uint32_t value = atomic_read32(patomic_word);
|
||||
|
||||
while(value == InitializingSegment || value == UninitializedSegment){
|
||||
detail::thread_yield();
|
||||
value = detail::atomic_read32(patomic_word);
|
||||
thread_yield();
|
||||
value = atomic_read32(patomic_word);
|
||||
}
|
||||
|
||||
if(value != InitializedSegment)
|
||||
@@ -376,15 +455,17 @@ class managed_open_or_create_impl
|
||||
//All ok, just move resources to the external mapped region
|
||||
m_mapped_region.swap(region);
|
||||
}
|
||||
if(StoreDevice){
|
||||
this->DevHolder::get_device() = boost::move(dev);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class detail::interprocess_tester;
|
||||
friend class interprocess_tester;
|
||||
void dont_close_on_destruction()
|
||||
{ detail::interprocess_tester::dont_close_on_destruction(m_mapped_region); }
|
||||
{ interprocess_tester::dont_close_on_destruction(m_mapped_region); }
|
||||
|
||||
mapped_region m_mapped_region;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
template<class DeviceAbstraction>
|
||||
@@ -392,9 +473,11 @@ inline void swap(managed_open_or_create_impl<DeviceAbstraction> &x
|
||||
,managed_open_or_create_impl<DeviceAbstraction> &y)
|
||||
{ x.swap(y); }
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_MANAGED_OPEN_OR_CREATE_IMPL
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Stephen Cleary 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2011.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
// Greatest common divisor and least common multiple
|
||||
|
||||
@@ -103,7 +103,7 @@ inline std::size_t floor_log2 (std::size_t x)
|
||||
return log2;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ipcdetail
|
||||
} // namespace interprocess
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template <class T, T val>
|
||||
struct integral_constant
|
||||
@@ -71,7 +71,7 @@ class is_convertible
|
||||
static false_t dispatch(...);
|
||||
static T trigger();
|
||||
public:
|
||||
enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
|
||||
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
||||
};
|
||||
|
||||
template<
|
||||
@@ -144,7 +144,7 @@ struct ls_zeros<1>
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
||||
#include <boost/interprocess/detail/preprocessor.hpp>
|
||||
#else
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/interprocess/detail/variadic_templates_tools.hpp>
|
||||
#endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
||||
|
||||
template<class T, bool is_iterator, class ...Args>
|
||||
struct CtorNArg : public placement_destroy<T>
|
||||
{
|
||||
typedef detail::bool_<is_iterator> IsIterator;
|
||||
typedef bool_<is_iterator> IsIterator;
|
||||
typedef CtorNArg<T, is_iterator, Args...> self_t;
|
||||
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
||||
|
||||
@@ -71,15 +71,15 @@ struct CtorNArg : public placement_destroy<T>
|
||||
|
||||
private:
|
||||
template<int ...IdxPack>
|
||||
void construct(void *mem, detail::true_, const index_tuple<IdxPack...>&)
|
||||
{ new((void*)mem)T(*boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
|
||||
void construct(void *mem, true_, const index_tuple<IdxPack...>&)
|
||||
{ new((void*)mem)T(*boost::forward<Args>(get<IdxPack>(args_))...); }
|
||||
|
||||
template<int ...IdxPack>
|
||||
void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&)
|
||||
{ new((void*)mem)T(boost::interprocess::forward<Args>(get<IdxPack>(args_))...); }
|
||||
void construct(void *mem, false_, const index_tuple<IdxPack...>&)
|
||||
{ new((void*)mem)T(boost::forward<Args>(get<IdxPack>(args_))...); }
|
||||
|
||||
template<int ...IdxPack>
|
||||
void do_increment(detail::true_, const index_tuple<IdxPack...>&)
|
||||
void do_increment(true_, const index_tuple<IdxPack...>&)
|
||||
{
|
||||
this->expansion_helper(++get<IdxPack>(args_)...);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ struct CtorNArg : public placement_destroy<T>
|
||||
{}
|
||||
|
||||
template<int ...IdxPack>
|
||||
void do_increment(detail::false_, const index_tuple<IdxPack...>&)
|
||||
void do_increment(false_, const index_tuple<IdxPack...>&)
|
||||
{}
|
||||
|
||||
tuple<Args&...> args_;
|
||||
@@ -121,7 +121,7 @@ class named_proxy
|
||||
T *operator()(Args &&...args) const
|
||||
{
|
||||
CtorNArg<T, is_iterator, Args...> &&ctor_obj = CtorNArg<T, is_iterator, Args...>
|
||||
(boost::interprocess::forward<Args>(args)...);
|
||||
(boost::forward<Args>(args)...);
|
||||
return mp_mngr->template
|
||||
generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
|
||||
}
|
||||
@@ -163,13 +163,13 @@ struct Ctor0Arg : public placement_destroy<T>
|
||||
// struct Ctor2Arg
|
||||
// : public placement_destroy<T>
|
||||
// {
|
||||
// typedef detail::bool_<is_iterator> IsIterator;
|
||||
// typedef bool_<is_iterator> IsIterator;
|
||||
// typedef Ctor2Arg self_t;
|
||||
//
|
||||
// void do_increment(detail::false_)
|
||||
// void do_increment(false_)
|
||||
// { ++m_p1; ++m_p2; }
|
||||
//
|
||||
// void do_increment(detail::true_){}
|
||||
// void do_increment(true_){}
|
||||
//
|
||||
// self_t& operator++()
|
||||
// {
|
||||
@@ -197,10 +197,10 @@ struct Ctor0Arg : public placement_destroy<T>
|
||||
// }
|
||||
//
|
||||
// private:
|
||||
// void construct(void *mem, detail::true_)
|
||||
// void construct(void *mem, true_)
|
||||
// { new((void*)mem)T(*m_p1, *m_p2); }
|
||||
//
|
||||
// void construct(void *mem, detail::false_)
|
||||
// void construct(void *mem, false_)
|
||||
// { new((void*)mem)T(m_p1, m_p2); }
|
||||
//
|
||||
// P1 &m_p1; P2 &m_p2;
|
||||
@@ -218,13 +218,13 @@ struct Ctor0Arg : public placement_destroy<T>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
|
||||
: public placement_destroy<T> \
|
||||
{ \
|
||||
typedef detail::bool_<is_iterator> IsIterator; \
|
||||
typedef bool_<is_iterator> IsIterator; \
|
||||
typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) self_t; \
|
||||
\
|
||||
void do_increment(detail::true_) \
|
||||
{ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INC, _); } \
|
||||
void do_increment(true_) \
|
||||
{ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_INC, _); } \
|
||||
\
|
||||
void do_increment(detail::false_){} \
|
||||
void do_increment(false_){} \
|
||||
\
|
||||
self_t& operator++() \
|
||||
{ \
|
||||
@@ -236,7 +236,7 @@ struct Ctor0Arg : public placement_destroy<T>
|
||||
\
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
|
||||
( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _) ) \
|
||||
: BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \
|
||||
: BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_INIT, _) {} \
|
||||
\
|
||||
virtual void construct_n(void *mem \
|
||||
, std::size_t num \
|
||||
@@ -250,19 +250,19 @@ struct Ctor0Arg : public placement_destroy<T>
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
void construct(void *mem, detail::true_) \
|
||||
void construct(void *mem, true_) \
|
||||
{ \
|
||||
new((void*)mem) T \
|
||||
(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD, _)); \
|
||||
} \
|
||||
\
|
||||
void construct(void *mem, detail::false_) \
|
||||
void construct(void *mem, false_) \
|
||||
{ \
|
||||
new((void*)mem) T \
|
||||
(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
|
||||
} \
|
||||
\
|
||||
BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
|
||||
BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_PP_PARAM_DEFINE, _) \
|
||||
}; \
|
||||
//!
|
||||
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
|
||||
@@ -342,7 +342,7 @@ class named_proxy
|
||||
|
||||
#endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
||||
|
||||
}}} //namespace boost { namespace interprocess { namespace detail {
|
||||
}}} //namespace boost { namespace interprocess { namespace ipcdetail {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <boost/interprocess/permissions.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
|
||||
#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
# include <boost/interprocess/detail/win32_api.hpp>
|
||||
@@ -64,7 +66,7 @@ typedef enum { file_begin = winapi::file_begin
|
||||
, file_current = winapi::file_current
|
||||
} file_pos_t;
|
||||
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
|
||||
{
|
||||
@@ -93,7 +95,7 @@ inline const char *get_temporary_path()
|
||||
|
||||
|
||||
inline file_handle_t create_new_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
|
||||
return winapi::create_file
|
||||
@@ -102,7 +104,7 @@ inline file_handle_t create_new_file
|
||||
}
|
||||
|
||||
inline file_handle_t create_or_open_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
|
||||
return winapi::create_file
|
||||
@@ -127,7 +129,15 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
|
||||
if(!winapi::get_file_size(hnd, filesize))
|
||||
return false;
|
||||
|
||||
if(size > (unsigned long long)filesize){
|
||||
const offset_t max_filesize = (std::numeric_limits<offset_t>::max)();
|
||||
//Avoid unused variable warnings in 32 bit systems
|
||||
(void)max_filesize;
|
||||
if( sizeof(std::size_t) >= sizeof(offset_t) && size > std::size_t(max_filesize) ){
|
||||
winapi::set_last_error(winapi::error_file_too_large);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(offset_t(size) > filesize){
|
||||
if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
|
||||
return false;
|
||||
}
|
||||
@@ -365,7 +375,7 @@ typedef enum { file_begin = SEEK_SET
|
||||
, file_current = SEEK_CUR
|
||||
} file_pos_t;
|
||||
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
|
||||
{
|
||||
@@ -395,7 +405,7 @@ inline const char *get_temporary_path()
|
||||
}
|
||||
|
||||
inline file_handle_t create_new_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
|
||||
@@ -406,12 +416,23 @@ inline file_handle_t create_new_file
|
||||
}
|
||||
|
||||
inline file_handle_t create_or_open_file
|
||||
(const char *name, mode_t mode, const permissions & perm, bool temporary = false)
|
||||
{
|
||||
(const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
int ret = ::open(name, ((int)mode) | O_CREAT, perm.get_permissions());
|
||||
if(ret >= 0){
|
||||
::fchmod(ret, perm.get_permissions());
|
||||
int ret = -1;
|
||||
//We need a loop to change permissions correctly using fchmod, since
|
||||
//with "O_CREAT only" ::open we don't know if we've created or opened the file.
|
||||
while(1){
|
||||
ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
|
||||
if(ret >= 0){
|
||||
::fchmod(ret, perm.get_permissions());
|
||||
break;
|
||||
}
|
||||
else if(errno == EEXIST){
|
||||
if((ret = ::open(name, (int)mode)) >= 0 || errno != ENOENT){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -420,14 +441,22 @@ inline file_handle_t open_existing_file
|
||||
(const char *name, mode_t mode, bool temporary = false)
|
||||
{
|
||||
(void)temporary;
|
||||
return ::open(name, (int)mode, 0666);
|
||||
return ::open(name, (int)mode);
|
||||
}
|
||||
|
||||
inline bool delete_file(const char *name)
|
||||
{ return ::unlink(name) == 0; }
|
||||
|
||||
inline bool truncate_file (file_handle_t hnd, std::size_t size)
|
||||
{ return 0 == ::ftruncate(hnd, size); }
|
||||
{
|
||||
if(sizeof(off_t) == sizeof(std::size_t)){
|
||||
if(size > ((~std::size_t(0)) >> 1)){
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return 0 == ::ftruncate(hnd, off_t(size));
|
||||
}
|
||||
|
||||
inline bool get_file_size(file_handle_t hnd, offset_t &size)
|
||||
{
|
||||
@@ -658,7 +687,7 @@ inline bool open_or_create_directory(const char *dir_name)
|
||||
}
|
||||
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -23,6 +23,7 @@
|
||||
# include <pthread.h>
|
||||
# include <unistd.h>
|
||||
# include <sched.h>
|
||||
# include <time.h>
|
||||
# else
|
||||
# error Unknown platform
|
||||
# endif
|
||||
@@ -30,7 +31,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
@@ -58,6 +59,9 @@ inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
|
||||
inline void thread_yield()
|
||||
{ winapi::sched_yield(); }
|
||||
|
||||
inline void thread_sleep(unsigned int ms)
|
||||
{ winapi::Sleep(ms); }
|
||||
|
||||
//systemwide thread
|
||||
inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
|
||||
{
|
||||
@@ -160,6 +164,12 @@ inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
|
||||
inline void thread_yield()
|
||||
{ ::sched_yield(); }
|
||||
|
||||
inline void thread_sleep(unsigned int ms)
|
||||
{
|
||||
const struct timespec rqt = { ms/1000u, (ms%1000u)*1000000u };
|
||||
::nanosleep(&rqt, 0);
|
||||
}
|
||||
|
||||
//systemwide thread
|
||||
inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
|
||||
{
|
||||
@@ -192,7 +202,7 @@ inline void get_pid_str(pid_str_t &pid_str, OS_process_id_t pid)
|
||||
inline void get_pid_str(pid_str_t &pid_str)
|
||||
{ get_pid_str(pid_str, get_current_process_id()); }
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
struct two {char _[2];};
|
||||
|
||||
@@ -61,10 +61,10 @@ template <class T, class D>
|
||||
struct pointer_type
|
||||
{
|
||||
typedef typename pointer_type_imp::pointer_type<T,
|
||||
typename detail::remove_reference<D>::type>::type type;
|
||||
typename ipcdetail::remove_reference<D>::type>::type type;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -15,7 +15,7 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "config_begin.hpp"
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
|
||||
#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
|
||||
#error "This file is not needed when perfect forwarding is available"
|
||||
@@ -46,11 +46,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#define BOOST_INTERPROCESS_PARAM(U, u) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM(U, u) \
|
||||
U && u \
|
||||
//!
|
||||
#else
|
||||
#define BOOST_INTERPROCESS_PARAM(U, u) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM(U, u) \
|
||||
const U & u \
|
||||
//!
|
||||
#endif
|
||||
@@ -59,25 +59,25 @@
|
||||
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (BOOST_INTERPROCESS_MOVE_NAMESPACE::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
|
||||
//!
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (BOOST_PP_CAT(p, n)) \
|
||||
//!
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_INIT(z, n, data) \
|
||||
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
|
||||
//!
|
||||
#endif
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_INC(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_INC(z, n, data) \
|
||||
BOOST_PP_CAT(++m_p, n) \
|
||||
//!
|
||||
|
||||
@@ -85,13 +85,13 @@
|
||||
|
||||
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
|
||||
@@ -99,27 +99,27 @@
|
||||
|
||||
|
||||
#else
|
||||
#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_DEFINE(z, n, data) \
|
||||
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
|
||||
//!
|
||||
#endif
|
||||
|
||||
#define BOOST_INTERPROCESS_PP_PARAM_FORWARD(z, n, data) \
|
||||
::boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
|
||||
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
|
||||
//!
|
||||
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
#include <boost/interprocess/containers/container/detail/stored_ref.hpp>
|
||||
#include <boost/container/detail/stored_ref.hpp>
|
||||
|
||||
#define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
|
||||
::boost::container::containers_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
|
||||
::boost::container::container_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(m_p, n) ) \
|
||||
//!
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_INTERPROCESS_PP_MEMBER_FORWARD(z, n, data) \
|
||||
::boost::interprocess::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
|
||||
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(m_p, n) ) \
|
||||
//!
|
||||
|
||||
#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2010-2010. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2010-2011. Distributed under 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)
|
||||
//
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
namespace boost{
|
||||
namespace interprocess{
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
namespace robust_emulation_helpers {
|
||||
|
||||
@@ -173,9 +173,9 @@ class robust_mutex_lock_file
|
||||
|
||||
//This is the mutex class. Mutex should follow mutex concept
|
||||
//with an additonal "take_ownership()" function to take ownership of the
|
||||
//mutex when robust_emulation_mutex determines the previous owner was dead.
|
||||
//mutex when robust_spin_mutex determines the previous owner was dead.
|
||||
template<class Mutex>
|
||||
class robust_emulation_mutex
|
||||
class robust_spin_mutex
|
||||
{
|
||||
public:
|
||||
static const boost::uint32_t correct_state = 0;
|
||||
@@ -184,7 +184,7 @@ class robust_emulation_mutex
|
||||
|
||||
typedef robust_emulation_helpers::mutex_traits<Mutex> mutex_traits_t;
|
||||
|
||||
robust_emulation_mutex();
|
||||
robust_spin_mutex();
|
||||
void lock();
|
||||
bool try_lock();
|
||||
bool timed_lock(const boost::posix_time::ptime &abs_time);
|
||||
@@ -208,12 +208,12 @@ class robust_emulation_mutex
|
||||
};
|
||||
|
||||
template<class Mutex>
|
||||
inline robust_emulation_mutex<Mutex>::robust_emulation_mutex()
|
||||
inline robust_spin_mutex<Mutex>::robust_spin_mutex()
|
||||
: mtx(), owner(get_invalid_process_id()), state(correct_state)
|
||||
{}
|
||||
|
||||
template<class Mutex>
|
||||
inline void robust_emulation_mutex<Mutex>::lock()
|
||||
inline void robust_spin_mutex<Mutex>::lock()
|
||||
{
|
||||
//If the mutex is broken (recovery didn't call consistent()),
|
||||
//then throw an exception
|
||||
@@ -236,7 +236,7 @@ inline void robust_emulation_mutex<Mutex>::lock()
|
||||
}
|
||||
else{
|
||||
//Do the dead owner checking each spin_threshold lock tries
|
||||
detail::thread_yield();
|
||||
ipcdetail::thread_yield();
|
||||
++spin_count;
|
||||
if(spin_count > spin_threshold){
|
||||
//Check if owner dead and take ownership if possible
|
||||
@@ -252,7 +252,7 @@ inline void robust_emulation_mutex<Mutex>::lock()
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::try_lock()
|
||||
inline bool robust_spin_mutex<Mutex>::try_lock()
|
||||
{
|
||||
//Same as lock() but without spinning
|
||||
if(atomic_read32(&this->state) == broken_state){
|
||||
@@ -278,7 +278,7 @@ inline bool robust_emulation_mutex<Mutex>::try_lock()
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::timed_lock
|
||||
inline bool robust_spin_mutex<Mutex>::timed_lock
|
||||
(const boost::posix_time::ptime &abs_time)
|
||||
{
|
||||
//Same as lock() but with an additional timeout
|
||||
@@ -302,20 +302,20 @@ inline bool robust_emulation_mutex<Mutex>::timed_lock
|
||||
return this->try_lock();
|
||||
}
|
||||
// relinquish current time slice
|
||||
detail::thread_yield();
|
||||
ipcdetail::thread_yield();
|
||||
}while (true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline void robust_emulation_mutex<Mutex>::owner_to_filename(boost::uint32_t owner, std::string &s)
|
||||
inline void robust_spin_mutex<Mutex>::owner_to_filename(boost::uint32_t owner, std::string &s)
|
||||
{
|
||||
robust_emulation_helpers::create_and_get_robust_lock_file_path(s, owner);
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::robust_check()
|
||||
inline bool robust_spin_mutex<Mutex>::robust_check()
|
||||
{
|
||||
//If the old owner was dead, and we've acquired ownership, mark
|
||||
//the mutex as 'fixing'. This means that a "consistent()" is needed
|
||||
@@ -328,7 +328,7 @@ inline bool robust_emulation_mutex<Mutex>::robust_check()
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::check_if_owner_dead_and_take_ownership_atomically()
|
||||
inline bool robust_spin_mutex<Mutex>::check_if_owner_dead_and_take_ownership_atomically()
|
||||
{
|
||||
boost::uint32_t cur_owner = get_current_process_id();
|
||||
boost::uint32_t old_owner = atomic_read32(&this->owner), old_owner2;
|
||||
@@ -349,7 +349,7 @@ inline bool robust_emulation_mutex<Mutex>::check_if_owner_dead_and_take_ownershi
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::is_owner_dead(boost::uint32_t owner)
|
||||
inline bool robust_spin_mutex<Mutex>::is_owner_dead(boost::uint32_t owner)
|
||||
{
|
||||
//If owner is an invalid id, then it's clear it's dead
|
||||
if(owner == (boost::uint32_t)get_invalid_process_id()){
|
||||
@@ -387,7 +387,7 @@ inline bool robust_emulation_mutex<Mutex>::is_owner_dead(boost::uint32_t owner)
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline void robust_emulation_mutex<Mutex>::consistent()
|
||||
inline void robust_spin_mutex<Mutex>::consistent()
|
||||
{
|
||||
//This function supposes the previous state was "fixing"
|
||||
//and the current process holds the mutex
|
||||
@@ -400,14 +400,14 @@ inline void robust_emulation_mutex<Mutex>::consistent()
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::previous_owner_dead()
|
||||
inline bool robust_spin_mutex<Mutex>::previous_owner_dead()
|
||||
{
|
||||
//Notifies if a owner recovery has been performed in the last lock()
|
||||
return atomic_read32(&this->state) == fixing_state;
|
||||
};
|
||||
|
||||
template<class Mutex>
|
||||
inline void robust_emulation_mutex<Mutex>::unlock()
|
||||
inline void robust_spin_mutex<Mutex>::unlock()
|
||||
{
|
||||
//If in "fixing" state, unlock and mark the mutex as unrecoverable
|
||||
//so next locks will fail and all threads will be notified that the
|
||||
@@ -421,16 +421,16 @@ inline void robust_emulation_mutex<Mutex>::unlock()
|
||||
}
|
||||
|
||||
template<class Mutex>
|
||||
inline bool robust_emulation_mutex<Mutex>::lock_own_unique_file()
|
||||
inline bool robust_spin_mutex<Mutex>::lock_own_unique_file()
|
||||
{
|
||||
//This function forces instantiation of the singleton
|
||||
robust_emulation_helpers::robust_mutex_lock_file* dummy =
|
||||
&detail::intermodule_singleton
|
||||
&ipcdetail::intermodule_singleton
|
||||
<robust_emulation_helpers::robust_mutex_lock_file>::get();
|
||||
return dummy != 0;
|
||||
}
|
||||
|
||||
} //namespace detail{
|
||||
} //namespace ipcdetail{
|
||||
} //namespace interprocess{
|
||||
} //namespace boost{
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -18,13 +18,16 @@
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/in_place_interface.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <cstddef> //std::size_t
|
||||
#include <string> //char_traits
|
||||
#include <new> //std::nothrow
|
||||
@@ -49,7 +52,7 @@ class segment_manager_base;
|
||||
//!instance constructed in memory
|
||||
enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type };
|
||||
|
||||
namespace detail{
|
||||
namespace ipcdetail{
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
class mem_algo_deallocator
|
||||
@@ -70,24 +73,25 @@ class mem_algo_deallocator
|
||||
};
|
||||
|
||||
/// @cond
|
||||
template<class size_type>
|
||||
struct block_header
|
||||
{
|
||||
std::size_t m_value_bytes;
|
||||
size_type m_value_bytes;
|
||||
unsigned short m_num_char;
|
||||
unsigned char m_value_alignment;
|
||||
unsigned char m_alloc_type_sizeof_char;
|
||||
|
||||
block_header(std::size_t value_bytes
|
||||
,std::size_t value_alignment
|
||||
,std::size_t alloc_type
|
||||
block_header(size_type value_bytes
|
||||
,size_type value_alignment
|
||||
,unsigned char alloc_type
|
||||
,std::size_t sizeof_char
|
||||
,std::size_t num_char
|
||||
)
|
||||
: m_value_bytes(value_bytes)
|
||||
, m_num_char(num_char)
|
||||
, m_value_alignment(value_alignment)
|
||||
, m_num_char((unsigned short)num_char)
|
||||
, m_value_alignment((unsigned char)value_alignment)
|
||||
, m_alloc_type_sizeof_char
|
||||
( ((unsigned char)alloc_type << 5u) |
|
||||
( (alloc_type << 5u) |
|
||||
((unsigned char)sizeof_char & 0x1F) )
|
||||
{};
|
||||
|
||||
@@ -96,32 +100,32 @@ struct block_header
|
||||
block_header &operator= (const T& )
|
||||
{ return *this; }
|
||||
|
||||
std::size_t total_size() const
|
||||
size_type total_size() const
|
||||
{
|
||||
if(alloc_type() != anonymous_type){
|
||||
return name_offset() + (m_num_char+1)*sizeof_char();
|
||||
}
|
||||
else{
|
||||
return value_offset() + m_value_bytes;
|
||||
return this->value_offset() + m_value_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t value_bytes() const
|
||||
size_type value_bytes() const
|
||||
{ return m_value_bytes; }
|
||||
|
||||
template<class Header>
|
||||
std::size_t total_size_with_header() const
|
||||
size_type total_size_with_header() const
|
||||
{
|
||||
return get_rounded_size
|
||||
( sizeof(Header)
|
||||
, detail::alignment_of<block_header>::value)
|
||||
( size_type(sizeof(Header))
|
||||
, size_type(::boost::alignment_of<block_header<size_type> >::value))
|
||||
+ total_size();
|
||||
}
|
||||
|
||||
std::size_t alloc_type() const
|
||||
unsigned char alloc_type() const
|
||||
{ return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
|
||||
|
||||
std::size_t sizeof_char() const
|
||||
unsigned char sizeof_char() const
|
||||
{ return m_alloc_type_sizeof_char & (unsigned char)0x1F; }
|
||||
|
||||
template<class CharType>
|
||||
@@ -131,26 +135,26 @@ struct block_header
|
||||
(reinterpret_cast<const char*>(this) + name_offset()));
|
||||
}
|
||||
|
||||
std::size_t name_length() const
|
||||
unsigned short name_length() const
|
||||
{ return m_num_char; }
|
||||
|
||||
std::size_t name_offset() const
|
||||
size_type name_offset() const
|
||||
{
|
||||
return value_offset() + get_rounded_size(m_value_bytes, sizeof_char());
|
||||
return this->value_offset() + get_rounded_size(size_type(m_value_bytes), size_type(sizeof_char()));
|
||||
}
|
||||
|
||||
void *value() const
|
||||
{
|
||||
return const_cast<char*>((reinterpret_cast<const char*>(this) + value_offset()));
|
||||
return const_cast<char*>((reinterpret_cast<const char*>(this) + this->value_offset()));
|
||||
}
|
||||
|
||||
std::size_t value_offset() const
|
||||
size_type value_offset() const
|
||||
{
|
||||
return get_rounded_size(sizeof(block_header), m_value_alignment);
|
||||
return get_rounded_size(size_type(sizeof(block_header<size_type>)), size_type(m_value_alignment));
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
bool less_comp(const block_header &b) const
|
||||
bool less_comp(const block_header<size_type> &b) const
|
||||
{
|
||||
return m_num_char < b.m_num_char ||
|
||||
(m_num_char < b.m_num_char &&
|
||||
@@ -159,7 +163,7 @@ struct block_header
|
||||
}
|
||||
|
||||
template<class CharType>
|
||||
bool equal_comp(const block_header &b) const
|
||||
bool equal_comp(const block_header<size_type> &b) const
|
||||
{
|
||||
return m_num_char == b.m_num_char &&
|
||||
std::char_traits<CharType>::compare
|
||||
@@ -167,10 +171,10 @@ struct block_header
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static block_header *block_header_from_value(T *value)
|
||||
{ return block_header_from_value(value, sizeof(T), detail::alignment_of<T>::value); }
|
||||
static block_header<size_type> *block_header_from_value(T *value)
|
||||
{ return block_header_from_value(value, sizeof(T), ::boost::alignment_of<T>::value); }
|
||||
|
||||
static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
|
||||
static block_header<size_type> *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
|
||||
{
|
||||
block_header * hdr =
|
||||
const_cast<block_header*>
|
||||
@@ -184,27 +188,27 @@ struct block_header
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
static block_header *from_first_header(Header *header)
|
||||
static block_header<size_type> *from_first_header(Header *header)
|
||||
{
|
||||
block_header * hdr =
|
||||
reinterpret_cast<block_header*>(reinterpret_cast<char*>(header) +
|
||||
get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
|
||||
block_header<size_type> * hdr =
|
||||
reinterpret_cast<block_header<size_type>*>(reinterpret_cast<char*>(header) +
|
||||
get_rounded_size(size_type(sizeof(Header)), size_type(::boost::alignment_of<block_header<size_type> >::value)));
|
||||
//Some sanity checks
|
||||
return hdr;
|
||||
}
|
||||
|
||||
template<class Header>
|
||||
static Header *to_first_header(block_header *bheader)
|
||||
static Header *to_first_header(block_header<size_type> *bheader)
|
||||
{
|
||||
Header * hdr =
|
||||
reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) -
|
||||
get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
|
||||
get_rounded_size(size_type(sizeof(Header)), size_type(::boost::alignment_of<block_header<size_type> >::value)));
|
||||
//Some sanity checks
|
||||
return hdr;
|
||||
}
|
||||
};
|
||||
|
||||
inline void array_construct(void *mem, std::size_t num, detail::in_place_interface &table)
|
||||
inline void array_construct(void *mem, std::size_t num, in_place_interface &table)
|
||||
{
|
||||
//Try constructors
|
||||
std::size_t constructed = 0;
|
||||
@@ -257,7 +261,7 @@ typedef instance_t<anonymous_type> anonymous_instance_t;
|
||||
typedef instance_t<unique_type> unique_instance_t;
|
||||
|
||||
|
||||
template<class Hook, class CharType>
|
||||
template<class Hook, class CharType, class SizeType>
|
||||
struct intrusive_value_type_impl
|
||||
: public Hook
|
||||
{
|
||||
@@ -268,34 +272,35 @@ struct intrusive_value_type_impl
|
||||
|
||||
public:
|
||||
typedef CharType char_type;
|
||||
typedef SizeType size_type;
|
||||
|
||||
intrusive_value_type_impl(){}
|
||||
|
||||
enum { BlockHdrAlignment = detail::alignment_of<block_header>::value };
|
||||
enum { BlockHdrAlignment = ::boost::alignment_of<block_header<size_type> >::value };
|
||||
|
||||
block_header *get_block_header() const
|
||||
block_header<size_type> *get_block_header() const
|
||||
{
|
||||
return const_cast<block_header*>
|
||||
(reinterpret_cast<const block_header *>(reinterpret_cast<const char*>(this) +
|
||||
get_rounded_size(sizeof(*this), BlockHdrAlignment)));
|
||||
return const_cast<block_header<size_type>*>
|
||||
(reinterpret_cast<const block_header<size_type> *>(reinterpret_cast<const char*>(this) +
|
||||
get_rounded_size(size_type(sizeof(*this)), size_type(BlockHdrAlignment))));
|
||||
}
|
||||
|
||||
bool operator <(const intrusive_value_type_impl<Hook, CharType> & other) const
|
||||
bool operator <(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
|
||||
{ return (this->get_block_header())->template less_comp<CharType>(*other.get_block_header()); }
|
||||
|
||||
bool operator ==(const intrusive_value_type_impl<Hook, CharType> & other) const
|
||||
bool operator ==(const intrusive_value_type_impl<Hook, CharType, SizeType> & other) const
|
||||
{ return (this->get_block_header())->template equal_comp<CharType>(*other.get_block_header()); }
|
||||
|
||||
static intrusive_value_type_impl *get_intrusive_value_type(block_header *hdr)
|
||||
static intrusive_value_type_impl *get_intrusive_value_type(block_header<size_type> *hdr)
|
||||
{
|
||||
return reinterpret_cast<intrusive_value_type_impl *>(reinterpret_cast<char*>(hdr) -
|
||||
get_rounded_size(sizeof(intrusive_value_type_impl), BlockHdrAlignment));
|
||||
get_rounded_size(size_type(sizeof(intrusive_value_type_impl)), size_type(BlockHdrAlignment)));
|
||||
}
|
||||
|
||||
CharType *name() const
|
||||
{ return get_block_header()->template name<CharType>(); }
|
||||
|
||||
std::size_t name_length() const
|
||||
unsigned short name_length() const
|
||||
{ return get_block_header()->name_length(); }
|
||||
|
||||
void *value() const
|
||||
@@ -310,11 +315,11 @@ class char_ptr_holder
|
||||
: m_name(name)
|
||||
{}
|
||||
|
||||
char_ptr_holder(const detail::anonymous_instance_t *)
|
||||
char_ptr_holder(const anonymous_instance_t *)
|
||||
: m_name(static_cast<CharType*>(0))
|
||||
{}
|
||||
|
||||
char_ptr_holder(const detail::unique_instance_t *)
|
||||
char_ptr_holder(const unique_instance_t *)
|
||||
: m_name(reinterpret_cast<CharType*>(-1))
|
||||
{}
|
||||
|
||||
@@ -330,19 +335,22 @@ class char_ptr_holder
|
||||
template<class CharT, class VoidPointer>
|
||||
struct index_key
|
||||
{
|
||||
typedef typename boost::
|
||||
pointer_to_other<VoidPointer, const CharT>::type const_char_ptr_t;
|
||||
typedef typename boost::intrusive::
|
||||
pointer_traits<VoidPointer>::template
|
||||
rebind_pointer<const CharT>::type const_char_ptr_t;
|
||||
typedef CharT char_type;
|
||||
typedef typename boost::intrusive::pointer_traits<const_char_ptr_t>::difference_type difference_type;
|
||||
typedef typename boost::make_unsigned<difference_type>::type size_type;
|
||||
|
||||
private:
|
||||
//Offset pointer to the object's name
|
||||
const_char_ptr_t mp_str;
|
||||
//Length of the name buffer (null NOT included)
|
||||
std::size_t m_len;
|
||||
size_type m_len;
|
||||
public:
|
||||
|
||||
//!Constructor of the key
|
||||
index_key (const char_type *name, std::size_t length)
|
||||
index_key (const char_type *name, size_type length)
|
||||
: mp_str(name), m_len(length) {}
|
||||
|
||||
//!Less than function for index ordering
|
||||
@@ -351,8 +359,8 @@ struct index_key
|
||||
return (m_len < right.m_len) ||
|
||||
(m_len == right.m_len &&
|
||||
std::char_traits<char_type>::compare
|
||||
(detail::get_pointer(mp_str)
|
||||
,detail::get_pointer(right.mp_str), m_len) < 0);
|
||||
(to_raw_pointer(mp_str)
|
||||
,to_raw_pointer(right.mp_str), m_len) < 0);
|
||||
}
|
||||
|
||||
//!Equal to function for index ordering
|
||||
@@ -360,20 +368,20 @@ struct index_key
|
||||
{
|
||||
return m_len == right.m_len &&
|
||||
std::char_traits<char_type>::compare
|
||||
(detail::get_pointer(mp_str),
|
||||
detail::get_pointer(right.mp_str), m_len) == 0;
|
||||
(to_raw_pointer(mp_str),
|
||||
to_raw_pointer(right.mp_str), m_len) == 0;
|
||||
}
|
||||
|
||||
void name(const CharT *name)
|
||||
{ mp_str = name; }
|
||||
|
||||
void name_length(std::size_t len)
|
||||
void name_length(size_type len)
|
||||
{ m_len = len; }
|
||||
|
||||
const CharT *name() const
|
||||
{ return detail::get_pointer(mp_str); }
|
||||
{ return to_raw_pointer(mp_str); }
|
||||
|
||||
std::size_t name_length() const
|
||||
size_type name_length() const
|
||||
{ return m_len; }
|
||||
};
|
||||
|
||||
@@ -387,7 +395,7 @@ struct index_data
|
||||
index_data(void *ptr) : m_ptr(ptr){}
|
||||
|
||||
void *value() const
|
||||
{ return static_cast<void*>(detail::get_pointer(m_ptr)); }
|
||||
{ return static_cast<void*>(to_raw_pointer(m_ptr)); }
|
||||
};
|
||||
|
||||
template<class MemoryAlgorithm>
|
||||
@@ -399,14 +407,14 @@ struct index_config
|
||||
{
|
||||
typedef typename MemoryAlgorithm::void_pointer void_pointer;
|
||||
typedef CharT char_type;
|
||||
typedef detail::index_key<CharT, void_pointer> key_type;
|
||||
typedef detail::index_data<void_pointer> mapped_type;
|
||||
typedef index_key<CharT, void_pointer> key_type;
|
||||
typedef index_data<void_pointer> mapped_type;
|
||||
typedef typename segment_manager_base_type
|
||||
<MemoryAlgorithm>::type segment_manager_base;
|
||||
|
||||
template<class HeaderBase>
|
||||
struct intrusive_value_type
|
||||
{ typedef detail::intrusive_value_type_impl<HeaderBase, CharT> type; };
|
||||
{ typedef intrusive_value_type_impl<HeaderBase, CharT, typename segment_manager_base::size_type> type; };
|
||||
|
||||
typedef intrusive_compare_key<CharT> intrusive_compare_key_type;
|
||||
};
|
||||
@@ -425,7 +433,7 @@ class segment_manager_iterator_value_adaptor
|
||||
const char_type *name() const
|
||||
{ return m_val->name(); }
|
||||
|
||||
std::size_t name_length() const
|
||||
unsigned short name_length() const
|
||||
{ return m_val->name_length(); }
|
||||
|
||||
const void *value() const
|
||||
@@ -442,6 +450,7 @@ class segment_manager_iterator_value_adaptor<Iterator, false>
|
||||
typedef typename iterator_val_t::first_type first_type;
|
||||
typedef typename iterator_val_t::second_type second_type;
|
||||
typedef typename first_type::char_type char_type;
|
||||
typedef typename first_type::size_type size_type;
|
||||
|
||||
public:
|
||||
segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
|
||||
@@ -451,13 +460,13 @@ class segment_manager_iterator_value_adaptor<Iterator, false>
|
||||
const char_type *name() const
|
||||
{ return m_val->first.name(); }
|
||||
|
||||
std::size_t name_length() const
|
||||
size_type name_length() const
|
||||
{ return m_val->first.name_length(); }
|
||||
|
||||
const void *value() const
|
||||
{
|
||||
return reinterpret_cast<block_header*>
|
||||
(detail::get_pointer(m_val->second.m_ptr))->value();
|
||||
return reinterpret_cast<block_header<size_type>*>
|
||||
(to_raw_pointer(m_val->second.m_ptr))->value();
|
||||
}
|
||||
|
||||
const typename Iterator::value_type *m_val;
|
||||
@@ -474,14 +483,14 @@ struct segment_manager_iterator_transform
|
||||
{ return result_type(arg); }
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
//These pointers are the ones the user will use to
|
||||
//indicate previous allocation types
|
||||
static const detail::anonymous_instance_t * anonymous_instance = 0;
|
||||
static const detail::unique_instance_t * unique_instance = 0;
|
||||
static const ipcdetail::anonymous_instance_t * anonymous_instance = 0;
|
||||
static const ipcdetail::unique_instance_t * unique_instance = 0;
|
||||
|
||||
namespace detail_really_deep_namespace {
|
||||
namespace ipcdetail_really_deep_namespace {
|
||||
|
||||
//Otherwise, gcc issues a warning of previously defined
|
||||
//anonymous_instance and unique_instance
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2007-2011. Distributed under 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)
|
||||
//
|
||||
@@ -19,20 +19,20 @@
|
||||
#include <string>
|
||||
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
|
||||
#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
||||
//#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
|
||||
//#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
//#include <boost/interprocess/detail/win32_api.hpp>
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||
#include <sys/sysctl.h>
|
||||
#if defined(CTL_KERN) && defined (KERN_BOOTTIME)
|
||||
#define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
|
||||
#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
#endif
|
||||
//#include <sys/sysctl.h>
|
||||
//#if defined(CTL_KERN) && defined (KERN_BOOTTIME)
|
||||
//#define BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME
|
||||
//#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
#if defined (BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME)
|
||||
inline void get_bootstamp(std::string &s, bool add = false)
|
||||
@@ -43,7 +43,7 @@ inline void get_bootstamp(std::string &s, bool add = false)
|
||||
s += bootstamp;
|
||||
}
|
||||
else{
|
||||
s = bootstamp;
|
||||
s.swap(bootstamp);
|
||||
}
|
||||
}
|
||||
#elif defined(BOOST_INTERPROCESS_HAS_BSD_KERNEL_BOOTTIME)
|
||||
@@ -52,7 +52,7 @@ inline void get_bootstamp(std::string &s, bool add = false)
|
||||
// FreeBSD specific: sysctl "kern.boottime"
|
||||
int request[2] = { CTL_KERN, KERN_BOOTTIME };
|
||||
struct ::timeval result;
|
||||
size_t result_len = sizeof result;
|
||||
std::size_t result_len = sizeof result;
|
||||
|
||||
if (::sysctl (request, 2, &result, &result_len, NULL, 0) < 0)
|
||||
return;
|
||||
@@ -64,9 +64,10 @@ inline void get_bootstamp(std::string &s, bool add = false)
|
||||
, '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
std::size_t char_counter = 0;
|
||||
long fields[2] = { result.tv_sec, result.tv_usec };
|
||||
//32 bit values to allow 32 and 64 bit process IPC
|
||||
boost::uint32_t fields[2] = { boost::uint32_t(result.tv_sec), boost::uint32_t(result.tv_usec) };
|
||||
for(std::size_t field = 0; field != 2; ++field){
|
||||
for(std::size_t i = 0; i != sizeof(long); ++i){
|
||||
for(std::size_t i = 0; i != sizeof(fields[0]); ++i){
|
||||
const char *ptr = (const char *)&fields[field];
|
||||
bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4];
|
||||
bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)];
|
||||
@@ -86,7 +87,7 @@ inline void get_tmp_base_dir(std::string &tmp_name)
|
||||
{
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
||||
winapi::get_shared_documents_folder(tmp_name);
|
||||
if(tmp_name.empty()){
|
||||
if(tmp_name.empty() || !winapi::is_directory(tmp_name.c_str())){
|
||||
tmp_name = get_temporary_path();
|
||||
}
|
||||
#else
|
||||
@@ -152,7 +153,8 @@ inline void create_tmp_and_clean_old(std::string &tmp_name)
|
||||
inline void create_tmp_and_clean_old_and_get_filename(const char *filename, std::string &tmp_name)
|
||||
{
|
||||
create_tmp_and_clean_old(tmp_name);
|
||||
tmp_filename(filename, tmp_name);
|
||||
tmp_name += "/";
|
||||
tmp_name += filename;
|
||||
}
|
||||
|
||||
inline void add_leading_slash(const char *name, std::string &new_name)
|
||||
@@ -165,7 +167,7 @@ inline void add_leading_slash(const char *name, std::string &new_name)
|
||||
|
||||
} //namespace boost{
|
||||
} //namespace interprocess {
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -62,7 +62,7 @@ class transform_iterator
|
||||
: public UnaryFunction
|
||||
, public std::iterator
|
||||
< typename Iterator::iterator_category
|
||||
, typename detail::remove_reference<typename UnaryFunction::result_type>::type
|
||||
, typename ipcdetail::remove_reference<typename UnaryFunction::result_type>::type
|
||||
, typename Iterator::difference_type
|
||||
, operator_arrow_proxy<typename UnaryFunction::result_type>
|
||||
, typename UnaryFunction::result_type>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -8,8 +8,6 @@
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
// The alignment_of implementation comes from John Maddock's boost::alignment_of code
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_TYPE_TRAITS_HPP
|
||||
@@ -23,52 +21,10 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
struct nat{};
|
||||
|
||||
//boost::alignment_of yields to 10K lines of preprocessed code, so we
|
||||
//need an alternative
|
||||
template <typename T> struct alignment_of;
|
||||
|
||||
template <typename T>
|
||||
struct alignment_of_hack
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
alignment_of_hack();
|
||||
};
|
||||
|
||||
template <unsigned A, unsigned S>
|
||||
struct alignment_logic
|
||||
{
|
||||
enum{ value = A < S ? A : S };
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct alignment_of
|
||||
{
|
||||
enum{ value = alignment_logic
|
||||
< sizeof(alignment_of_hack<T>) - sizeof(T)
|
||||
, sizeof(T)>::value };
|
||||
};
|
||||
|
||||
//This is not standard, but should work with all compilers
|
||||
union max_align
|
||||
{
|
||||
char char_;
|
||||
short short_;
|
||||
int int_;
|
||||
long long_;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
long long long_long_;
|
||||
#endif
|
||||
float float_;
|
||||
double double_;
|
||||
long double long_double_;
|
||||
void * void_ptr_;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_reference
|
||||
{
|
||||
@@ -84,25 +40,25 @@ struct remove_reference<T&>
|
||||
template<class T>
|
||||
struct is_reference
|
||||
{
|
||||
enum { value = false };
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_reference<T&>
|
||||
{
|
||||
enum { value = true };
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_pointer
|
||||
{
|
||||
enum { value = false };
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_pointer<T*>
|
||||
{
|
||||
enum { value = true };
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -137,6 +93,30 @@ template <class T>
|
||||
struct add_const_reference<T&>
|
||||
{ typedef T& type; };
|
||||
|
||||
template<class T>
|
||||
struct remove_const
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_const<const T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_volatile
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_volatile<volatile T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same
|
||||
{
|
||||
@@ -156,11 +136,10 @@ struct is_same
|
||||
static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ipcdetail
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009.
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011.
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
@@ -22,44 +22,30 @@
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/interprocess/detail/min_max.hpp>
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
||||
#include <boost/interprocess/detail/transform_iterator.hpp>
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
||||
#include <boost/interprocess/containers/version_type.hpp>
|
||||
#include <boost/interprocess/detail/move.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template<class SmartPtr>
|
||||
struct smart_ptr_type
|
||||
{
|
||||
typedef typename SmartPtr::value_type value_type;
|
||||
typedef value_type *pointer;
|
||||
static pointer get (const SmartPtr &smartptr)
|
||||
{ return smartptr.get();}
|
||||
};
|
||||
template <class T>
|
||||
inline T* to_raw_pointer(T* p)
|
||||
{ return p; }
|
||||
|
||||
template<class T>
|
||||
struct smart_ptr_type<T*>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef value_type *pointer;
|
||||
static pointer get (pointer ptr)
|
||||
{ return ptr;}
|
||||
};
|
||||
|
||||
//!Overload for smart pointers to avoid ADL problems with get_pointer
|
||||
template<class Ptr>
|
||||
inline typename smart_ptr_type<Ptr>::pointer
|
||||
get_pointer(const Ptr &ptr)
|
||||
{ return smart_ptr_type<Ptr>::get(ptr); }
|
||||
template <class Pointer>
|
||||
inline typename boost::intrusive::pointer_traits<Pointer>::element_type*
|
||||
to_raw_pointer(const Pointer &p)
|
||||
{ return boost::interprocess::ipcdetail::to_raw_pointer(p.operator->()); }
|
||||
|
||||
//!To avoid ADL problems with swap
|
||||
template <class T>
|
||||
@@ -70,25 +56,29 @@ inline void do_swap(T& x, T& y)
|
||||
}
|
||||
|
||||
//Rounds "orig_size" by excess to round_to bytes
|
||||
inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
|
||||
template<class SizeType>
|
||||
inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
|
||||
{
|
||||
return ((orig_size-1)/round_to+1)*round_to;
|
||||
}
|
||||
|
||||
//Truncates "orig_size" to a multiple of "multiple" bytes.
|
||||
inline std::size_t get_truncated_size(std::size_t orig_size, std::size_t multiple)
|
||||
template<class SizeType>
|
||||
inline SizeType get_truncated_size(SizeType orig_size, SizeType multiple)
|
||||
{
|
||||
return orig_size/multiple*multiple;
|
||||
}
|
||||
|
||||
//Rounds "orig_size" by excess to round_to bytes. round_to must be power of two
|
||||
inline std::size_t get_rounded_size_po2(std::size_t orig_size, std::size_t round_to)
|
||||
template<class SizeType>
|
||||
inline SizeType get_rounded_size_po2(SizeType orig_size, SizeType round_to)
|
||||
{
|
||||
return ((orig_size-1)&(~(round_to-1))) + round_to;
|
||||
}
|
||||
|
||||
//Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of two
|
||||
inline std::size_t get_truncated_size_po2(std::size_t orig_size, std::size_t multiple)
|
||||
template<class SizeType>
|
||||
inline SizeType get_truncated_size_po2(SizeType orig_size, SizeType multiple)
|
||||
{
|
||||
return (orig_size & (~(multiple-1)));
|
||||
}
|
||||
@@ -96,14 +86,14 @@ inline std::size_t get_truncated_size_po2(std::size_t orig_size, std::size_t mul
|
||||
template <std::size_t OrigSize, std::size_t RoundTo>
|
||||
struct ct_rounded_size
|
||||
{
|
||||
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
|
||||
static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo;
|
||||
};
|
||||
|
||||
// Gennaro Prota wrote this. Thanks!
|
||||
template <int p, int n = 4>
|
||||
struct ct_max_pow2_less
|
||||
{
|
||||
enum { c = 2*n < p };
|
||||
static const std::size_t c = 2*n < p;
|
||||
|
||||
static const std::size_t value =
|
||||
c ? (ct_max_pow2_less< c*p, 2*c*n>::value) : n;
|
||||
@@ -115,7 +105,7 @@ struct ct_max_pow2_less<0, 0>
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace ipcdetail {
|
||||
|
||||
//!Trait class to detect if an index is a node
|
||||
//!index. This allows more efficient operations
|
||||
@@ -123,7 +113,7 @@ struct ct_max_pow2_less<0, 0>
|
||||
template <class Index>
|
||||
struct is_node_index
|
||||
{
|
||||
enum { value = false };
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
//!Trait class to detect if an index is an intrusive
|
||||
@@ -133,7 +123,7 @@ struct is_node_index
|
||||
template <class Index>
|
||||
struct is_intrusive_index
|
||||
{
|
||||
enum { value = false };
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T> T*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under 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)
|
||||
//
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
namespace detail {
|
||||
namespace ipcdetail {
|
||||
|
||||
template<typename... Values>
|
||||
class tuple;
|
||||
@@ -146,7 +146,7 @@ struct build_number_seq<0, index_tuple<Indexes...> >
|
||||
{ typedef index_tuple<Indexes...> type; };
|
||||
|
||||
|
||||
}}} //namespace boost { namespace interprocess { namespace detail {
|
||||
}}} //namespace boost { namespace interprocess { namespace ipcdetail {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if !(defined BOOST_INTERPROCESS_WINDOWS)
|
||||
#if !defined(BOOST_INTERPROCESS_WINDOWS)
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -138,6 +138,11 @@
|
||||
|
||||
#endif
|
||||
|
||||
// Timeout duration use if BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING is set
|
||||
#ifndef BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS
|
||||
#define BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS 10000
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_WORKAROUND_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under 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)
|
||||
//
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
|
||||
#include <boost/interprocess/detail/xsi_shared_memory.hpp>
|
||||
#include <boost/interprocess/xsi_shared_memory.hpp>
|
||||
#include <boost/interprocess/sync/xsi/xsi_named_mutex.hpp>
|
||||
#include <boost/interprocess/mapped_region.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
@@ -45,40 +45,37 @@ namespace interprocess {
|
||||
class xsi_shared_memory_device
|
||||
{
|
||||
/// @cond
|
||||
//Non-copyable and non-assignable
|
||||
xsi_shared_memory_device(xsi_shared_memory_device &);
|
||||
xsi_shared_memory_device &operator=(xsi_shared_memory_device &);
|
||||
/// @endcond
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(xsi_shared_memory_device)
|
||||
|
||||
xsi_shared_memory_device();
|
||||
|
||||
xsi_shared_memory_device(create_only_t, const char *name, mode_t mode, std::size_t size)
|
||||
{ this->priv_open_or_create_name_only(detail::DoCreate, name, mode, size); }
|
||||
{ this->priv_open_or_create_name_only(ipcdetail::DoCreate, name, mode, size); }
|
||||
|
||||
xsi_shared_memory_device(open_or_create_t, const char *name, mode_t mode, std::size_t size)
|
||||
{ this->priv_open_or_create_name_only(detail::DoOpenOrCreate, name, mode, size); }
|
||||
{ this->priv_open_or_create_name_only(ipcdetail::DoOpenOrCreate, name, mode, size); }
|
||||
|
||||
xsi_shared_memory_device(open_only_t, const char *name, mode_t mode)
|
||||
{ this->priv_open_or_create_name_only(detail::DoOpen, name, mode, 0); }
|
||||
{ this->priv_open_or_create_name_only(ipcdetail::DoOpen, name, mode, 0); }
|
||||
|
||||
xsi_shared_memory_device(create_only_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
|
||||
{ this->priv_open_or_create_name_id(detail::DoCreate, name, id, mode, size); }
|
||||
{ this->priv_open_or_create_name_id(ipcdetail::DoCreate, name, id, mode, size); }
|
||||
|
||||
xsi_shared_memory_device(open_or_create_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
|
||||
{ this->priv_open_or_create_name_id(detail::DoOpenOrCreate, id, name, mode, size); }
|
||||
{ this->priv_open_or_create_name_id(ipcdetail::DoOpenOrCreate, id, name, mode, size); }
|
||||
|
||||
xsi_shared_memory_device(open_only_t, const char *filepath, boost::uint8_t id, mode_t mode)
|
||||
{ this->priv_open_or_create_name_id(detail::DoOpen, name, id, mode, 0); }
|
||||
{ this->priv_open_or_create_name_id(ipcdetail::DoOpen, name, id, mode, 0); }
|
||||
|
||||
xsi_shared_memory_device(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory_device) moved)
|
||||
xsi_shared_memory_device(BOOST_RV_REF(xsi_shared_memory_device) moved)
|
||||
{ this->swap(moved); }
|
||||
|
||||
xsi_shared_memory_device &operator=(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory_device) moved)
|
||||
xsi_shared_memory_device &operator=(BOOST_RV_REF(xsi_shared_memory_device) moved)
|
||||
{
|
||||
xsi_shared_memory_device tmp(boost::interprocess::move(moved));
|
||||
xsi_shared_memory_device tmp(boost::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
@@ -138,11 +135,11 @@ class xsi_shared_memory_device
|
||||
static void priv_obtain_index(mapped_region &m, xsi_named_mutex &m, std::string &path);
|
||||
static bool priv_remove_dead_memory(info_t *info, const char *path);
|
||||
|
||||
bool priv_open_or_create_name_only( detail::create_enum_t type
|
||||
bool priv_open_or_create_name_only( ipcdetail::create_enum_t type
|
||||
, const char *shmname
|
||||
, mode_t mode
|
||||
, std::size_t size);
|
||||
bool priv_open_or_create_name_id( detail::create_enum_t type
|
||||
bool priv_open_or_create_name_id( ipcdetail::create_enum_t type
|
||||
, const char *shmname
|
||||
, boost::uint8_t id
|
||||
, mode_t mode
|
||||
@@ -200,15 +197,15 @@ inline void xsi_shared_memory_device::priv_obtain_index
|
||||
permissions p;
|
||||
p.set_unrestricted();
|
||||
std::string xsi_shm_emulation_file_path;
|
||||
detail::create_tmp_and_clean_old_and_get_filename(filename, xsi_shm_emulation_file_path);
|
||||
detail::create_or_open_file(xsi_shm_emulation_file_path.c_str(), read_write, p);
|
||||
ipcdetail::create_tmp_and_clean_old_and_get_filename(filename, xsi_shm_emulation_file_path);
|
||||
ipcdetail::create_or_open_file(xsi_shm_emulation_file_path.c_str(), read_write, p);
|
||||
const std::size_t MemSize = sizeof(info_t);
|
||||
|
||||
xsi_shared_memory index_shm(open_or_create, xsi_shm_emulation_file_path.c_str(), 1, MemSize, 0666);
|
||||
mapped_region r(index_shm, read_write, 0, MemSize, 0);
|
||||
xsi_named_mutex m(open_or_create, xsi_shm_emulation_file_path.c_str(), 2, 0666);
|
||||
reg = boost::interprocess::move(r);
|
||||
mut = boost::interprocess::move(m);
|
||||
reg = boost::move(r);
|
||||
mut = boost::move(m);
|
||||
path.swap(xsi_shm_emulation_file_path);
|
||||
}
|
||||
|
||||
@@ -233,7 +230,7 @@ inline bool xsi_shared_memory_device::priv_remove_dead_memory
|
||||
}
|
||||
|
||||
inline bool xsi_shared_memory_device::priv_open_or_create_name_id
|
||||
(detail::create_enum_t type, const char *filepath, mode_t mode, std::size_t size)
|
||||
(ipcdetail::create_enum_t type, const char *filepath, mode_t mode, std::size_t size)
|
||||
{
|
||||
//Set accesses
|
||||
if (mode != read_write && mode != read_only){
|
||||
@@ -243,23 +240,23 @@ inline bool xsi_shared_memory_device::priv_open_or_create_name_id
|
||||
|
||||
int perm = (mode == read_only) ? (0444) : (0666);
|
||||
|
||||
if(type == detail::DoOpen){
|
||||
if(type == ipcdetail::DoOpen){
|
||||
if(!found){
|
||||
error_info err = not_found_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
xsi_shared_memory temp(open_only, filepath, id, perm);
|
||||
m_shm = boost::interprocess::move(temp);
|
||||
m_shm = boost::move(temp);
|
||||
}
|
||||
else if(type == detail::DoCreate){
|
||||
else if(type == ipcdetail::DoCreate){
|
||||
//Try to reuse slot
|
||||
xsi_shared_memory temp(create_only, filepath, id, size, perm);
|
||||
std::strcpy(info->names[target_entry].buf, shmname);
|
||||
m_shm = boost::interprocess::move(temp);
|
||||
m_shm = boost::move(temp);
|
||||
}
|
||||
else{ // if(type == detail::DoOpenOrCreate){
|
||||
else{ // if(type == ipcdetail::DoOpenOrCreate){
|
||||
xsi_shared_memory temp(open_or_create, filepath, id, size, perm);
|
||||
m_shm = boost::interprocess::move(temp);
|
||||
m_shm = boost::move(temp);
|
||||
}
|
||||
|
||||
m_mode = mode;
|
||||
@@ -268,7 +265,7 @@ inline bool xsi_shared_memory_device::priv_open_or_create_name_id
|
||||
}
|
||||
|
||||
inline bool xsi_shared_memory_device::priv_open_or_create_name_only
|
||||
(detail::create_enum_t type, const char *shmname, mode_t mode, std::size_t size)
|
||||
(ipcdetail::create_enum_t type, const char *shmname, mode_t mode, std::size_t size)
|
||||
{
|
||||
//Set accesses
|
||||
if (mode != read_write && mode != read_only){
|
||||
@@ -314,32 +311,32 @@ inline bool xsi_shared_memory_device::priv_open_or_create_name_only
|
||||
}
|
||||
//Now handle the result
|
||||
int perm = (mode == read_only) ? (0444) : (0666);
|
||||
if(type == detail::DoOpen){
|
||||
if(type == ipcdetail::DoOpen){
|
||||
if(!found){
|
||||
error_info err = not_found_error;
|
||||
throw interprocess_exception(err);
|
||||
}
|
||||
xsi_shared_memory temp( open_only, xsi_shm_emulation_file_path.c_str()
|
||||
, target_entry+info_constants_t<0>::FirstID, perm);
|
||||
m_shm = boost::interprocess::move(temp);
|
||||
m_shm = boost::move(temp);
|
||||
}
|
||||
else{
|
||||
|
||||
if(type == detail::DoCreate){
|
||||
if(type == ipcdetail::DoCreate){
|
||||
//Try to reuse slot
|
||||
xsi_shared_memory temp( create_only, xsi_shm_emulation_file_path.c_str()
|
||||
, target_entry+info_constants_t<0>::FirstID, size, perm);
|
||||
std::strcpy(info->names[target_entry].buf, shmname);
|
||||
m_shm = boost::interprocess::move(temp);
|
||||
m_shm = boost::move(temp);
|
||||
}
|
||||
else{ // if(type == detail::DoOpenOrCreate){
|
||||
else{ // if(type == ipcdetail::DoOpenOrCreate){
|
||||
xsi_shared_memory temp( open_or_create, xsi_shm_emulation_file_path.c_str()
|
||||
, target_entry+info_constants_t<0>::FirstID, size, perm);
|
||||
if(!found){
|
||||
std::memset(info->names[target_entry].buf, 0, info_constants_t<0>::MaxName);
|
||||
std::strcpy(info->names[target_entry].buf, shmname);
|
||||
}
|
||||
m_shm = boost::interprocess::move(temp);
|
||||
m_shm = boost::move(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2011. Distributed under 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)
|
||||
//
|
||||
// See http://www.boost.org/libs/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_FILE_WRAPPER_HPP
|
||||
#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_FILE_WRAPPER_HPP
|
||||
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if !defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
|
||||
#error "This header can't be used in operating systems without XSI (System V) shared memory support"
|
||||
#endif
|
||||
|
||||
#include <boost/interprocess/creation_tags.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
||||
#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
||||
#include <boost/interprocess/exceptions.hpp>
|
||||
|
||||
#include <boost/interprocess/xsi_shared_memory.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes a class representing a pseudo-file implemented on top of xsi shared memory.
|
||||
|
||||
namespace boost {
|
||||
namespace interprocess {
|
||||
|
||||
class xsi_shared_memory_file_wrapper
|
||||
: public xsi_shared_memory
|
||||
{
|
||||
/// @cond
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(xsi_shared_memory_file_wrapper)
|
||||
/// @endcond
|
||||
public:
|
||||
|
||||
xsi_shared_memory_file_wrapper() : xsi_shared_memory() {}
|
||||
|
||||
xsi_shared_memory_file_wrapper(create_only_t, const xsi_key &key, mode_t mode, std::size_t size, const permissions& perm = permissions())
|
||||
: xsi_shared_memory(create_only_t(), key, size, perm.get_permissions())
|
||||
{}
|
||||
|
||||
xsi_shared_memory_file_wrapper(open_or_create_t, const xsi_key &key, mode_t mode, std::size_t size, const permissions& perm = permissions())
|
||||
: xsi_shared_memory(open_or_create_t(), key, size, perm.get_permissions())
|
||||
{}
|
||||
|
||||
xsi_shared_memory_file_wrapper(open_only_t, const xsi_key &key, mode_t mode, const permissions& perm = permissions())
|
||||
: xsi_shared_memory(open_only_t(), key)
|
||||
{}
|
||||
|
||||
xsi_shared_memory_file_wrapper(BOOST_RV_REF(xsi_shared_memory_file_wrapper) moved)
|
||||
{ this->swap(moved); }
|
||||
|
||||
xsi_shared_memory_file_wrapper &operator=(BOOST_RV_REF(xsi_shared_memory_file_wrapper) moved)
|
||||
{
|
||||
xsi_shared_memory_file_wrapper tmp(boost::move(moved));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//!Swaps two xsi_shared_memory_file_wrapper. Does not throw
|
||||
void swap(xsi_shared_memory_file_wrapper &other)
|
||||
{ this->xsi_shared_memory::swap(other); }
|
||||
};
|
||||
|
||||
} //namespace interprocess {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_FILE_WRAPPER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
@@ -112,7 +112,9 @@ enum error_code_t
|
||||
size_error,
|
||||
corrupted_error,
|
||||
not_such_file_or_directory,
|
||||
invalid_argument
|
||||
invalid_argument,
|
||||
timeout_when_locking_error,
|
||||
timeout_when_waiting_error,
|
||||
};
|
||||
|
||||
typedef int native_error_t;
|
||||
@@ -157,7 +159,8 @@ static const ec_xlate ec_table[] =
|
||||
{ /*ERROR_DISK_FULL*/112L, out_of_space_error },
|
||||
{ /*ERROR_OUTOFMEMORY*/14L, out_of_memory_error },
|
||||
{ /*ERROR_NOT_ENOUGH_MEMORY*/8L, out_of_memory_error },
|
||||
{ /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error }
|
||||
{ /*ERROR_TOO_MANY_OPEN_FILES*/4L, out_of_resource_error },
|
||||
{ /*ERROR_INVALID_ADDRESS*/487L, busy_error }
|
||||
#else //#if (defined BOOST_INTERPROCESS_WINDOWS)
|
||||
{ EACCES, security_error },
|
||||
{ EROFS, read_only_error },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under 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)
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user