|
Boost-Commit : |
From: igaztanaga_at_[hidden]
Date: 2007-09-26 11:11:49
Author: igaztanaga
Date: 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
New Revision: 39546
URL: http://svn.boost.org/trac/boost/changeset/39546
Log:
Changes introduced by the new intrusive version.
Added:
trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp (contents, props changed)
trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp (contents, props changed)
Removed:
trunk/boost/interprocess/detail/basic_segment_manager.hpp
trunk/boost/interprocess/detail/gcd_lcm.hpp
trunk/boost/interprocess/detail/generic_cast.hpp
trunk/boost/interprocess/detail/null_create_func.hpp
Text files modified:
trunk/boost/interprocess/allocators/allocation_type.hpp | 4
trunk/boost/interprocess/allocators/allocator.hpp | 12
trunk/boost/interprocess/allocators/cached_node_allocator.hpp | 118 ++--
trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 19
trunk/boost/interprocess/allocators/detail/node_pool.hpp | 19
trunk/boost/interprocess/allocators/detail/node_tools.hpp | 8
trunk/boost/interprocess/allocators/private_adaptive_pool.hpp | 3
trunk/boost/interprocess/allocators/private_node_allocator.hpp | 3
trunk/boost/interprocess/containers/deque.hpp | 601 +++++++++++------------
trunk/boost/interprocess/containers/detail/flat_tree.hpp | 5
trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp | 154 +++--
trunk/boost/interprocess/containers/detail/tree.hpp | 165 +++---
trunk/boost/interprocess/containers/flat_set.hpp | 12
trunk/boost/interprocess/containers/list.hpp | 115 ++--
trunk/boost/interprocess/containers/map.hpp | 11
trunk/boost/interprocess/containers/set.hpp | 6
trunk/boost/interprocess/containers/slist.hpp | 139 ++--
trunk/boost/interprocess/containers/string.hpp | 116 ++--
trunk/boost/interprocess/containers/vector.hpp | 1015 ++++++++++++++++++++-------------------
trunk/boost/interprocess/creation_tags.hpp | 2
trunk/boost/interprocess/errors.hpp | 5
trunk/boost/interprocess/exceptions.hpp | 29
trunk/boost/interprocess/file_mapping.hpp | 50 +
trunk/boost/interprocess/indexes/flat_map_index.hpp | 7
trunk/boost/interprocess/indexes/iset_index.hpp | 55 +-
trunk/boost/interprocess/indexes/iunordered_set_index.hpp | 76 +-
trunk/boost/interprocess/indexes/map_index.hpp | 44
trunk/boost/interprocess/indexes/null_index.hpp | 28
trunk/boost/interprocess/indexes/unordered_map_index.hpp | 32
trunk/boost/interprocess/interprocess_fwd.hpp | 45
trunk/boost/interprocess/ipc/message_queue.hpp | 231 ++++----
trunk/boost/interprocess/managed_external_buffer.hpp | 7
trunk/boost/interprocess/managed_heap_memory.hpp | 8
trunk/boost/interprocess/managed_mapped_file.hpp | 68 +-
trunk/boost/interprocess/managed_shared_memory.hpp | 27
trunk/boost/interprocess/managed_windows_shared_memory.hpp | 42
trunk/boost/interprocess/mapped_region.hpp | 60 +-
trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 484 ++++--------------
trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 629 ++++-------------------
trunk/boost/interprocess/mem_algo/simple_seq_fit.hpp | 15
trunk/boost/interprocess/offset_ptr.hpp | 136 +++--
trunk/boost/interprocess/segment_manager.hpp | 43 +
trunk/boost/interprocess/shared_memory_object.hpp | 23
trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp | 95 +-
trunk/boost/interprocess/smart_ptr/enable_shared_from_this.hpp | 3
trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp | 124 ++--
trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp | 3
trunk/boost/interprocess/smart_ptr/shared_ptr.hpp | 248 ++++++---
trunk/boost/interprocess/smart_ptr/unique_ptr.hpp | 314 +++++++++---
trunk/boost/interprocess/smart_ptr/weak_ptr.hpp | 111 ++++
trunk/boost/interprocess/sync/file_lock.hpp | 89 +-
trunk/boost/interprocess/sync/interprocess_barrier.hpp | 36
trunk/boost/interprocess/sync/interprocess_condition.hpp | 43
trunk/boost/interprocess/sync/interprocess_mutex.hpp | 56 +-
trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 54 +-
trunk/boost/interprocess/sync/interprocess_semaphore.hpp | 46
trunk/boost/interprocess/sync/interprocess_upgradable_mutex.hpp | 208 ++++----
trunk/boost/interprocess/sync/lock_options.hpp | 11
trunk/boost/interprocess/sync/mutex_family.hpp | 13
trunk/boost/interprocess/sync/named_condition.hpp | 233 ++++++---
trunk/boost/interprocess/sync/named_mutex.hpp | 156 +++--
trunk/boost/interprocess/sync/named_recursive_mutex.hpp | 104 +--
trunk/boost/interprocess/sync/named_semaphore.hpp | 171 +++--
trunk/boost/interprocess/sync/named_upgradable_mutex.hpp | 263 ++++-----
trunk/boost/interprocess/sync/null_mutex.hpp | 90 +-
trunk/boost/interprocess/sync/posix/pthread_helpers.hpp | 34
trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 273 ++++++++--
trunk/boost/interprocess/sync/scoped_lock.hpp | 302 +++++-----
trunk/boost/interprocess/sync/sharable_lock.hpp | 232 ++++----
trunk/boost/interprocess/sync/upgradable_lock.hpp | 234 ++++----
trunk/boost/interprocess/windows_shared_memory.hpp | 8
71 files changed, 4149 insertions(+), 4076 deletions(-)
Modified: trunk/boost/interprocess/allocators/allocation_type.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/allocation_type.hpp (original)
+++ trunk/boost/interprocess/allocators/allocation_type.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -32,7 +32,8 @@
// expand_or_new = allocate_new | expand_both,
shrink_in_place_v = 0x08,
nothrow_allocation_v = 0x10,
- zero_memory_v = 0x20
+ zero_memory_v = 0x20,
+ try_shrink_in_place_v = 0x40
};
typedef int allocation_type;
@@ -41,6 +42,7 @@
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;
Modified: trunk/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/allocator.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -201,11 +201,8 @@
//!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_iterator allocate_individual(std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements)
- {
- return this->allocate_many
- (1, min_elements, preferred_elements, received_elements);
- }
+ multiallocation_iterator allocate_individual(std::size_t num_elements)
+ { return this->allocate_many(1, num_elements); }
/// @endcond
@@ -223,11 +220,10 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements)
{
return multiallocation_iterator
- (mp_mngr->allocate_many
- (sizeof(T)*elem_size, min_elements, preferred_elements, received_elements));
+ (mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
}
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
Modified: trunk/boost/interprocess/allocators/cached_node_allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/cached_node_allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/cached_node_allocator.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -30,22 +30,20 @@
#include <stdio.h>
#include <cstddef>
-/*!\file
- Describes cached_cached_node_allocator pooled shared memory STL compatible allocator
-*/
+//!\file
+//!Describes cached_cached_node_allocator pooled shared memory STL compatible allocator
namespace boost {
-
namespace interprocess {
-/*!An STL node allocator that uses a segment manager as memory
- source. The internal pointer type will of the same type (raw, smart) as
- "typename SegmentManager::void_pointer" type. This allows
- placing the allocator in shared memory, memory mapped-files, etc...
- This node allocator shares a segregated storage between all instances of
- cached_node_allocator with equal sizeof(T) placed in the same fixed size
- memory segment. But also caches some nodes privately to
- avoid some synchronization overhead.*/
+//!An STL node allocator that uses a segment manager as memory
+//!source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
+//!This node allocator shares a segregated storage between all instances of
+//!cached_node_allocator with equal sizeof(T) placed in the same fixed size
+//!memory segment. But also caches some nodes privately to
+//!avoid some synchronization overhead.
template<class T, class SegmentManager, std::size_t NodesPerChunk>
class cached_node_allocator
{
@@ -97,30 +95,30 @@
cached_node_allocator& operator=
(const cached_node_allocator<T2, SegmentManager2, N2>&);
- /*!Not assignable from other cached_node_allocator*/
+ //!Not assignable from other cached_node_allocator
cached_node_allocator& operator=(const cached_node_allocator&);
/// @endcond
public:
- /*!Constructor from a segment manager. If not present, constructs
- a node pool. Increments the reference count of the node pool.
- Can throw boost::interprocess::bad_alloc*/
+ //!Constructor from a segment manager. If not present, constructs
+ //!a node pool. Increments the reference count of the node pool.
+ //!Can throw boost::interprocess::bad_alloc
cached_node_allocator(segment_manager *segment_mngr,
std::size_t max_cached_nodes = DEFAULT_MAX_CACHED_NODES)
: mp_node_pool(priv_get_or_create(segment_mngr)),
m_max_cached_nodes(max_cached_nodes)
{}
- /*!Copy constructor from other cached_node_allocator. Increments the
- reference count of the associated node pool. Never throws*/
+ //!Copy constructor from other cached_node_allocator. Increments the
+ //!reference count of the associated node pool. Never throws
cached_node_allocator(const cached_node_allocator &other)
: mp_node_pool(other.get_node_pool()),
m_max_cached_nodes(other.get_max_cached_nodes())
{ mp_node_pool->inc_ref_count(); }
- /*!Copy constructor from related cached_node_allocator. If not present, constructs
- a node pool. Increments the reference count of the associated node pool.
- Can throw boost::interprocess::bad_alloc*/
+ //!Copy constructor from related cached_node_allocator. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
template<class T2>
cached_node_allocator
(const cached_node_allocator<T2, SegmentManager, NodesPerChunk> &other)
@@ -128,31 +126,34 @@
m_max_cached_nodes(other.get_max_cached_nodes())
{ }
- /*!Destructor, removes node_pool_t from memory
- if its reference count reaches to zero. Never throws*/
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
~cached_node_allocator()
{
priv_deallocate_all_cached_nodes();
priv_destroy_if_last_link();
}
- /*!Returns a pointer to the node pool. Never throws*/
+ //!Returns a pointer to the node pool.
+ //!Never throws
node_pool_t* get_node_pool() const
{ return detail::get_pointer(mp_node_pool); }
- /*!Returns the segment manager. Never throws*/
+ //!Returns the segment manager.
+ //!Never throws
segment_manager* get_segment_manager()const
{ return mp_node_pool->get_segment_manager(); }
- /*!Sets the new max cached nodes value. This can provoke deallocations
- if "newmax" is less than current cached nodes. Never throws*/
+ //!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)
{
m_max_cached_nodes = newmax;
priv_deallocate_remaining_nodes();
}
- /*!Returns the max cached nodes parameter. Never throws*/
+ //!Returns the max cached nodes parameter.
+ //!Never throws
std::size_t get_max_cached_nodes() const
{ return m_max_cached_nodes; }
@@ -160,8 +161,8 @@
size_type max_size() const
{ return this->get_segment_manager()->get_size()/sizeof(value_type); }
- /*!Allocate memory for an array of count elements.
- Throws boost::interprocess::bad_alloc if there is no enough memory*/
+ //!Allocate memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
pointer allocate(size_type count, cvoid_pointer hint = 0)
{
(void)hint;
@@ -186,7 +187,8 @@
return pointer(static_cast<T*>(ret));
}
- /*!Deallocate allocated memory. Never throws*/
+ //!Deallocate allocated memory.
+ //!Never throws
void deallocate(const pointer &ptr, size_type count)
{
typedef detail::shared_node_pool
@@ -208,8 +210,8 @@
}
}
- /*!Swaps allocators. Does not throw. If each allocator is placed in a
- different shared memory segments, the result is undefined.*/
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different shared memory segments, the result is undefined.
friend void swap(self_t &alloc1, self_t &alloc2)
{
detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool);
@@ -233,7 +235,8 @@
pointer address(reference value) const
{ return pointer(boost::addressof(value)); }
- /*!Returns address of non mutable object. Never throws*/
+ //!Returns address of non mutable object.
+ //!Never throws
const_pointer address(const_reference value) const
{ return const_pointer(boost::addressof(value)); }
@@ -250,15 +253,15 @@
/// @cond
private:
- /*!Object function that creates the node allocator if it is not created and
- increments reference count if it is already created*/
+ //!Object function that creates the node allocator if it is not created and
+ //!increments reference count if it is already created
struct get_or_create_func
{
typedef detail::shared_node_pool
<SegmentManager, mutex_type, sizeof(T), NodesPerChunk> node_pool_t;
- /*!This connects or constructs the unique instance of node_pool_t
- Can throw boost::interprocess::bad_alloc*/
+ //!This connects or constructs the unique instance of node_pool_t
+ //!Can throw boost::interprocess::bad_alloc
void operator()()
{
//Find or create the node_pool_t
@@ -269,18 +272,21 @@
mp_node_pool->inc_ref_count();
}
- /*!Constructor. Initializes function object parameters*/
+ //!Constructor. Initializes function
+ //!object parameters
get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
node_pool_t *mp_node_pool;
segment_manager *mp_named_alloc;
};
- /*!Frees all cached nodes. Never throws*/
+ //!Frees all cached nodes.
+ //!Never throws
void priv_deallocate_all_cached_nodes()
{ mp_node_pool->deallocate_nodes(m_cached_nodes); }
- /*!Frees all cached nodes at once. Never throws*/
+ //!Frees all cached nodes at once.
+ //!Never throws
void priv_deallocate_remaining_nodes()
{
if(m_cached_nodes.size() > m_max_cached_nodes){
@@ -288,12 +294,13 @@
}
}
- /*!Frees n cached nodes at once. Never throws*/
+ //!Frees n cached nodes at once.
+ //!Never throws
void priv_deallocate_n_nodes(std::size_t n)
{ mp_node_pool->deallocate_nodes(m_cached_nodes, n); }
- /*!Initialization function, creates an executes atomically the
- initialization object functions. Can throw boost::interprocess::bad_alloc*/
+ //!Initialization function, creates an executes atomically the
+ //!initialization object functions. Can throw boost::interprocess::bad_alloc
node_pool_t *priv_get_or_create(segment_manager *named_alloc)
{
get_or_create_func func(named_alloc);
@@ -301,16 +308,16 @@
return func.mp_node_pool;
}
- /*!Object function that decrements the reference count. If the count
- reaches to zero destroys the node allocator from memory.
- Never throws*/
+ //!Object function that decrements the reference count. If the count
+ //!reaches to zero destroys the node allocator from memory.
+ //!Never throws
struct destroy_if_last_link_func
{
typedef detail::shared_node_pool
<SegmentManager, mutex_type,sizeof(T), NodesPerChunk> node_pool_t;
- /*!Decrements reference count and destroys the object if there is no
- more attached allocators. Never throws*/
+ //!Decrements reference count and destroys the object if there is no
+ //!more attached allocators. Never throws
void operator()()
{
//If not the last link return
@@ -320,7 +327,8 @@
mp_named_alloc->template destroy<node_pool_t>(unique_instance);
}
- /*!Constructor. Initializes function object parameters*/
+ //!Constructor. Initializes function object
+ //!parameters
destroy_if_last_link_func(segment_manager *nhdr,
node_pool_t *phdr)
: mp_named_alloc(nhdr), mp_node_pool(phdr){}
@@ -329,8 +337,8 @@
node_pool_t *mp_node_pool;
};
- /*!Destruction function, initializes and executes destruction function
- object. Never throws*/
+ //!Destruction function, initializes and executes destruction function
+ //!object. Never throws
void priv_destroy_if_last_link()
{
typedef detail::shared_node_pool
@@ -349,13 +357,15 @@
/// @endcond
};
-/*!Equality test for same type of cached_node_allocator*/
+//!Equality test for same type of
+//!cached_node_allocator
template<class T, class S, std::size_t NodesPerChunk> inline
bool operator==(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
const cached_node_allocator<T, S, NodesPerChunk> &alloc2)
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); }
-/*!Inequality test for same type of cached_node_allocator*/
+//!Inequality test for same type of
+//!cached_node_allocator
template<class T, class S, std::size_t NodesPerChunk> inline
bool operator!=(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
const cached_node_allocator<T, S, NodesPerChunk> &alloc2)
Modified: trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -13,8 +13,6 @@
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
-# pragma warning (disable : 4503)
-
#endif
#include <boost/interprocess/detail/config_begin.hpp>
@@ -34,9 +32,8 @@
#include <cassert>
#include <assert.h>
-/*!\file
- Describes the real adaptive pool shared by many Interprocess pool allocators
-*/
+//!\file
+//!Describes the real adaptive pool shared by many Interprocess pool allocators
namespace boost {
namespace interprocess {
@@ -62,8 +59,8 @@
private:
//This hook will be used to chain the memory chunks
- typedef boost::intrusive::list_base_hook
- < boost::intrusive::tag, boost::intrusive::normal_link, void_pointer> list_hook_t;
+ typedef typename bi::make_list_base_hook
+ <bi::void_pointer<void_pointer>, bi::link_mode<bi::normal_link> >::type list_hook_t;
struct chunk_info_t
: public list_hook_t
@@ -71,9 +68,7 @@
//An intrusive list of free node from this chunk
free_nodes_t free_nodes;
};
-
- typedef boost::intrusive::list
- <typename list_hook_t::template value_traits<chunk_info_t> > chunk_list_t;
+ typedef typename bi::make_list<chunk_info_t, bi::base_hook<list_hook_t> >::type chunk_list_t;
public:
//!Segment manager typedef
@@ -324,7 +319,7 @@
//We put the node at the beginning of the free node list
node_t * to_deallocate = static_cast<node_t*>(pElem);
chunk_info->free_nodes.push_front(*to_deallocate);
- chunk_iterator this_chunk(chunk_list_t::iterator_to(*chunk_info));
+ chunk_iterator this_chunk(chunk_list_t::s_iterator_to(*chunk_info));
chunk_iterator next_chunk(this_chunk);
++next_chunk;
@@ -343,7 +338,7 @@
}
//Update m_first_free_chunk if the moved chunk crosses the empty boundary
else if(this_chunk->free_nodes.size() == 1){
- m_first_free_chunk = chunk_list_t::iterator_to(*chunk_info);
+ m_first_free_chunk = chunk_list_t::s_iterator_to(*chunk_info);
}
//Now move the chunk to the new position
m_chunklist.erase(this_chunk);
Modified: trunk/boost/interprocess/allocators/detail/node_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/node_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/node_pool.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -13,7 +13,6 @@
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
-# pragma warning (disable : 4503)
#endif
#include <boost/interprocess/detail/config_begin.hpp>
@@ -31,9 +30,8 @@
#include <algorithm>
#include <assert.h>
-/*!\file
- Describes the real adaptive pool shared by many Interprocess adaptive pool allocators
-*/
+//!\file
+//!Describes the real adaptive pool shared by many Interprocess adaptive pool allocators
namespace boost {
namespace interprocess {
@@ -49,15 +47,14 @@
//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::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;
private:
- typedef boost::intrusive::slist
- <typename slist_hook_t::template value_traits<node_t>, false > chunkslist_t;
-
+ typedef typename bi::make_slist < node_t, bi::base_hook<slist_hook_t>
+ , bi::constant_time_size<false> >::type chunkslist_t;
public:
//!Segment manager typedef
Modified: trunk/boost/interprocess/allocators/detail/node_tools.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/node_tools.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/node_tools.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -13,7 +13,6 @@
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
-# pragma warning (disable : 4503)
#endif
#include <boost/interprocess/detail/config_begin.hpp>
@@ -30,16 +29,15 @@
struct node_slist
{
//This hook will be used to chain the individual nodes
- typedef boost::intrusive::slist_base_hook
- <boost::intrusive::tag, boost::intrusive::normal_link, VoidPointer> slist_hook_t;
+ 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
struct node_t
: public slist_hook_t
{};
- typedef boost::intrusive::slist
- <typename slist_hook_t::template value_traits<node_t> > node_slist_t;
+ typedef typename bi::make_slist<node_t, bi::base_hook<slist_hook_t> >::type node_slist_t;
};
} //namespace detail {
Modified: trunk/boost/interprocess/allocators/private_adaptive_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/private_adaptive_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/private_adaptive_pool.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -158,7 +158,8 @@
pointer address(reference value) const
{ return pointer(boost::addressof(value)); }
- /*!Returns address of non mutable object. Never throws*/
+ //!Returns address of non mutable object.
+ //!Never throws
const_pointer address(const_reference value) const
{ return const_pointer(boost::addressof(value)); }
Modified: trunk/boost/interprocess/allocators/private_node_allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/private_node_allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/private_node_allocator.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -156,7 +156,8 @@
pointer address(reference value) const
{ return pointer(boost::addressof(value)); }
- /*!Returns address of non mutable object. Never throws*/
+ //!Returns address of non mutable object.
+ //!Never throws
const_pointer address(const_reference value) const
{ return const_pointer(boost::addressof(value)); }
Modified: trunk/boost/interprocess/containers/deque.hpp
==============================================================================
--- trunk/boost/interprocess/containers/deque.hpp (original)
+++ trunk/boost/interprocess/containers/deque.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -85,35 +85,24 @@
// exception safety easier.
template <class T, class Alloc>
class deque_base
- : public Alloc::template rebind<T>::other,
- public Alloc::template rebind<typename Alloc::pointer>::other
{
- public:
- typedef typename Alloc::value_type val_alloc_val;
- typedef typename Alloc::pointer val_alloc_ptr;
- typedef typename Alloc::const_pointer val_alloc_cptr;
- typedef typename Alloc::reference val_alloc_ref;
- typedef typename Alloc::const_reference val_alloc_cref;
- typedef typename Alloc::value_type val_alloc_diff;
+ public:
+ typedef typename Alloc::value_type val_alloc_val;
+ typedef typename Alloc::pointer val_alloc_ptr;
+ typedef typename Alloc::const_pointer val_alloc_cptr;
+ typedef typename Alloc::reference val_alloc_ref;
+ typedef typename Alloc::const_reference val_alloc_cref;
+ typedef typename Alloc::value_type val_alloc_diff;
typedef typename Alloc::template rebind
- <typename Alloc::pointer>::other ptr_alloc;
- typedef typename ptr_alloc::value_type ptr_alloc_val;
- typedef typename ptr_alloc::pointer ptr_alloc_ptr;
- typedef typename ptr_alloc::const_pointer ptr_alloc_cptr;
- typedef typename ptr_alloc::reference ptr_alloc_ref;
- typedef typename ptr_alloc::const_reference ptr_alloc_cref;
+ <typename Alloc::pointer>::other ptr_alloc_t;
+ typedef typename ptr_alloc_t::value_type ptr_alloc_val;
+ typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
+ typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
+ typedef typename ptr_alloc_t::reference ptr_alloc_ref;
+ typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
typedef typename Alloc::template
- rebind<T>::other allocator_type;
- typedef allocator_type stored_allocator_type;
-
- allocator_type get_allocator() const
- { return *this; }
-
- const stored_allocator_type &get_stored_allocator() const
- { return *this; }
-
- stored_allocator_type &get_stored_allocator()
- { return *this; }
+ rebind<T>::other allocator_type;
+ typedef allocator_type stored_allocator_type;
protected:
enum { trivial_dctr_after_move = boost::has_trivial_destructor<val_alloc_val>::value };
@@ -122,16 +111,16 @@
rebind<typename Alloc::pointer>::other map_allocator_type;
val_alloc_ptr priv_allocate_node()
- { return this->allocator_type::allocate(deque_buf_size(sizeof(T))); }
+ { return this->alloc().allocate(deque_buf_size(sizeof(T))); }
void priv_deallocate_node(val_alloc_ptr p)
- { this->allocator_type::deallocate(p, deque_buf_size(sizeof(T))); }
+ { this->alloc().deallocate(p, deque_buf_size(sizeof(T))); }
ptr_alloc_ptr priv_allocate_map(std::size_t n)
- { return this->map_allocator_type::allocate(n); }
+ { return this->ptr_alloc().allocate(n); }
void priv_deallocate_map(ptr_alloc_ptr p, std::size_t n)
- { this->map_allocator_type::deallocate(p, n); }
+ { this->ptr_alloc().deallocate(p, n); }
public:
// Class invariants:
@@ -302,7 +291,7 @@
{ return x + n; }
};
- //Vector iterator
+ //Deque iterator
class iterator : public const_iterator
{
public:
@@ -368,75 +357,48 @@
};
deque_base(const allocator_type& a, std::size_t num_elements)
- : allocator_type(a), map_allocator_type(a),
- m_map(0), m_map_size(0),
- m_start(), m_finish()
- { this->priv_initialize_map(num_elements); }
+ : members_(a)
+ { this->priv_initialize_map(num_elements); }
deque_base(const allocator_type& a)
- : allocator_type(a), map_allocator_type(a),
- m_map(0), m_map_size(0), m_start(), m_finish() {}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- deque_base(const detail::moved_object<deque_base> &md)
- : allocator_type(md.get()), map_allocator_type(md.get()),
- m_map(md.get().m_map), m_map_size(md.get().m_map_size),
- m_start(md.get().m_start), m_finish(md.get().m_finish)
- {
- m_map = 0;
- m_map_size = 0;
- m_start = iterator();
- m_finish = iterator();
- }
- #else
- deque_base(deque_base &&md)
- : allocator_type(md), map_allocator_type(md),
- m_map(md.m_map), m_map_size(md.m_map_size),
- m_start(md.m_start), m_finish(md.m_finish)
- {
- m_map = 0;
- m_map_size = 0;
- m_start = iterator();
- m_finish = iterator();
- }
- #endif
+ : members_(a)
+ {}
~deque_base()
{
- if (this->m_map) {
- this->priv_destroy_nodes(this->m_start.m_node, this->m_finish.m_node + 1);
- this->priv_deallocate_map(this->m_map, this->m_map_size);
+ if (this->members_.m_map) {
+ this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
}
}
- protected:
+ protected:
void priv_initialize_map(std::size_t num_elements)
{
std::size_t num_nodes = num_elements / deque_buf_size(sizeof(T)) + 1;
- this->m_map_size = max_value((std::size_t) InitialMapSize, num_nodes + 2);
- this->m_map = this->priv_allocate_map(this->m_map_size);
+ this->members_.m_map_size = max_value((std::size_t) InitialMapSize, num_nodes + 2);
+ this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
- ptr_alloc_ptr nstart = this->m_map + (this->m_map_size - num_nodes) / 2;
+ ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
ptr_alloc_ptr nfinish = nstart + num_nodes;
BOOST_TRY {
this->priv_create_nodes(nstart, nfinish);
}
BOOST_CATCH(...){
- this->priv_deallocate_map(this->m_map, this->m_map_size);
- this->m_map = 0;
- this->m_map_size = 0;
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ this->members_.m_map = 0;
+ this->members_.m_map_size = 0;
BOOST_RETHROW
}
BOOST_CATCH_END
- this->m_start.priv_set_node(nstart);
- this->m_finish.priv_set_node(nfinish - 1);
- this->m_start.m_cur = this->m_start.m_first;
- this->m_finish.m_cur = this->m_finish.m_first +
+ this->members_.m_start.priv_set_node(nstart);
+ this->members_.m_finish.priv_set_node(nfinish - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
num_elements % deque_buf_size(sizeof(T));
-
}
void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
@@ -461,11 +423,34 @@
enum { InitialMapSize = 8 };
- protected:
- ptr_alloc_ptr m_map;
- std::size_t m_map_size;
- iterator m_start;
- iterator m_finish;
+ protected:
+ struct members_holder
+ : public ptr_alloc_t
+ , public allocator_type
+ {
+ members_holder(const allocator_type &a)
+ : map_allocator_type(a), allocator_type(a)
+ , m_map(0), m_map_size(0)
+ , m_start(), m_finish()
+ {}
+
+ ptr_alloc_ptr m_map;
+ std::size_t m_map_size;
+ iterator m_start;
+ iterator m_finish;
+ } members_;
+
+ ptr_alloc_t &ptr_alloc()
+ { return members_; }
+
+ const ptr_alloc_t &ptr_alloc() const
+ { return members_; }
+
+ allocator_type &alloc()
+ { return members_; }
+
+ const allocator_type &alloc() const
+ { return members_; }
};
/// @endcond
@@ -483,12 +468,12 @@
typedef typename Alloc::reference val_alloc_ref;
typedef typename Alloc::const_reference val_alloc_cref;
typedef typename Alloc::template
- rebind<val_alloc_ptr>::other ptr_alloc;
- typedef typename ptr_alloc::value_type ptr_alloc_val;
- typedef typename ptr_alloc::pointer ptr_alloc_ptr;
- typedef typename ptr_alloc::const_pointer ptr_alloc_cptr;
- typedef typename ptr_alloc::reference ptr_alloc_ref;
- typedef typename ptr_alloc::const_reference ptr_alloc_cref;
+ rebind<val_alloc_ptr>::other ptr_alloc_t;
+ typedef typename ptr_alloc_t::value_type ptr_alloc_val;
+ typedef typename ptr_alloc_t::pointer ptr_alloc_ptr;
+ typedef typename ptr_alloc_t::const_pointer ptr_alloc_cptr;
+ typedef typename ptr_alloc_t::reference ptr_alloc_ref;
+ typedef typename ptr_alloc_t::const_reference ptr_alloc_cref;
typedef T value_type;
typedef val_alloc_ptr pointer;
@@ -499,7 +484,7 @@
typedef std::ptrdiff_t difference_type;
typedef typename Base::allocator_type allocator_type;
- allocator_type get_allocator() const { return Base::get_allocator(); }
+ allocator_type get_allocator() const { return Base::alloc(); }
public: // Iterators
typedef typename Base::iterator iterator;
@@ -513,52 +498,38 @@
typedef ptr_alloc_ptr index_pointer;
static std::size_t s_buffer_size()
{ return deque_buf_size(sizeof(T)); }
-
- protected:
- using Base::priv_initialize_map;
- using Base::priv_create_nodes;
- using Base::priv_destroy_nodes;
- using Base::priv_allocate_node;
- using Base::priv_deallocate_node;
- using Base::priv_allocate_map;
- using Base::priv_deallocate_map;
-
- using Base::m_map;
- using Base::m_map_size;
- using Base::m_start;
- using Base::m_finish;
/// @endcond
public: // Basic accessors
iterator begin()
- { return this->m_start; }
+ { return this->members_.m_start; }
iterator end()
- { return this->m_finish; }
+ { return this->members_.m_finish; }
const_iterator begin() const
- { return this->m_start; }
+ { return this->members_.m_start; }
const_iterator end() const
- { return this->m_finish; }
+ { return this->members_.m_finish; }
reverse_iterator rbegin()
- { return reverse_iterator(this->m_finish); }
+ { return reverse_iterator(this->members_.m_finish); }
reverse_iterator rend()
- { return reverse_iterator(this->m_start); }
+ { return reverse_iterator(this->members_.m_start); }
const_reverse_iterator rbegin() const
- { return const_reverse_iterator(this->m_finish); }
+ { return const_reverse_iterator(this->members_.m_finish); }
const_reverse_iterator rend() const
- { return const_reverse_iterator(this->m_start); }
+ { return const_reverse_iterator(this->members_.m_start); }
reference operator[](size_type n)
- { return this->m_start[difference_type(n)]; }
+ { return this->members_.m_start[difference_type(n)]; }
const_reference operator[](size_type n) const
- { return this->m_start[difference_type(n)]; }
+ { return this->members_.m_start[difference_type(n)]; }
void priv_range_check(size_type n) const
{ if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
@@ -569,44 +540,45 @@
const_reference at(size_type n) const
{ this->priv_range_check(n); return (*this)[n]; }
- reference front() { return *this->m_start; }
+ reference front() { return *this->members_.m_start; }
reference back()
{
- iterator tmp = this->m_finish;
+ iterator tmp = this->members_.m_finish;
--tmp;
return *tmp;
}
const_reference front() const
- { return *this->m_start; }
+ { return *this->members_.m_start; }
const_reference back() const
- { const_iterator tmp = this->m_finish; --tmp; return *tmp; }
+ { const_iterator tmp = this->members_.m_finish; --tmp; return *tmp; }
size_type size() const
- { return this->m_finish - this->m_start; }
+ { return this->members_.m_finish - this->members_.m_start; }
size_type max_size() const
- { return allocator_type::max_size(); }
+ { return this->alloc().max_size(); }
bool empty() const
- { return this->m_finish == this->m_start; }
+ { return this->members_.m_finish == this->members_.m_start; }
explicit deque(const allocator_type& a = allocator_type())
: Base(a, 0) {}
- deque(const deque& x) : Base(x.get_allocator(), x.size())
- { std::uninitialized_copy(x.begin(), x.end(), this->m_start); }
+ deque(const deque& x)
+ : Base(x.alloc(), x.size())
+ { std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start); }
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
deque(const detail::moved_object<deque> &mx)
- : Base(move((Base&)mx.get()))
- {}
+ : Base(mx.get())
+ { this->swap(mx.get()); }
#else
- deque(deque &&mx)
- : Base(move((Base&)mx))
- {}
+ deque(deque &&x)
+ : Base(x))
+ { this->swap(x); }
#endif
deque(size_type n, const value_type& value,
@@ -628,18 +600,18 @@
}
~deque()
- { priv_destroy_range(this->m_start, this->m_finish); }
+ { priv_destroy_range(this->members_.m_start, this->members_.m_finish); }
deque& operator= (const deque& x)
{
const size_type len = size();
if (&x != this) {
if (len >= x.size())
- this->erase(std::copy(x.begin(), x.end(), this->m_start), this->m_finish);
+ this->erase(std::copy(x.begin(), x.end(), this->members_.m_start), this->members_.m_finish);
else {
const_iterator mid = x.begin() + difference_type(len);
- std::copy(x.begin(), mid, this->m_start);
- this->insert(this->m_finish, mid, x.end());
+ std::copy(x.begin(), mid, this->members_.m_start);
+ this->insert(this->members_.m_finish, mid, x.end());
}
}
return *this;
@@ -655,10 +627,10 @@
void swap(deque& x)
{
- std::swap(this->m_start, x.m_start);
- std::swap(this->m_finish, x.m_finish);
- std::swap(this->m_map, x.m_map);
- std::swap(this->m_map_size, x.m_map_size);
+ std::swap(this->members_.m_start, x.members_.m_start);
+ std::swap(this->members_.m_finish, x.members_.m_finish);
+ std::swap(this->members_.m_map, x.members_.m_map);
+ std::swap(this->members_.m_map_size, x.members_.m_map_size);
}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -669,9 +641,8 @@
{ this->swap(mx); }
#endif
- void assign(size_type n, const T& val) {
- this->priv_fill_assign(n, val);
- }
+ void assign(size_type n, const T& val)
+ { this->priv_fill_assign(n, val); }
template <class InpIt>
void assign(InpIt first, InpIt last) {
@@ -683,9 +654,9 @@
void push_back(const value_type& t)
{
- if (this->m_finish.m_cur != this->m_finish.m_last - 1) {
- new(detail::get_pointer(this->m_finish.m_cur))value_type(t);
- ++this->m_finish.m_cur;
+ if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
+ new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
+ ++this->members_.m_finish.m_cur;
}
else
this->priv_push_back_aux(t);
@@ -694,9 +665,9 @@
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void push_back(const detail::moved_object<value_type> &mt)
{
- if (this->m_finish.m_cur != this->m_finish.m_last - 1) {
- new(detail::get_pointer(this->m_finish.m_cur))value_type(mt);
- ++this->m_finish.m_cur;
+ if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
+ new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
+ ++this->members_.m_finish.m_cur;
}
else
this->priv_push_back_aux(mt);
@@ -704,9 +675,9 @@
#else
void push_back(value_type &&mt)
{
- if (this->m_finish.m_cur != this->m_finish.m_last - 1) {
- new(detail::get_pointer(this->m_finish.m_cur))value_type(move(mt));
- ++this->m_finish.m_cur;
+ if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
+ new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
+ ++this->members_.m_finish.m_cur;
}
else
this->priv_push_back_aux(move(mt));
@@ -715,9 +686,9 @@
void push_front(const value_type& t)
{
- if (this->m_start.m_cur != this->m_start.m_first) {
- new(detail::get_pointer(this->m_start.m_cur)- 1)value_type(t);
- --this->m_start.m_cur;
+ if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
+ new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(t);
+ --this->members_.m_start.m_cur;
}
else
this->priv_push_front_aux(t);
@@ -726,9 +697,9 @@
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void push_front(const detail::moved_object<value_type> &mt)
{
- if (this->m_start.m_cur != this->m_start.m_first) {
- new(detail::get_pointer(this->m_start.m_cur)- 1)value_type(mt);
- --this->m_start.m_cur;
+ if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
+ new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(mt);
+ --this->members_.m_start.m_cur;
}
else
this->priv_push_front_aux(mt);
@@ -736,9 +707,9 @@
#else
void push_front(value_type &&mt)
{
- if (this->m_start.m_cur != this->m_start.m_first) {
- new(detail::get_pointer(this->m_start.m_cur)- 1)value_type(move(mt));
- --this->m_start.m_cur;
+ if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
+ new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(move(mt));
+ --this->members_.m_start.m_cur;
}
else
this->priv_push_front_aux(move(mt));
@@ -747,9 +718,9 @@
void pop_back()
{
- if (this->m_finish.m_cur != this->m_finish.m_first) {
- --this->m_finish.m_cur;
- detail::get_pointer(this->m_finish.m_cur)->~value_type();
+ if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
+ --this->members_.m_finish.m_cur;
+ detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
}
else
this->priv_pop_back_aux();
@@ -757,9 +728,9 @@
void pop_front()
{
- if (this->m_start.m_cur != this->m_start.m_last - 1) {
- detail::get_pointer(this->m_start.m_cur)->~value_type();
- ++this->m_start.m_cur;
+ if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
+ detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
+ ++this->members_.m_start.m_cur;
}
else
this->priv_pop_front_aux();
@@ -767,13 +738,13 @@
iterator insert(iterator position, const value_type& x)
{
- if (position.m_cur == this->m_start.m_cur) {
+ if (position.m_cur == this->members_.m_start.m_cur) {
this->push_front(x);
- return this->m_start;
+ return this->members_.m_start;
}
- else if (position.m_cur == this->m_finish.m_cur) {
+ else if (position.m_cur == this->members_.m_finish.m_cur) {
this->push_back(x);
- iterator tmp = this->m_finish;
+ iterator tmp = this->members_.m_finish;
--tmp;
return tmp;
}
@@ -785,13 +756,13 @@
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
iterator insert(iterator position, const detail::moved_object<value_type> &mx)
{
- if (position.m_cur == this->m_start.m_cur) {
+ if (position.m_cur == this->members_.m_start.m_cur) {
this->push_front(mx);
- return this->m_start;
+ return this->members_.m_start;
}
- else if (position.m_cur == this->m_finish.m_cur) {
+ else if (position.m_cur == this->members_.m_finish.m_cur) {
this->push_back(mx);
- iterator tmp = this->m_finish;
+ iterator tmp = this->members_.m_finish;
--tmp;
return tmp;
}
@@ -802,13 +773,13 @@
#else
iterator insert(iterator position, value_type &&mx)
{
- if (position.m_cur == this->m_start.m_cur) {
+ if (position.m_cur == this->members_.m_start.m_cur) {
this->push_front(move(mx));
- return this->m_start;
+ return this->members_.m_start;
}
- else if (position.m_cur == this->m_finish.m_cur) {
+ else if (position.m_cur == this->members_.m_finish.m_cur) {
this->push_back(move(mx));
- iterator tmp = this->m_finish;
+ iterator tmp = this->members_.m_finish;
--tmp;
return tmp;
}
@@ -835,16 +806,16 @@
{
const size_type len = size();
if (new_size < len)
- this->erase(this->m_start + new_size, this->m_finish);
+ this->erase(this->members_.m_start + new_size, this->members_.m_finish);
else
- this->insert(this->m_finish, new_size - len, x);
+ this->insert(this->members_.m_finish, new_size - len, x);
}
void resize(size_type new_size)
{
const size_type len = size();
if (new_size < len)
- this->erase(this->m_start + new_size, this->m_finish);
+ this->erase(this->members_.m_start + new_size, this->members_.m_finish);
else{
size_type n = new_size - this->size();
this->priv_reserve_elements_at_back(new_size);
@@ -865,73 +836,73 @@
{
iterator next = pos;
++next;
- difference_type index = pos - this->m_start;
+ difference_type index = pos - this->members_.m_start;
if (size_type(index) < (this->size() >> 1)) {
- std::copy_backward( detail::make_move_iterator(this->m_start)
+ std::copy_backward( detail::make_move_iterator(this->members_.m_start)
, detail::make_move_iterator(pos)
, next);
pop_front();
}
else {
std::copy( detail::make_move_iterator(next)
- , detail::make_move_iterator(this->m_finish)
+ , detail::make_move_iterator(this->members_.m_finish)
, pos);
pop_back();
}
- return this->m_start + index;
+ return this->members_.m_start + index;
}
iterator erase(iterator first, iterator last)
{
- if (first == this->m_start && last == this->m_finish) {
+ if (first == this->members_.m_start && last == this->members_.m_finish) {
this->clear();
- return this->m_finish;
+ return this->members_.m_finish;
}
else {
difference_type n = last - first;
- difference_type elems_before = first - this->m_start;
+ difference_type elems_before = first - this->members_.m_start;
if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
- std::copy_backward( detail::make_move_iterator(this->m_start)
+ std::copy_backward( detail::make_move_iterator(this->members_.m_start)
, detail::make_move_iterator(first)
, last);
- iterator new_start = this->m_start + n;
+ iterator new_start = this->members_.m_start + n;
if(!Base::trivial_dctr_after_move)
- this->priv_destroy_range(this->m_start, new_start);
- this->priv_destroy_nodes(new_start.m_node, this->m_start.m_node);
- this->m_start = new_start;
+ this->priv_destroy_range(this->members_.m_start, new_start);
+ this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
+ this->members_.m_start = new_start;
}
else {
std::copy( detail::make_move_iterator(last)
- , detail::make_move_iterator(this->m_finish)
+ , detail::make_move_iterator(this->members_.m_finish)
, first);
- iterator new_finish = this->m_finish - n;
+ iterator new_finish = this->members_.m_finish - n;
if(!Base::trivial_dctr_after_move)
- this->priv_destroy_range(new_finish, this->m_finish);
- this->priv_destroy_nodes(new_finish.m_node + 1, this->m_finish.m_node + 1);
- this->m_finish = new_finish;
+ this->priv_destroy_range(new_finish, this->members_.m_finish);
+ this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+ this->members_.m_finish = new_finish;
}
- return this->m_start + elems_before;
+ return this->members_.m_start + elems_before;
}
}
void clear()
{
- for (index_pointer node = this->m_start.m_node + 1;
- node < this->m_finish.m_node;
+ for (index_pointer node = this->members_.m_start.m_node + 1;
+ node < this->members_.m_finish.m_node;
++node) {
this->priv_destroy_range(*node, *node + this->s_buffer_size());
this->priv_deallocate_node(*node);
}
- if (this->m_start.m_node != this->m_finish.m_node) {
- this->priv_destroy_range(this->m_start.m_cur, this->m_start.m_last);
- this->priv_destroy_range(this->m_finish.m_first, this->m_finish.m_cur);
- this->priv_deallocate_node(this->m_finish.m_first);
+ if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
+ this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
+ this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
+ this->priv_deallocate_node(this->members_.m_finish.m_first);
}
else
- this->priv_destroy_range(this->m_start.m_cur, this->m_finish.m_cur);
+ this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
- this->m_finish = this->m_start;
+ this->members_.m_finish = this->members_.m_start;
}
/// @cond
@@ -948,26 +919,26 @@
size_type n = 0;
n = std::distance(first, last);
- if (pos.m_cur == this->m_start.m_cur) {
+ if (pos.m_cur == this->members_.m_start.m_cur) {
iterator new_start = this->priv_reserve_elements_at_front(n);
BOOST_TRY{
- boost::interprocess::uninitialized_copy(first, last, new_start);
- this->m_start = new_start;
+ std::uninitialized_copy(first, last, new_start);
+ this->members_.m_start = new_start;
}
BOOST_CATCH(...){
- this->priv_destroy_nodes(new_start.m_node, this->m_start.m_node);
+ this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
BOOST_RETHROW
}
BOOST_CATCH_END
}
- else if (pos.m_cur == this->m_finish.m_cur) {
+ else if (pos.m_cur == this->members_.m_finish.m_cur) {
iterator new_finish = this->priv_reserve_elements_at_back(n);
BOOST_TRY{
- boost::interprocess::uninitialized_copy(first, last, this->m_finish);
- this->m_finish = new_finish;
+ std::uninitialized_copy(first, last, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
}
BOOST_CATCH(...){
- this->priv_destroy_nodes(this->m_finish.m_node + 1, new_finish.m_node + 1);
+ this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1113,17 +1084,17 @@
template <class FwdIt>
void priv_insert_aux(iterator pos, FwdIt first, FwdIt last, size_type n)
{
- const difference_type elemsbefore = pos - this->m_start;
+ const difference_type elemsbefore = pos - this->members_.m_start;
size_type length = size();
if (elemsbefore < static_cast<difference_type>(length / 2)) {
iterator new_start = this->priv_reserve_elements_at_front(n);
- iterator old_start = this->m_start;
- pos = this->m_start + elemsbefore;
+ iterator old_start = this->members_.m_start;
+ pos = this->members_.m_start + elemsbefore;
BOOST_TRY {
if (elemsbefore >= difference_type(n)) {
- iterator start_n = this->m_start + difference_type(n);
- boost::interprocess::uninitialized_copy(detail::make_move_iterator(this->m_start), detail::make_move_iterator(start_n), new_start);
- this->m_start = new_start;
+ iterator start_n = this->members_.m_start + difference_type(n);
+ std::uninitialized_copy(detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(start_n), new_start);
+ this->members_.m_start = new_start;
std::copy(detail::make_move_iterator(start_n), detail::make_move_iterator(pos), old_start);
std::copy(first, last, pos - difference_type(n));
}
@@ -1131,41 +1102,41 @@
FwdIt mid = first;
std::advance(mid, difference_type(n) - elemsbefore);
this->priv_uninitialized_copy_copy
- (detail::make_move_iterator(this->m_start), detail::make_move_iterator(pos), first, mid, new_start);
- this->m_start = new_start;
+ (detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(pos), first, mid, new_start);
+ this->members_.m_start = new_start;
std::copy(mid, last, old_start);
}
}
BOOST_CATCH(...){
- this->priv_destroy_nodes(new_start.m_node, this->m_start.m_node);
+ this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
BOOST_RETHROW
}
BOOST_CATCH_END
}
else {
iterator new_finish = this->priv_reserve_elements_at_back(n);
- iterator old_finish = this->m_finish;
+ iterator old_finish = this->members_.m_finish;
const difference_type elemsafter =
difference_type(length) - elemsbefore;
- pos = this->m_finish - elemsafter;
+ pos = this->members_.m_finish - elemsafter;
BOOST_TRY {
if (elemsafter > difference_type(n)) {
- iterator finish_n = this->m_finish - difference_type(n);
- boost::interprocess::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->m_finish), this->m_finish);
- this->m_finish = new_finish;
+ iterator finish_n = this->members_.m_finish - difference_type(n);
+ std::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish);
+ this->members_.m_finish = new_finish;
std::copy_backward(detail::make_move_iterator(pos), detail::make_move_iterator(finish_n), old_finish);
std::copy(first, last, pos);
}
else {
FwdIt mid = first;
std::advance(mid, elemsafter);
- this->priv_uninitialized_copy_copy(mid, last, detail::make_move_iterator(pos), detail::make_move_iterator(this->m_finish), this->m_finish);
- this->m_finish = new_finish;
+ this->priv_uninitialized_copy_copy(mid, last, detail::make_move_iterator(pos), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish);
+ this->members_.m_finish = new_finish;
std::copy(first, mid, pos);
}
}
BOOST_CATCH(...){
- this->priv_destroy_nodes(this->m_finish.m_node + 1, new_finish.m_node + 1);
+ this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1178,19 +1149,19 @@
this->insert(pos, c_it(x, n), c_it());
}
- // Precondition: this->m_start and this->m_finish have already been initialized,
+ // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
// but none of the deque's elements have yet been constructed.
void priv_fill_initialize(const value_type& value)
{
index_pointer cur;
BOOST_TRY {
- for (cur = this->m_start.m_node; cur < this->m_finish.m_node; ++cur){
- boost::interprocess::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
+ for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
+ std::uninitialized_fill(*cur, *cur + this->s_buffer_size(), value);
}
- boost::interprocess::uninitialized_fill(this->m_finish.m_first, this->m_finish.m_cur, value);
+ std::uninitialized_fill(this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
}
BOOST_CATCH(...){
- this->priv_destroy_range(this->m_start, iterator(*cur, cur));
+ this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1220,53 +1191,53 @@
index_pointer cur_node;
BOOST_TRY {
- for (cur_node = this->m_start.m_node;
- cur_node < this->m_finish.m_node;
+ for (cur_node = this->members_.m_start.m_node;
+ cur_node < this->members_.m_finish.m_node;
++cur_node) {
FwdIt mid = first;
std::advance(mid, this->s_buffer_size());
- boost::interprocess::uninitialized_copy(first, mid, *cur_node);
+ std::uninitialized_copy(first, mid, *cur_node);
first = mid;
}
- boost::interprocess::uninitialized_copy(first, last, this->m_finish.m_first);
+ std::uninitialized_copy(first, last, this->members_.m_finish.m_first);
}
BOOST_CATCH(...){
- this->priv_destroy_range(this->m_start, iterator(*cur_node, cur_node));
+ this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
BOOST_RETHROW
}
BOOST_CATCH_END
}
- // Called only if this->m_finish.m_cur == this->m_finish.m_last - 1.
+ // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_last - 1.
void priv_push_back_aux(const value_type& t = value_type())
{
this->priv_reserve_map_at_back();
- *(this->m_finish.m_node + 1) = this->priv_allocate_node();
+ *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
BOOST_TRY {
- new(detail::get_pointer(this->m_finish.m_cur))value_type(t);
- this->m_finish.priv_set_node(this->m_finish.m_node + 1);
- this->m_finish.m_cur = this->m_finish.m_first;
+ new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
+ this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
}
BOOST_CATCH(...){
- this->priv_deallocate_node(*(this->m_finish.m_node + 1));
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1));
BOOST_RETHROW
}
BOOST_CATCH_END
}
- // Called only if this->m_finish.m_cur == this->m_finish.m_last - 1.
+ // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_last - 1.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void priv_push_back_aux(const detail::moved_object<value_type> &mt)
{
this->priv_reserve_map_at_back();
- *(this->m_finish.m_node + 1) = this->priv_allocate_node();
+ *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
BOOST_TRY {
- new(detail::get_pointer(this->m_finish.m_cur))value_type(mt);
- this->m_finish.priv_set_node(this->m_finish.m_node + 1);
- this->m_finish.m_cur = this->m_finish.m_first;
+ new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
+ this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
}
BOOST_CATCH(...){
- this->priv_deallocate_node(*(this->m_finish.m_node + 1));
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1275,33 +1246,33 @@
void priv_push_back_aux(value_type &&mt)
{
this->priv_reserve_map_at_back();
- *(this->m_finish.m_node + 1) = this->priv_allocate_node();
+ *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
BOOST_TRY {
- new(detail::get_pointer(this->m_finish.m_cur))value_type(move(mt));
- this->m_finish.priv_set_node(this->m_finish.m_node + 1);
- this->m_finish.m_cur = this->m_finish.m_first;
+ new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
+ this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
}
BOOST_CATCH(...){
- this->priv_deallocate_node(*(this->m_finish.m_node + 1));
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1));
BOOST_RETHROW
}
BOOST_CATCH_END
}
#endif
- // Called only if this->m_start.m_cur == this->m_start.m_first.
+ // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_first.
void priv_push_front_aux(const value_type& t)
{
this->priv_reserve_map_at_front();
- *(this->m_start.m_node - 1) = this->priv_allocate_node();
+ *(this->members_.m_start.m_node - 1) = this->priv_allocate_node();
BOOST_TRY {
- this->m_start.priv_set_node(this->m_start.m_node - 1);
- this->m_start.m_cur = this->m_start.m_last - 1;
- new(detail::get_pointer(this->m_start.m_cur))value_type(t);
+ this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
+ new(detail::get_pointer(this->members_.m_start.m_cur))value_type(t);
}
BOOST_CATCH(...){
- ++this->m_start;
- this->priv_deallocate_node(*(this->m_start.m_node - 1));
+ ++this->members_.m_start;
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - 1));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1311,15 +1282,15 @@
void priv_push_front_aux(const detail::moved_object<value_type> &mt)
{
this->priv_reserve_map_at_front();
- *(this->m_start.m_node - 1) = this->priv_allocate_node();
+ *(this->members_.m_start.m_node - 1) = this->priv_allocate_node();
BOOST_TRY {
- this->m_start.priv_set_node(this->m_start.m_node - 1);
- this->m_start.m_cur = this->m_start.m_last - 1;
- new(detail::get_pointer(this->m_start.m_cur))value_type(mt);
+ this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
+ new(detail::get_pointer(this->members_.m_start.m_cur))value_type(mt);
}
BOOST_CATCH(...){
- ++this->m_start;
- this->priv_deallocate_node(*(this->m_start.m_node - 1));
+ ++this->members_.m_start;
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - 1));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1328,56 +1299,56 @@
void priv_push_front_aux(value_type &&mt)
{
this->priv_reserve_map_at_front();
- *(this->m_start.m_node - 1) = this->priv_allocate_node();
+ *(this->members_.m_start.m_node - 1) = this->priv_allocate_node();
BOOST_TRY {
- this->m_start.priv_set_node(this->m_start.m_node - 1);
- this->m_start.m_cur = this->m_start.m_last - 1;
- new(detail::get_pointer(this->m_start.m_cur))value_type(move(mt));
+ this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
+ new(detail::get_pointer(this->members_.m_start.m_cur))value_type(move(mt));
}
BOOST_CATCH(...){
- ++this->m_start;
- this->priv_deallocate_node(*(this->m_start.m_node - 1));
+ ++this->members_.m_start;
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - 1));
BOOST_RETHROW
}
BOOST_CATCH_END
}
#endif
- // Called only if this->m_finish.m_cur == this->m_finish.m_first.
+ // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
void priv_pop_back_aux()
{
- this->priv_deallocate_node(this->m_finish.m_first);
- this->m_finish.priv_set_node(this->m_finish.m_node - 1);
- this->m_finish.m_cur = this->m_finish.m_last - 1;
- detail::get_pointer(this->m_finish.m_cur)->~value_type();
+ this->priv_deallocate_node(this->members_.m_finish.m_first);
+ this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
+ detail::get_pointer(this->members_.m_finish.m_cur)->~value_type();
}
- // Called only if this->m_start.m_cur == this->m_start.m_last - 1. Note that
+ // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
// if the deque has at least one element (a precondition for this member
- // function), and if this->m_start.m_cur == this->m_start.m_last, then the deque
+ // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
// must have at least two nodes.
void priv_pop_front_aux()
{
- detail::get_pointer(this->m_start.m_cur)->~value_type();
- this->priv_deallocate_node(this->m_start.m_first);
- this->m_start.priv_set_node(this->m_start.m_node + 1);
- this->m_start.m_cur = this->m_start.m_first;
+ detail::get_pointer(this->members_.m_start.m_cur)->~value_type();
+ this->priv_deallocate_node(this->members_.m_start.m_first);
+ this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
}
iterator priv_reserve_elements_at_front(size_type n)
{
- size_type vacancies = this->m_start.m_cur - this->m_start.m_first;
+ size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
if (n > vacancies)
this->priv_new_elements_at_front(n - vacancies);
- return this->m_start - difference_type(n);
+ return this->members_.m_start - difference_type(n);
}
iterator priv_reserve_elements_at_back(size_type n)
{
- size_type vacancies = (this->m_finish.m_last - this->m_finish.m_cur) - 1;
+ size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
if (n > vacancies)
this->priv_new_elements_at_back(n - vacancies);
- return this->m_finish + difference_type(n);
+ return this->members_.m_finish + difference_type(n);
}
void priv_new_elements_at_front(size_type new_elems)
@@ -1388,11 +1359,11 @@
size_type i;
BOOST_TRY {
for (i = 1; i <= new_nodes; ++i)
- *(this->m_start.m_node - i) = this->priv_allocate_node();
+ *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
}
BOOST_CATCH(...) {
for (size_type j = 1; j < i; ++j)
- this->priv_deallocate_node(*(this->m_start.m_node - j));
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
BOOST_RETHROW
}
BOOST_CATCH_END
@@ -1406,62 +1377,62 @@
size_type i;
BOOST_TRY {
for (i = 1; i <= new_nodes; ++i)
- *(this->m_finish.m_node + i) = this->priv_allocate_node();
+ *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
}
BOOST_CATCH(...) {
for (size_type j = 1; j < i; ++j)
- this->priv_deallocate_node(*(this->m_finish.m_node + j));
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
BOOST_RETHROW
}
BOOST_CATCH_END
}
- // Makes sure the this->m_map has space for new nodes. Does not actually
- // add the nodes. Can invalidate this->m_map pointers. (And consequently,
+ // Makes sure the this->members_.m_map has space for new nodes. Does not actually
+ // add the nodes. Can invalidate this->members_.m_map pointers. (And consequently,
// deque iterators.)
void priv_reserve_map_at_back (size_type nodes_to_add = 1)
{
- if (nodes_to_add + 1 > this->m_map_size - (this->m_finish.m_node - this->m_map))
+ if (nodes_to_add + 1 > this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map))
this->priv_reallocate_map(nodes_to_add, false);
}
void priv_reserve_map_at_front (size_type nodes_to_add = 1)
{
- if (nodes_to_add > size_type(this->m_start.m_node - this->m_map))
+ if (nodes_to_add > size_type(this->members_.m_start.m_node - this->members_.m_map))
this->priv_reallocate_map(nodes_to_add, true);
}
void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
{
- size_type old_num_nodes = this->m_finish.m_node - this->m_start.m_node + 1;
+ size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
size_type new_num_nodes = old_num_nodes + nodes_to_add;
index_pointer new_nstart;
- if (this->m_map_size > 2 * new_num_nodes) {
- new_nstart = this->m_map + (this->m_map_size - new_num_nodes) / 2
+ if (this->members_.m_map_size > 2 * new_num_nodes) {
+ new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
- if (new_nstart < this->m_start.m_node)
- std::copy(this->m_start.m_node, this->m_finish.m_node + 1, new_nstart);
+ if (new_nstart < this->members_.m_start.m_node)
+ std::copy(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
else
- std::copy_backward(this->m_start.m_node, this->m_finish.m_node + 1,
+ std::copy_backward(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1,
new_nstart + old_num_nodes);
}
else {
size_type new_map_size =
- this->m_map_size + max_value(this->m_map_size, nodes_to_add) + 2;
+ this->members_.m_map_size + max_value(this->members_.m_map_size, nodes_to_add) + 2;
index_pointer new_map = this->priv_allocate_map(new_map_size);
new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
- std::copy(this->m_start.m_node, this->m_finish.m_node + 1, new_nstart);
- this->priv_deallocate_map(this->m_map, this->m_map_size);
+ std::copy(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
- this->m_map = new_map;
- this->m_map_size = new_map_size;
+ this->members_.m_map = new_map;
+ this->members_.m_map_size = new_map_size;
}
- this->m_start.priv_set_node(new_nstart);
- this->m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
+ this->members_.m_start.priv_set_node(new_nstart);
+ this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
}
// this->priv_uninitialized_copy_fill
@@ -1471,9 +1442,9 @@
iterator first2, iterator last2,
const T& x)
{
- iterator mid2 = boost::interprocess::uninitialized_copy(first1, last1, first2);
+ iterator mid2 = std::uninitialized_copy(first1, last1, first2);
BOOST_TRY {
- boost::interprocess::uninitialized_fill(mid2, last2, x);
+ std::uninitialized_fill(mid2, last2, x);
}
BOOST_CATCH(...){
for(;first2 != mid2; ++first2){
@@ -1490,9 +1461,9 @@
const T& x,
iterator first, iterator last)
{
- boost::interprocess::uninitialized_fill(result, mid, x);
+ std::uninitialized_fill(result, mid, x);
BOOST_TRY {
- return boost::interprocess::uninitialized_copy(first, last, mid);
+ return std::uninitialized_copy(first, last, mid);
}
BOOST_CATCH(...){
for(;result != mid; ++result){
@@ -1512,9 +1483,9 @@
InpIt2 first2, InpIt2 last2,
FwdIt result)
{
- FwdIt mid = boost::interprocess::uninitialized_copy(first1, last1, result);
+ FwdIt mid = std::uninitialized_copy(first1, last1, result);
BOOST_TRY {
- return boost::interprocess::uninitialized_copy(first2, last2, mid);
+ return std::uninitialized_copy(first2, last2, mid);
}
BOOST_CATCH(...){
for(;result != mid; ++result){
Modified: trunk/boost/interprocess/containers/detail/flat_tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/flat_tree.hpp (original)
+++ trunk/boost/interprocess/containers/detail/flat_tree.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -348,8 +348,6 @@
typedef typename
std::iterator_traits<InIt>::iterator_category ItCat;
priv_insert_equal(first, last, ItCat());
-// for ( ; first != last; ++first)
-// this->insert_equal(*first);
}
iterator erase(const_iterator position)
@@ -360,9 +358,8 @@
std::pair<iterator,iterator > itp = this->equal_range(k);
size_type ret = static_cast<size_type>(itp.second-itp.first);
if (ret){
- this->erase(itp.first, itp.second);
+ this->m_data.m_vect.erase(itp.first, itp.second);
}
-
return ret;
}
Modified: trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp (original)
+++ trunk/boost/interprocess/containers/detail/node_alloc_holder.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -21,10 +21,11 @@
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/version_type.hpp>
#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/detail/algorithms.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/algorithms.hpp>
#include <boost/interprocess/detail/mpl.hpp>
+#include <boost/intrusive/options.hpp>
#include <utility>
#include <functional>
@@ -58,7 +59,6 @@
template<class A, class ICont>
struct node_alloc_holder
- : public A::template rebind<typename ICont::value_type>::other
{
typedef node_alloc_holder<A, ICont> self_t;
typedef typename A::value_type value_type;
@@ -76,91 +76,68 @@
version<NodeAlloc>::value> alloc_version;
node_alloc_holder(const ValAlloc &a)
- : NodeAlloc(a)
- {}
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- node_alloc_holder(const detail::moved_object<ValAlloc> &a)
- : NodeAlloc(a.get())
- {}
- #else
- node_alloc_holder(ValAlloc &&a)
- : NodeAlloc(a)
+ : members_(a)
{}
- #endif
node_alloc_holder(const node_alloc_holder &other)
- : NodeAlloc(other)
+ : members_(other.node_alloc())
{}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
node_alloc_holder(const detail::moved_object<node_alloc_holder> &other)
- : NodeAlloc(move((NodeAlloc&)other.get()))
+ : members_(move(other.get().node_alloc()))
{ this->swap(other.get()); }
#else
node_alloc_holder(node_alloc_holder &&other)
- : NodeAlloc(move((NodeAlloc&)other))
+ : members_(move(other.node_alloc()))
{ this->swap(other); }
#endif
template<class Pred>
node_alloc_holder(const ValAlloc &a, const Pred &c)
- : NodeAlloc(a), m_icont(typename ICont::value_compare(c))
+ : members_(a, typename ICont::value_compare(c))
{}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
template<class Pred>
node_alloc_holder(const detail::moved_object<ValAlloc> &a, const Pred &c)
- : NodeAlloc(a.get()), m_icont(typename ICont::value_compare(c))
+ : members_(a.get(), typename ICont::value_compare(c))
{}
#else
template<class Pred>
node_alloc_holder(ValAlloc &&a, const Pred &c)
- : NodeAlloc(a), m_icont(typename ICont::value_compare(c))
+ : members_(a, typename ICont::value_compare(c))
{}
#endif
template<class Pred>
node_alloc_holder(const node_alloc_holder &other, const Pred &c)
- : NodeAlloc(other), m_icont(typename ICont::value_compare(c))
+ : members_(other.node_alloc(), typename ICont::value_compare(c))
{}
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Pred>
- node_alloc_holder
- (const detail::moved_object<node_alloc_holder> &other, const Pred &c)
- : NodeAlloc(move((NodeAlloc&)other.get())), m_icont(typename ICont::value_compare(c))
- { this->swap(other.get()); }
- #else
- template<class Pred>
- node_alloc_holder(node_alloc_holder &&other, const Pred &c)
- : NodeAlloc(move((NodeAlloc&)other)), m_icont(typename ICont::value_compare(c))
- { this->swap(other); }
- #endif
-
~node_alloc_holder()
{}
size_type max_size() const
- { return NodeAlloc::max_size(); }
+ { return this->node_alloc().max_size(); }
NodePtr allocate_one()
{ return this->allocate_one(alloc_version()); }
NodePtr allocate_one(allocator_v1)
- { return NodeAlloc::allocate(1); }
+ { return this->node_alloc().allocate(1); }
NodePtr allocate_one(allocator_v2)
- { return NodeAlloc::allocate_one(); }
+ { 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)
- { NodeAlloc::deallocate(p, 1); }
+ { this->node_alloc().deallocate(p, 1); }
void deallocate_one(NodePtr p, allocator_v2)
- { NodeAlloc::deallocate_one(p); }
+ { this->node_alloc().deallocate_one(p); }
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
template<class Convertible>
@@ -187,7 +164,7 @@
//Hook constructor does not throw
new(static_cast<hook_type*>(nodeptr))hook_type();
- //Now construct pair members
+ //Now construct pair members_holder
value_type *valueptr = &nodeptr->m_data;
new((void*)&valueptr->first) first_type(move(value.get().first));
BOOST_TRY{
@@ -212,7 +189,7 @@
//Hook constructor does not throw
new(static_cast<hook_type*>(nodeptr))hook_type();
- //Now construct pair members
+ //Now construct pair members_holder
value_type *valueptr = &nodeptr->m_data;
new((void*)&valueptr->first) first_type(move(value.first));
BOOST_TRY{
@@ -235,7 +212,7 @@
NodePtr create_node(const Convertible& x)
{
NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, *this);
+ Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p, x);
node_deallocator.release();
return (p);
@@ -245,7 +222,7 @@
NodePtr create_node(Convertible &&x)
{
NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, *this);
+ Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p, forward<Convertible>(x));
node_deallocator.release();
return (p);
@@ -256,8 +233,8 @@
NodePtr create_node_from_it(It it)
{
NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, *this);
- construct_in_place(detail::get_pointer(p), it);
+ Deallocator node_deallocator(p, this->node_alloc());
+ ::boost::interprocess::construct_in_place(detail::get_pointer(p), it);
node_deallocator.release();
return (p);
}
@@ -265,7 +242,7 @@
NodePtr create_node()
{
NodePtr p = this->allocate_one();
- Deallocator node_deallocator(p, *this);
+ Deallocator node_deallocator(p, this->node_alloc());
self_t::construct(p);
node_deallocator.release();
return (p);
@@ -279,36 +256,52 @@
void swap(node_alloc_holder &x)
{
- NodeAlloc& this_alloc = static_cast<NodeAlloc&>(*this);
- NodeAlloc& other_alloc = static_cast<NodeAlloc&>(x);
+ NodeAlloc& this_alloc = this->node_alloc();
+ NodeAlloc& other_alloc = x.node_alloc();
if (this_alloc != other_alloc){
detail::do_swap(this_alloc, other_alloc);
}
- this->m_icont.swap(x.m_icont);
+ this->icont().swap(x.icont());
}
- template<class FwdIterator, class MultiAllocator>
+ template<class FwdIterator, class Inserter>
FwdIterator allocate_many_and_construct
- (FwdIterator beg, difference_type n, MultiAllocator &multi_beg, size_type &constructed)
+ (FwdIterator beg, difference_type n, Inserter inserter)
{
typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
//Try to allocate memory in a single chunk
- MultiAllocator itbeg = NodeAlloc::allocate_individual(1, n, constructed), itend, it;
-
- //Prepare exception-safety machinery
- detail::multiallocation_deallocator<NodeAlloc> multi_deallocator(itbeg, *this);
-
- //Initialize all the data (this can throw)
- FwdIterator next =
- boost::interprocess::n_uninitialized_copy_n(beg, constructed, itbeg);
-
- //Exception-unsafe zone passed. Disable auto-deallocation
- multi_deallocator.release();
- multi_beg = itbeg;
- return next;
+ multiallocation_iterator itbeg =
+ this->node_alloc().allocate_individual(n), itend, itold;
+ int constructed = 0;
+ Node *p;
+ BOOST_TRY{
+ for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
+ p = &*itbeg;
+ ++itbeg;
+ //This can throw
+ boost::interprocess::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->deallocate_one(p);
+ multiallocation_iterator itend;
+ while(itbeg != itend){
+ Node *n = &*itbeg;
+ ++itbeg;
+ this->deallocate_one(n);
+ }
+ }
+ BOOST_CATCH_END
+ return beg;
}
protected:
@@ -336,11 +329,40 @@
node_alloc_holder &m_holder;
};
- //The intrusive container
- ICont m_icont;
+ 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)
+ {}
+ //The intrusive container
+ ICont m_icont;
+ } members_;
ICont &non_const_icont() const
- { return const_cast<ICont&>(this->m_icont); }
+ { 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 this->members_; }
+
+ const NodeAlloc &node_alloc() const
+ { return this->members_; }
};
} //namespace detail {
Modified: trunk/boost/interprocess/containers/detail/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/detail/tree.hpp (original)
+++ trunk/boost/interprocess/containers/detail/tree.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -86,15 +86,11 @@
template <class T, class VoidPointer>
struct rbtree_node
- : public boost::intrusive::set_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , VoidPointer>
-{
- typedef boost::intrusive::set_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , VoidPointer> hook_type;
+ : public bi::make_set_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type
+{
+ typedef typename bi::make_set_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type hook_type;
typedef T value_type;
@@ -129,16 +125,11 @@
public:
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+
template<class Convertible>
static void construct(node_type *ptr, const Convertible &value)
{ new(ptr) node_type(value); }
- #else
- template<class Convertible>
- static void construct(node_type *ptr, Convertible &&value)
- { new(ptr) node_type(forward<Convertible>(value)); }
- #endif
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
template<class Convertible1, class Convertible2>
static void construct(node_type *ptr,
const detail::moved_object<std::pair<Convertible1, Convertible2> > &value)
@@ -151,7 +142,13 @@
new((void*)ptr) hack_node_t(value);
}
+
#else
+
+ template<class Convertible>
+ static void construct(node_type *ptr, Convertible &&value)
+ { new(ptr) node_type(forward<Convertible>(value)); }
+
template<class Convertible1, class Convertible2>
static void construct(node_type *ptr,
std::pair<Convertible1, Convertible2> &&value)
@@ -164,6 +161,7 @@
new((void*)ptr) hack_node_t(value);
}
+
#endif
};
@@ -187,14 +185,13 @@
typedef typename detail::rbtree_node
<value_type, void_pointer> node_type;
typedef node_compare<ValueCompare, node_type> node_compare_type;
-
- typedef typename boost::intrusive::rbtree
- <typename node_type::hook_type::
- template value_traits<node_type>
- ,node_compare_type
- ,boost::intrusive::safe_link
- ,typename A::size_type> container_type;
-
+ typedef typename bi::make_rbtree
+ <node_type
+ ,bi::compare<node_compare_type>
+ ,bi::base_hook<typename node_type::hook_type>
+ ,bi::constant_time_size<true>
+ ,bi::size_type<typename A::size_type>
+ >::type container_type;
typedef container_type type ;
};
@@ -241,9 +238,10 @@
NodePtr operator()(const Node &other) const
{
- if(!m_icont.empty()){
+// if(!m_icont.empty()){
+ if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
//First recycle a node (this can't throw)
- NodePtr p = m_icont.unlink_leftmost_without_rebalance();
+ //NodePtr p = m_icont.unlink_leftmost_without_rebalance();
try{
//This can throw
*p = other;
@@ -421,8 +419,8 @@
rbtree(const rbtree& x)
: AllocHolder(x, x.key_comp())
{
- this->m_icont.clone_from
- (x.m_icont, typename AllocHolder::cloner(*this), Destroyer(*this));
+ this->icont().clone_from
+ (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -444,12 +442,15 @@
//Transfer all the nodes to a temporary tree
//If anything goes wrong, all the nodes will be destroyed
//automatically
- Icont other_tree(this->m_icont.value_comp());
- other_tree.swap(this->m_icont);
+ Icont other_tree(this->icont().value_comp());
+ other_tree.swap(this->icont());
//Now recreate the source tree reusing nodes stored by other_tree
- this->m_icont.clone_from
- (x.m_icont, RecyclingCloner(*this, other_tree), Destroyer(*this));
+ this->icont().clone_from
+ (x.icont()
+ , RecyclingCloner(*this, other_tree)
+ //, AllocHolder::cloner(*this)
+ , Destroyer(this->node_alloc()));
//If there are remaining nodes, destroy them
NodePtr p;
@@ -471,28 +472,28 @@
public:
// accessors:
value_compare value_comp() const
- { return this->m_icont.value_comp().value_comp(); }
+ { return this->icont().value_comp().value_comp(); }
key_compare key_comp() const
- { return this->m_icont.value_comp().value_comp().key_comp(); }
+ { return this->icont().value_comp().value_comp().key_comp(); }
allocator_type get_allocator() const
- { return allocator_type(*this); }
+ { return allocator_type(this->node_alloc()); }
const stored_allocator_type &get_stored_allocator() const
- { return static_cast<const stored_allocator_type &>(*this); }
+ { return this->node_alloc(); }
stored_allocator_type &get_stored_allocator()
- { return static_cast<stored_allocator_type&>(*this); }
+ { return this->node_alloc(); }
iterator begin()
- { return iterator(this->m_icont.begin()); }
+ { return iterator(this->icont().begin()); }
const_iterator begin() const
{ return const_iterator(this->non_const_icont().begin()); }
iterator end()
- { return iterator(this->m_icont.end()); }
+ { return iterator(this->icont().end()); }
const_iterator end() const
{ return const_iterator(this->non_const_icont().end()); }
@@ -513,7 +514,7 @@
{ return !this->size(); }
size_type size() const
- { return this->m_icont.size(); }
+ { return this->icont().size(); }
size_type max_size() const
{ return AllocHolder::max_size(); }
@@ -538,7 +539,7 @@
(const key_type& key, insert_commit_data &data)
{
std::pair<iiterator, bool> ret =
- this->m_icont.insert_unique_check(key, KeyNodeCompare(value_comp()), data);
+ this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
}
@@ -546,14 +547,14 @@
(const_iterator hint, const key_type& key, insert_commit_data &data)
{
std::pair<iiterator, bool> ret =
- this->m_icont.insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
+ this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
}
iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(v);
- iiterator it(this->m_icont.insert_unique_commit(*tmp, data));
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
}
@@ -563,7 +564,7 @@
(const detail::moved_object<MovableConvertible>& mv, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(mv);
- iiterator it(this->m_icont.insert_unique_commit(*tmp, data));
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
}
#else
@@ -572,7 +573,7 @@
(MovableConvertible && mv, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(forward<MovableConvertible>(mv));
- iiterator it(this->m_icont.insert_unique_commit(*tmp, data));
+ iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
}
#endif
@@ -670,7 +671,7 @@
iterator insert_equal(const value_type& v)
{
NodePtr p(AllocHolder::create_node(v));
- return iterator(this->m_icont.insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal_upper_bound(*p));
}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -678,21 +679,21 @@
iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
{
NodePtr p(AllocHolder::create_node(mv));
- return iterator(this->m_icont.insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal_upper_bound(*p));
}
#else
template<class MovableConvertible>
iterator insert_equal(MovableConvertible &&mv)
{
NodePtr p(AllocHolder::create_node(forward<MovableConvertible>(mv)));
- return iterator(this->m_icont.insert_equal_upper_bound(*p));
+ return iterator(this->icont().insert_equal_upper_bound(*p));
}
#endif
iterator insert_equal(const_iterator hint, const value_type& v)
{
NodePtr p(AllocHolder::create_node(v));
- return iterator(this->m_icont.insert_equal(hint.get(), *p));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
}
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
@@ -700,14 +701,14 @@
iterator insert_equal(const_iterator hint, const detail::moved_object<MovableConvertible> &mv)
{
NodePtr p(AllocHolder::create_node(mv));
- return iterator(this->m_icont.insert_equal(hint.get(), *p));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
}
#else
template<class MovableConvertible>
iterator insert_equal(const_iterator hint, MovableConvertible &&mv)
{
NodePtr p(AllocHolder::create_node(move(mv)));
- return iterator(this->m_icont.insert_equal(hint.get(), *p));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
}
#endif
@@ -728,35 +729,35 @@
}
iterator erase(const_iterator position)
- { return iterator(this->m_icont.erase_and_dispose(position.get(), Destroyer(*this))); }
+ { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
size_type erase(const key_type& k)
- { return this->m_icont.erase_and_dispose(k, KeyNodeCompare(value_comp()), Destroyer(*this)); }
+ { return this->icont().erase_and_dispose(k, KeyNodeCompare(value_comp()), Destroyer(this->node_alloc())); }
iterator erase(const_iterator first, const_iterator last)
- { return iterator(this->m_icont.erase_and_dispose(first.get(), last.get(), Destroyer(*this))); }
+ { return iterator(this->icont().erase_and_dispose(first.get(), last.get(), Destroyer(this->node_alloc()))); }
void clear()
- { this->m_icont.clear_and_dispose(Destroyer(*this)); }
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
// set operations:
iterator find(const key_type& k)
- { return iterator(this->m_icont.find(k, KeyNodeCompare(value_comp()))); }
+ { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
const_iterator find(const key_type& k) const
{ return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
size_type count(const key_type& k) const
- { return size_type(this->m_icont.count(k, KeyNodeCompare(value_comp()))); }
+ { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
iterator lower_bound(const key_type& k)
- { return iterator(this->m_icont.lower_bound(k, KeyNodeCompare(value_comp()))); }
+ { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
const_iterator lower_bound(const key_type& k) const
{ return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
iterator upper_bound(const key_type& k)
- { return iterator(this->m_icont.upper_bound(k, KeyNodeCompare(value_comp()))); }
+ { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
const_iterator upper_bound(const key_type& k) const
{ return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
@@ -764,7 +765,7 @@
std::pair<iterator,iterator> equal_range(const key_type& k)
{
std::pair<iiterator, iiterator> ret =
- this->m_icont.equal_range(k, KeyNodeCompare(value_comp()));
+ this->icont().equal_range(k, KeyNodeCompare(value_comp()));
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
}
@@ -809,6 +810,24 @@
priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
}
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
+ {
+ Icont &icont_;
+ typename Icont::iterator pos_;
+
+ public:
+ insertion_functor(Icont &icont)
+ : icont_(icont)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.insert_equal_upper_bound(n); }
+ };
+
+
template<class FwdIterator>
void priv_create_and_insert_nodes
(FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
@@ -817,31 +836,9 @@
priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
}
else{
- //Optimize memory allocation obtaining the distance between iterators
- size_type n = std::distance(beg, end);
-
- //Allocate and construct as many nodes as possible with
- //the one-shot allocation
- typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
- multiallocation_iterator many_beg, itend, it;
- size_type received_array;
- FwdIterator next = this->allocate_many_and_construct
- (beg, n, many_beg, received_array);
-
- detail::multiallocation_destroy_dealloc<NodeAlloc>
- multi_destroy_dealloc(many_beg, *this);
-
- //Insert constructed nodes (this does not throw)
- for (it = many_beg; it != itend; ++it){
- this->m_icont.insert_equal_upper_bound(*it);
- multi_destroy_dealloc.next();
- }
-
- //Insert remaining nodes using individual allocation
- //(this can throw, but there is no leak)
- for (size_type i = received_array; i < n; ++i, ++next){
- this->insert_equal(*next);
- }
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont()));
}
}
};
Modified: trunk/boost/interprocess/containers/flat_set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/flat_set.hpp (original)
+++ trunk/boost/interprocess/containers/flat_set.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTERPROCESS_SHMEM_FLAT_SET_HPP
-#define BOOST_INTERPROCESS_SHMEM_FLAT_SET_HPP
+#ifndef BOOST_INTERPROCESS_FLAT_SET_HPP
+#define BOOST_INTERPROCESS_FLAT_SET_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -556,7 +556,8 @@
#endif
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class T, class P, class A>
struct is_movable<flat_set<T, P, A> >
{
@@ -1055,7 +1056,8 @@
#endif
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class T, class P, class A>
struct is_movable<flat_multiset<T, P, A> >
{
@@ -1077,4 +1079,4 @@
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_SHMEM_FLAT_SET_HPP */
+#endif /* BOOST_INTERPROCESS_FLAT_SET_HPP */
Modified: trunk/boost/interprocess/containers/list.hpp
==============================================================================
--- trunk/boost/interprocess/containers/list.hpp (original)
+++ trunk/boost/interprocess/containers/list.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -75,15 +75,11 @@
template <class T, class VoidPointer>
struct list_node
- : public boost::intrusive::list_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , VoidPointer>
+ : public bi::make_list_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type
{
- typedef boost::intrusive::list_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , VoidPointer> hook_type;
+ typedef typename bi::make_list_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type hook_type;
list_node()
: m_data()
@@ -112,12 +108,12 @@
<typename A::pointer, void>::type void_pointer;
typedef typename detail::list_node
<value_type, void_pointer> node_type;
-
- typedef typename boost::intrusive::list
- <typename node_type::hook_type::
- template value_traits<node_type>
- ,true
- ,typename A::size_type> container_type;
+ typedef typename bi::make_list
+ < node_type
+ , bi::base_hook<typename node_type::hook_type>
+ , bi::constant_time_size<true>
+ , bi::size_type<typename A::size_type>
+ >::type container_type;
typedef container_type type ;
};
@@ -390,13 +386,13 @@
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const
- { return allocator_type(*this); }
+ { return allocator_type(this->node_alloc()); }
const stored_allocator_type &get_stored_allocator() const
- { return *this; }
+ { return this->node_alloc(); }
stored_allocator_type &get_stored_allocator()
- { return *this; }
+ { return this->node_alloc(); }
//! <b>Effects</b>: Erases all the elements of the list.
//!
@@ -404,7 +400,7 @@
//!
//! <b>Complexity</b>: Linear to the number of elements in the list.
void clear()
- { this->m_icont.clear_and_dispose(Destroyer(*this)); }
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
//!
@@ -412,7 +408,7 @@
//!
//! <b>Complexity</b>: Constant.
iterator begin()
- { return iterator(this->m_icont.begin()); }
+ { return iterator(this->icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
@@ -428,7 +424,7 @@
//!
//! <b>Complexity</b>: Constant.
iterator end()
- { return iterator(this->m_icont.end()); }
+ { return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
//!
@@ -488,7 +484,7 @@
//!
//! <b>Complexity</b>: Constant.
size_type size() const
- { return this->m_icont.size(); }
+ { return this->icont().size(); }
//! <b>Effects</b>: Returns the largest possible size of the list.
//!
@@ -744,7 +740,7 @@
iterator insert(iterator p, const T& x)
{
NodePtr tmp = AllocHolder::create_node(x);
- return iterator(this->m_icont.insert(p.get(), *tmp));
+ return iterator(this->icont().insert(p.get(), *tmp));
}
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -758,13 +754,13 @@
iterator insert(iterator p, const detail::moved_object<T>& x)
{
NodePtr tmp = AllocHolder::create_node(x);
- return iterator(this->m_icont.insert(p.get(), *tmp));
+ return iterator(this->icont().insert(p.get(), *tmp));
}
#else
iterator insert(iterator p, T &&x)
{
NodePtr tmp = AllocHolder::create_node(move(x));
- return iterator(this->m_icont.insert(p.get(), *tmp));
+ return iterator(this->icont().insert(p.get(), *tmp));
}
#endif
@@ -776,7 +772,7 @@
//!
//! <b>Complexity</b>: Amortized constant time.
iterator erase(iterator p)
- { return iterator(this->m_icont.erase_and_dispose(p.get(), Destroyer(*this))); }
+ { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
//! <b>Requires</b>: first and last must be valid iterator to elements in *this.
//!
@@ -786,7 +782,7 @@
//!
//! <b>Complexity</b>: Linear to the distance between first and last.
iterator erase(iterator first, iterator last)
- { return iterator(this->m_icont.erase_and_dispose(first.get(), last.get(), Destroyer(*this))); }
+ { return iterator(this->icont().erase_and_dispose(first.get(), last.get(), Destroyer(this->node_alloc()))); }
//! <b>Effects</b>: Assigns the n copies of val to *this.
//!
@@ -826,7 +822,7 @@
void splice(iterator p, ThisType& x)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice(p.get(), x.m_icont);
+ this->icont().splice(p.get(), x.icont());
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
@@ -853,7 +849,7 @@
void splice(iterator p, ThisType &x, iterator i)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice(p.get(), x.m_icont, i.get());
+ this->icont().splice(p.get(), x.icont(), i.get());
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
@@ -879,7 +875,7 @@
void splice(iterator p, ThisType &x, iterator first, iterator last)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice(p.get(), x.m_icont, first.get(), last.get());
+ this->icont().splice(p.get(), x.icont(), first.get(), last.get());
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
@@ -906,7 +902,7 @@
void splice(iterator p, ThisType &x, iterator first, iterator last, size_type n)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice(p.get(), x.m_icont, first.get(), last.get(), n);
+ this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
}
else{
throw std::runtime_error("list::splice called with unequal allocators");
@@ -924,7 +920,7 @@
//!
//! <b>Note</b>: Iterators and references are not invalidated
void reverse()
- { this->m_icont.reverse(); }
+ { this->icont().reverse(); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
//!
@@ -950,7 +946,7 @@
void remove_if(Pred pred)
{
typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->m_icont.remove_and_dispose_if(Predicate(pred), Destroyer(*this));
+ this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
}
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -978,7 +974,7 @@
void unique(BinaryPredicate binary_pred)
{
typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
- this->m_icont.unique_and_dispose(Predicate(binary_pred), Destroyer(*this));
+ this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
}
//! <b>Requires</b>: The lists x and *this must be distinct.
@@ -1027,7 +1023,7 @@
void merge(list<T, A>& x, StrictWeakOrdering comp)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.merge(x.m_icont,
+ this->icont().merge(x.icont(),
ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
else{
@@ -1080,7 +1076,7 @@
// nothing if the list has length 0 or 1.
if (this->size() < 2)
return;
- this->m_icont.sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
/// @cond
@@ -1099,7 +1095,7 @@
(const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
{
for (; beg != end; ++beg){
- this->m_icont.insert(pos.get(), *this->create_node_from_it(beg));
+ this->icont().insert(pos.get(), *this->create_node_from_it(beg));
}
}
@@ -1110,36 +1106,31 @@
priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag());
}
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
{
- //Optimize memory allocation obtaining the distance between iterators
- size_type n = std::distance(beg, end);
+ Icont &icont_;
+ typename Icont::iterator pos_;
- //Allocate and construct as many nodes as possible with
- //the one-shot allocation
- typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
- multiallocation_iterator many_beg, itend, it;
- size_type received_array;
- FwdIterator next = this->allocate_many_and_construct
- (beg, n, many_beg, received_array);
-
- //Insert constructed nodes (this does not throw)
- for (it = many_beg; it != itend; ++it){
- this->m_icont.insert(pos.get(), *it);
- }
+ public:
+ insertion_functor(Icont &icont, typename Icont::iterator pos)
+ : icont_(icont), pos_(pos)
+ {}
- //Insert remaining nodes using individual allocation
- //(this can throw, but there is no leak)
- for (size_type i = received_array; i < n; ++i, ++next){
- this->m_icont.insert(pos.get(), *this->create_node_from_it(next));
- }
+ void operator()(Node &n)
+ { this->icont_.insert(pos_, n); }
+ };
- //good old version
- //for (; beg != end; ++beg){
- // this->m_icont.insert(pos.get(), *this->create_node(*beg));
- //}
+
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
}
//Default constructed version
Modified: trunk/boost/interprocess/containers/map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/map.hpp (original)
+++ trunk/boost/interprocess/containers/map.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -40,8 +40,8 @@
*
*/
-#ifndef BOOST_INTERPROCESS_SHMEM_MAP_HPP
-#define BOOST_INTERPROCESS_SHMEM_MAP_HPP
+#ifndef BOOST_INTERPROCESS_MAP_HPP
+#define BOOST_INTERPROCESS_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -687,10 +687,9 @@
#endif
-
-
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class T, class P, class A>
struct is_movable<map<T, P, A> >
{
@@ -1238,5 +1237,5 @@
#include <boost/interprocess/detail/config_end.hpp>
-#endif /* BOOST_INTERPROCESS_SHMEM_MAP_HPP */
+#endif /* BOOST_INTERPROCESS_MAP_HPP */
Modified: trunk/boost/interprocess/containers/set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/set.hpp (original)
+++ trunk/boost/interprocess/containers/set.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -532,7 +532,8 @@
#endif
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class T, class P, class A>
struct is_movable<set<T, P, A> >
{
@@ -1015,7 +1016,8 @@
#endif
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class T, class P, class A>
struct is_movable<multiset<T, P, A> >
{
Modified: trunk/boost/interprocess/containers/slist.hpp
==============================================================================
--- trunk/boost/interprocess/containers/slist.hpp (original)
+++ trunk/boost/interprocess/containers/slist.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -71,15 +71,11 @@
/// @cond
template <class T, class VoidPointer>
struct slist_node
- : public boost::intrusive::slist_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , VoidPointer>
+ : public bi::make_slist_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type
{
- typedef boost::intrusive::slist_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , VoidPointer> hook_type;
+ typedef typename bi::make_slist_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type hook_type;
slist_node()
: m_data()
@@ -106,11 +102,12 @@
typedef typename detail::slist_node
<value_type, void_pointer> node_type;
- typedef typename boost::intrusive::slist
- <typename node_type::hook_type::
- template value_traits<node_type>
- ,true
- ,typename A::size_type> container_type;
+ typedef typename bi::make_slist
+ <node_type
+ ,bi::base_hook<typename node_type::hook_type>
+ ,bi::constant_time_size<true>
+ ,bi::size_type<typename A::size_type>
+ >::type container_type;
typedef container_type type ;
};
@@ -355,7 +352,7 @@
//!
//! <b>Complexity</b>: Linear to the elements x contains.
slist(const slist& x)
- : AllocHolder(static_cast<const NodeAlloc&>(x))
+ : AllocHolder(x)
{ this->insert_after(this->before_begin(), x.begin(), x.end()); }
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
@@ -432,13 +429,13 @@
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const
- { return allocator_type(*this); }
+ { return allocator_type(this->node_alloc()); }
const stored_allocator_type &get_stored_allocator() const
- { return *this; }
+ { return this->node_alloc(); }
stored_allocator_type &get_stored_allocator()
- { return *this; }
+ { return this->node_alloc(); }
public:
@@ -470,7 +467,7 @@
//!
//! <b>Complexity</b>: Constant.
iterator begin()
- { return iterator(this->m_icont.begin()); }
+ { return iterator(this->icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
@@ -486,7 +483,7 @@
//!
//! <b>Complexity</b>: Constant.
iterator end()
- { return iterator(this->m_icont.end()); }
+ { return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
//!
@@ -522,7 +519,7 @@
//!
//! <b>Complexity</b>: Constant.
size_type size() const
- { return this->m_icont.size(); }
+ { return this->icont().size(); }
//! <b>Effects</b>: Returns the largest possible size of the list.
//!
@@ -579,7 +576,7 @@
//!
//! <b>Complexity</b>: Amortized constant time.
void push_front(const value_type& x)
- { this->m_icont.push_front(*this->create_node(x)); }
+ { this->icont().push_front(*this->create_node(x)); }
//! <b>Effects</b>: Constructs a new element in the beginning of the list
//! and moves the resources of t to this new element.
@@ -589,10 +586,10 @@
//! <b>Complexity</b>: Amortized constant time.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void push_front(const detail::moved_object<T>& x)
- { this->m_icont.push_front(*this->create_node(x)); }
+ { this->icont().push_front(*this->create_node(x)); }
#else
void push_front(T && x)
- { this->m_icont.push_front(*this->create_node(move(x))); }
+ { this->icont().push_front(*this->create_node(move(x))); }
#endif
//! <b>Effects</b>: Removes the first element from the list.
@@ -601,7 +598,7 @@
//!
//! <b>Complexity</b>: Amortized constant time.
void pop_front()
- { this->m_icont.pop_front_and_dispose(Destroyer(*this)); }
+ { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
//! <b>Returns</b>: The iterator to the element before i in the sequence.
//! Returns the end-iterator, if either i is the begin-iterator or the
@@ -611,7 +608,7 @@
//!
//! <b>Complexity</b>: Linear to the number of elements before i.
iterator previous(iterator p)
- { return iterator(this->m_icont.previous(p.get())); }
+ { return iterator(this->icont().previous(p.get())); }
//! <b>Returns</b>: The const_iterator to the element before i in the sequence.
//! Returns the end-const_iterator, if either i is the begin-const_iterator or
@@ -621,7 +618,7 @@
//!
//! <b>Complexity</b>: Linear to the number of elements before i.
const_iterator previous(const_iterator p)
- { return const_iterator(this->m_icont.previous(p.get())); }
+ { return const_iterator(this->icont().previous(p.get())); }
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
@@ -637,7 +634,7 @@
//! <b>Note</b>: Does not affect the validity of iterators and references of
//! previous values.
iterator insert_after(iterator prev_pos, const value_type& x)
- { return iterator(this->m_icont.insert_after(prev_pos.get(), *this->create_node(x))); }
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
//!
@@ -654,10 +651,10 @@
//! previous values.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
iterator insert_after(iterator prev_pos, const detail::moved_object<value_type>& x)
- { return iterator(this->m_icont.insert_after(prev_pos.get(), *this->create_node(x))); }
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
#else
iterator insert_after(iterator prev_pos, value_type && x)
- { return iterator(this->m_icont.insert_after(prev_pos.get(), *this->create_node(move(x)))); }
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(move(x)))); }
#endif
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
@@ -754,7 +751,7 @@
//! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
iterator erase_after(iterator prev_pos)
{
- return iterator(this->m_icont.erase_after_and_dispose(prev_pos.get(), Destroyer(*this)));
+ return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
}
//! <b>Effects</b>: Erases the range (before_first, last) from
@@ -770,7 +767,7 @@
//! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
iterator erase_after(iterator before_first, iterator last)
{
- return iterator(this->m_icont.erase_after_and_dispose(before_first.get(), last.get(), Destroyer(*this)));
+ return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
}
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -802,7 +799,7 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size, const T& x)
{
- typename Icont::iterator end_n(this->m_icont.end()), cur(end_n), cur_next;
+ typename Icont::iterator end_n(this->icont().end()), cur(end_n), cur_next;
while (++(cur_next = cur) != end_n && new_size > 0){
--new_size;
cur = cur_next;
@@ -821,7 +818,7 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size)
{
- typename Icont::iterator end_n(this->m_icont.end()), cur(end_n), cur_next;
+ typename Icont::iterator end_n(this->icont().end()), cur(end_n), cur_next;
size_type len = this->size();
size_type left = new_size;
@@ -843,7 +840,7 @@
//!
//! <b>Complexity</b>: Linear to the number of elements in the list.
void clear()
- { this->m_icont.clear_and_dispose(Destroyer(*this)); }
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
//! <b>Requires</b>: p must point to an element contained
//! by the list. x != *this
@@ -861,7 +858,7 @@
void splice_after(iterator prev_pos, slist& x)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice_after(prev_pos.get(), x.m_icont);
+ this->icont().splice_after(prev_pos.get(), x.icont());
}
else{
throw std::runtime_error("slist::splice called with unequal allocators");
@@ -891,7 +888,7 @@
void splice_after(iterator prev_pos, slist& x, iterator prev)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice_after(prev_pos.get(), x.m_icont, prev.get());
+ this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
}
else{
throw std::runtime_error("slist::splice called with unequal allocators");
@@ -923,8 +920,8 @@
iterator before_first, iterator before_last)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice_after
- (prev_pos.get(), x.m_icont, before_first.get(), before_last.get());
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
}
else{
throw std::runtime_error("slist::splice called with unequal allocators");
@@ -955,8 +952,8 @@
size_type n)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.splice_after
- (prev_pos.get(), x.m_icont, before_first.get(), before_last.get(), n);
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
}
else{
throw std::runtime_error("slist::splice called with unequal allocators");
@@ -1034,7 +1031,7 @@
//!
//! <b>Note</b>: Iterators and references are not invalidated
void reverse()
- { this->m_icont.reverse(); }
+ { this->icont().reverse(); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
//!
@@ -1060,7 +1057,7 @@
void remove_if(Pred pred)
{
typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->m_icont.remove_and_dispose_if(Predicate(pred), Destroyer(*this));
+ this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
}
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1088,7 +1085,7 @@
void unique(Pred pred)
{
typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->m_icont.unique_and_dispose(Predicate(pred), Destroyer(*this));
+ this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
}
//! <b>Requires</b>: The lists x and *this must be distinct.
@@ -1126,7 +1123,7 @@
void merge(slist& x, StrictWeakOrdering comp)
{
if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->m_icont.merge(x.m_icont,
+ this->icont().merge(x.icont(),
ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
else{
@@ -1165,11 +1162,12 @@
// nothing if the slist has length 0 or 1.
if (this->size() < 2)
return;
- this->m_icont.sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
/// @cond
private:
+
//Iterator range version
template<class InpIterator>
void priv_create_and_insert_nodes
@@ -1184,7 +1182,7 @@
(const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
{
for (; beg != end; ++beg){
- this->m_icont.insert_after(prev.get(), *this->create_node_from_it(beg));
+ this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
++prev;
}
}
@@ -1196,39 +1194,30 @@
priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
}
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ class insertion_functor;
+ friend class insertion_functor;
+
+ class insertion_functor
{
- //Optimize memory allocation obtaining the distance between iterators
- size_type n = std::distance(beg, end);
+ Icont &icont_;
+ typename Icont::iterator prev_;
- //Allocate and construct as many nodes as possible with
- //the one-shot allocation
- typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
- multiallocation_iterator many_beg, itend, it;
- size_type received_array;
- FwdIterator next = this->allocate_many_and_construct
- (beg, n, many_beg, received_array);
-
- //Insert constructed nodes (this does not throw)
- for (it = many_beg; it != itend; ++it){
- this->m_icont.insert_after(prev.get(), *it);
- ++prev;
- }
+ public:
+ insertion_functor(Icont &icont, typename Icont::iterator prev)
+ : icont_(icont), prev_(prev)
+ {}
- //Insert remaining nodes using individual allocation
- //(this can throw, but there is no leak)
- for (size_type i = received_array; i < n; ++i, ++next){
- this->m_icont.insert_after(prev.get(), *this->create_node_from_it(next));
- ++prev;
- }
+ void operator()(Node &n)
+ { prev_ = this->icont_.insert_after(prev_, n); }
+ };
- //good old version
- //for (; beg != end; ++beg){
- // this->m_icont.insert_after(prev.get(), *this->create_node(*beg));
- // ++prev;
- //}
+ template<class FwdIterator>
+ void priv_create_and_insert_nodes
+ (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
}
//Default constructed version
Modified: trunk/boost/interprocess/containers/string.hpp
==============================================================================
--- trunk/boost/interprocess/containers/string.hpp (original)
+++ trunk/boost/interprocess/containers/string.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -75,7 +75,6 @@
// allocator and whose size is this->m_storage.
template <class A>
class basic_string_base
- : private A
{
basic_string_base();
public:
@@ -86,20 +85,12 @@
typedef typename A::value_type value_type;
typedef typename A::size_type size_type;
- allocator_type get_allocator() const { return *this; }
-
- const stored_allocator_type &get_stored_allocator() const
- { return *this; }
-
- stored_allocator_type &get_stored_allocator()
- { return *this; }
-
basic_string_base(const allocator_type& a)
- : allocator_type(a)
+ : members_(a)
{ init(); }
basic_string_base(const allocator_type& a, std::size_t n)
- : allocator_type(a)
+ : members_(a)
{
this->init();
this->allocate_initial_block(n);
@@ -107,14 +98,14 @@
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_string_base(const detail::moved_object<basic_string_base<A> >& b)
- : allocator_type(static_cast<allocator_type&>(b.get()))
+ : members_(b.get().members_)
{
init();
this->swap(b.get());
}
#else
basic_string_base(basic_string_base<A> && b)
- : allocator_type(static_cast<allocator_type&>(b))
+ : members_(b.members_)
{
init();
this->swap(b);
@@ -125,7 +116,7 @@
{
this->deallocate_block();
if(!this->is_short()){
- static_cast<long_t*>(static_cast<void*>(&m_repr.r))->~long_t();
+ static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
}
}
@@ -212,7 +203,23 @@
long_t &long_repr() const
{ return *static_cast<long_t*>(const_cast<void*>(static_cast<const void*>(&r))); }
- } m_repr;
+ };
+
+ struct members_holder
+ : public A
+ {
+ members_holder(const A &a)
+ : A(a)
+ {}
+
+ repr_t m_repr;
+ } members_;
+
+ const A &alloc() const
+ { return members_; }
+
+ A &alloc()
+ { return members_; }
static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
@@ -222,24 +229,24 @@
protected:
bool is_short() const
- { return static_cast<bool>(m_repr.s.h.is_short != 0); }
+ { return static_cast<bool>(this->members_.m_repr.s.h.is_short != 0); }
void is_short(bool yes)
{
if(yes && !this->is_short()){
- static_cast<long_t*>(static_cast<void*>(&m_repr.r))->~long_t();
+ static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))->~long_t();
}
else{
- new(static_cast<void*>(&m_repr.r))long_t();
+ new(static_cast<void*>(&this->members_.m_repr.r))long_t();
}
- m_repr.s.h.is_short = yes;
+ this->members_.m_repr.s.h.is_short = yes;
}
private:
void init()
{
- m_repr.s.h.is_short = 1;
- m_repr.s.h.length = 0;
+ this->members_.m_repr.s.h.is_short = 1;
+ this->members_.m_repr.s.h.length = 0;
}
protected:
@@ -276,7 +283,7 @@
if(!(command & allocate_new))
return std::pair<pointer, bool>(0, 0);
received_size = preferred_size;
- return std::make_pair(A::allocate(received_size), false);
+ return std::make_pair(this->alloc().allocate(received_size), false);
}
std::pair<pointer, bool>
@@ -287,17 +294,17 @@
pointer reuse,
allocator_v2)
{
- return A::allocation_command(command, limit_size, preferred_size,
- received_size, reuse);
+ return this->alloc().allocation_command(command, limit_size, preferred_size,
+ received_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
- { return get_next_capacity(A::max_size(), this->priv_storage(), additional_objects); }
+ { return get_next_capacity(this->alloc().max_size(), this->priv_storage(), additional_objects); }
void deallocate(pointer p, std::size_t n)
{
if (p && (n > InternalBufferChars))
- allocator_type::deallocate(p, n);
+ this->alloc().deallocate(p, n);
}
void construct(pointer p, const value_type &value = value_type())
@@ -332,7 +339,7 @@
{ this->deallocate(this->priv_addr(), this->priv_storage()); }
std::size_t max_size() const
- { return A::max_size() - 1; }
+ { return this->alloc().max_size() - 1; }
// Helper functions for exception handling.
void throw_length_error() const
@@ -341,66 +348,60 @@
void throw_out_of_range() const
{ throw(std::out_of_range("basic_string")); }
- A & get_alloc()
- { return *this; }
-
- const A & get_alloc() const
- { return *this; }
-
protected:
size_type priv_capacity() const
{ return this->priv_storage() - 1; }
pointer priv_addr() const
- { return this->is_short() ? pointer(&m_repr.short_repr().data[0]) : m_repr.long_repr().start; }
+ { return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start; }
void priv_addr(pointer addr)
- { m_repr.long_repr().start = addr; }
+ { this->members_.m_repr.long_repr().start = addr; }
size_type priv_storage() const
- { return this->is_short() ? InternalBufferChars : m_repr.long_repr().storage; }
+ { return this->is_short() ? InternalBufferChars : this->members_.m_repr.long_repr().storage; }
void priv_storage(size_type storage)
{
if(!this->is_short())
- m_repr.long_repr().storage = storage;
+ this->members_.m_repr.long_repr().storage = storage;
}
size_type priv_size() const
- { return this->is_short() ? m_repr.short_repr().h.length : m_repr.long_repr().length; }
+ { return this->is_short() ? this->members_.m_repr.short_repr().h.length : this->members_.m_repr.long_repr().length; }
void priv_size(size_type sz)
{
if(this->is_short())
- m_repr.s.h.length = (unsigned char)sz;
+ this->members_.m_repr.s.h.length = (unsigned char)sz;
else
- m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
+ this->members_.m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
}
void swap(basic_string_base& other)
{
if(this->is_short()){
if(other.is_short()){
- std::swap(m_repr, other.m_repr);
+ std::swap(this->members_.m_repr, other.members_.m_repr);
}
else{
- repr_t copy(m_repr);
- m_repr.long_repr() = other.m_repr.long_repr();
- other.m_repr = copy;
+ repr_t copied(this->members_.m_repr);
+ this->members_.m_repr.long_repr() = other.members_.m_repr.long_repr();
+ other.members_.m_repr = copied;
}
}
else{
if(other.is_short()){
- repr_t copy(other.m_repr);
- other.m_repr.long_repr() = m_repr.long_repr();
- m_repr = copy;
+ repr_t copied(other.members_.m_repr);
+ other.members_.m_repr.long_repr() = this->members_.m_repr.long_repr();
+ this->members_.m_repr = copied;
}
else{
- std::swap(m_repr.long_repr(), other.m_repr.long_repr());
+ std::swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
}
}
- allocator_type & this_al = this->get_alloc(), &other_al = other.get_alloc();
+ allocator_type & this_al = this->alloc(), &other_al = other.alloc();
if(this_al != other_al){
detail::do_swap(this_al, other_al);
}
@@ -540,7 +541,7 @@
//!
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
basic_string(const basic_string& s)
- : base_t(s.get_allocator())
+ : base_t(s.alloc())
{ this->priv_range_initialize(s.begin(), s.end()); }
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
@@ -735,7 +736,7 @@
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const
- { return base_t::get_allocator(); }
+ { return this->alloc(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
//!
@@ -1531,7 +1532,7 @@
if (pos > size())
this->throw_out_of_range();
return basic_string(this->priv_addr() + pos,
- this->priv_addr() + pos + min_value(n, size() - pos), this->get_alloc());
+ this->priv_addr() + pos + min_value(n, size() - pos), this->alloc());
}
//! <b>Effects</b>: Three-way lexicographical comparison of s and *this.
@@ -1917,7 +1918,7 @@
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
- str_t result(reserve, x.size() + y.size(), x.get_allocator());
+ str_t result(reserve, x.size() + y.size(), x.alloc());
result.append(x);
result.append(y);
return result;
@@ -2038,7 +2039,7 @@
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
const std::size_t n = Traits::length(s);
- str_t result(reserve, x.size() + n, x.get_allocator());
+ str_t result(reserve, x.size() + n, x.alloc());
result.append(x);
result.append(s, s + n);
return result;
@@ -2071,7 +2072,7 @@
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
- str_t result(reserve, x.size() + 1, x.get_allocator());
+ str_t result(reserve, x.size() + 1, x.alloc());
result.append(x);
result.push_back(c);
return result;
@@ -2457,14 +2458,15 @@
}
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class C, class T, class A>
struct is_movable<basic_string<C, T, A> >
{
enum { value = true };
};
-/*!This class is movable*/
+//!This class is movable
template <class A>
struct is_movable<detail::basic_string_base<A> >
{
Modified: trunk/boost/interprocess/containers/vector.hpp
==============================================================================
--- trunk/boost/interprocess/containers/vector.hpp (original)
+++ trunk/boost/interprocess/containers/vector.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -52,10 +52,14 @@
#include <stdexcept>
#include <iterator>
#include <utility>
+#include <string.h> //for memcopy, memmove
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
-
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
#include <boost/interprocess/detail/version_type.hpp>
#include <boost/interprocess/allocators/allocation_type.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -71,40 +75,191 @@
namespace interprocess {
/// @cond
+
namespace detail {
+
+//! Const vector_iterator used to iterate through a vector.
+template <class Pointer>
+class vector_const_iterator
+ : public std::iterator<std::random_access_iterator_tag
+ ,const typename std::iterator_traits<Pointer>::value_type
+ ,typename std::iterator_traits<Pointer>::difference_type
+ ,typename pointer_to_other
+ <Pointer
+ ,const typename std::iterator_traits<Pointer>::value_type
+ >::type
+ ,const typename std::iterator_traits<Pointer>::value_type &>
+{
+ public:
+ typedef const typename std::iterator_traits<Pointer>::value_type value_type;
+ typedef typename std::iterator_traits<Pointer>::difference_type difference_type;
+ typedef typename pointer_to_other<Pointer, value_type>::type pointer;
+ typedef value_type& reference;
+
+ /// @cond
+ protected:
+ Pointer m_ptr;
+
+ public:
+ Pointer get_ptr() const { return m_ptr; }
+ explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){}
+ /// @endcond
+
+ public:
+
+ //Constructors
+ vector_const_iterator() : m_ptr(0){}
+
+ //Pointer like operators
+ reference operator*() const
+ { return *m_ptr; }
+
+ const value_type * operator->() const
+ { return detail::get_pointer(m_ptr); }
+
+ reference operator[](difference_type off) const
+ { return m_ptr[off]; }
+
+ //Increment / Decrement
+ vector_const_iterator& operator++()
+ { ++m_ptr; return *this; }
+
+ vector_const_iterator operator++(int)
+ { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); }
+
+ vector_const_iterator& operator--()
+ { --m_ptr; return *this; }
+
+ vector_const_iterator operator--(int)
+ { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); }
+
+ //Arithmetic
+ vector_const_iterator& operator+=(difference_type off)
+ { m_ptr += off; return *this; }
+
+ vector_const_iterator operator+(difference_type off) const
+ { return vector_const_iterator(m_ptr+off); }
+
+ friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right)
+ { return vector_const_iterator(off + right.m_ptr); }
+
+ vector_const_iterator& operator-=(difference_type off)
+ { m_ptr -= off; return *this; }
+
+ vector_const_iterator operator-(difference_type off) const
+ { return vector_const_iterator(m_ptr-off); }
+
+ difference_type operator-(const vector_const_iterator& right) const
+ { return m_ptr - right.m_ptr; }
+
+ //Comparison operators
+ bool operator== (const vector_const_iterator& r) const
+ { return m_ptr == r.m_ptr; }
+
+ bool operator!= (const vector_const_iterator& r) const
+ { return m_ptr != r.m_ptr; }
+
+ bool operator< (const vector_const_iterator& r) const
+ { return m_ptr < r.m_ptr; }
+
+ bool operator<= (const vector_const_iterator& r) const
+ { return m_ptr <= r.m_ptr; }
+
+ bool operator> (const vector_const_iterator& r) const
+ { return m_ptr > r.m_ptr; }
+
+ bool operator>= (const vector_const_iterator& r) const
+ { return m_ptr >= r.m_ptr; }
+};
+
+//! Iterator used to iterate through a vector
+template <class Pointer>
+class vector_iterator
+ : public vector_const_iterator<Pointer>
+{
+ public:
+ explicit vector_iterator(Pointer ptr)
+ : vector_const_iterator<Pointer>(ptr)
+ {}
+
+ public:
+ typedef typename std::iterator_traits<Pointer>::value_type value_type;
+ typedef typename vector_const_iterator<Pointer>::difference_type difference_type;
+ typedef Pointer pointer;
+ typedef value_type& reference;
+
+ //Constructors
+ vector_iterator()
+ {}
+
+ //Pointer like operators
+ reference operator*() const
+ { return *this->m_ptr; }
+
+ value_type* operator->() const
+ { return detail::get_pointer(this->m_ptr); }
+
+ reference operator[](difference_type off) const
+ { return this->m_ptr[off]; }
+
+ //Increment / Decrement
+ vector_iterator& operator++()
+ { ++this->m_ptr; return *this; }
+
+ vector_iterator operator++(int)
+ { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); }
+
+ vector_iterator& operator--()
+ { --this->m_ptr; return *this; }
+
+ vector_iterator operator--(int)
+ { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); }
+
+ // Arithmetic
+ vector_iterator& operator+=(difference_type off)
+ { this->m_ptr += off; return *this; }
+
+ vector_iterator operator+(difference_type off) const
+ { return vector_iterator(this->m_ptr+off); }
+
+ friend vector_iterator operator+(difference_type off, const vector_iterator& right)
+ { return vector_iterator(off + right.m_ptr); }
+
+ vector_iterator& operator-=(difference_type off)
+ { this->m_ptr -= off; return *this; }
+
+ vector_iterator operator-(difference_type off) const
+ { return vector_iterator(this->m_ptr-off); }
+
+ difference_type operator-(const vector_const_iterator<Pointer>& right) const
+ { return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; }
+};
+
//!This struct deallocates and allocated memory
template <class A>
struct vector_alloc_holder
- : public A
{
typedef typename A::pointer pointer;
typedef typename A::size_type size_type;
typedef typename A::value_type value_type;
- enum { trivial_dctr_after_move =
- has_trivial_destructor_after_move<value_type>::value ||
- boost::has_trivial_destructor<value_type>::value };
+ static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr_after_move =
+ has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_copy = has_trivial_copy<value_type>::value;
+ static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
+ static const bool trivial_assign = has_trivial_assign<value_type>::value;
+ static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
//Constructor, does not throw
vector_alloc_holder(const A &a)
- : A(a), m_start(0), m_size(0), m_capacity(0)
+ : members_(a)
{}
//Constructor, does not throw
vector_alloc_holder(const vector_alloc_holder<A> &h)
- : A((A&)h), m_start(0), m_size(0), m_capacity(0)
- {}
-
- //Constructor, does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- vector_alloc_holder(const detail::moved_object<vector_alloc_holder<A> > &h)
- : A(move((A&)h.get())), m_start(0), m_size(0), m_capacity(0)
+ : members_(h.alloc())
{}
- #else
- vector_alloc_holder(vector_alloc_holder<A> &&h)
- : A(move((A&)h)), m_start(0), m_size(0), m_capacity(0)
- {}
- #endif
//Destructor
~vector_alloc_holder()
@@ -137,7 +292,7 @@
if(!(command & allocate_new))
return std::pair<pointer, bool>(0, 0);
received_size = preferred_size;
- return std::make_pair(A::allocate(received_size), false);
+ return std::make_pair(this->alloc().allocate(received_size), false);
}
std::pair<pointer, bool>
@@ -148,38 +303,56 @@
const pointer &reuse,
allocator_v2)
{
- return A::allocation_command(command, limit_size, preferred_size,
- received_size, reuse);
+ return this->alloc().allocation_command(command, limit_size, preferred_size,
+ received_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
- { return get_next_capacity(A::max_size(), this->m_capacity, additional_objects); }
+ { return get_next_capacity(this->alloc().max_size(), this->members_.m_capacity, additional_objects); }
- pointer m_start;
- size_type m_size;
- size_type m_capacity;
+ struct members_holder
+ : public A
+ {
+ private:
+ members_holder(const members_holder&);
+
+ public:
+ members_holder(const A &alloc)
+ : A(alloc), m_start(0), m_size(0), m_capacity(0)
+ {}
+
+ pointer m_start;
+ size_type m_size;
+ size_type m_capacity;
+ } members_;
protected:
void prot_deallocate()
{
- if(!m_start) return;
- this->deallocate(m_start, m_capacity);
- m_start = 0;
- m_size = 0;
- m_capacity = 0;
+ if(!this->members_.m_start) return;
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ this->members_.m_start = 0;
+ this->members_.m_size = 0;
+ this->members_.m_capacity = 0;
}
- void destroy(pointer p)
+ void destroy(value_type* p)
{
- if(!has_trivial_destructor<value_type>::value)
+ if(!trivial_dctr)
detail::get_pointer(p)->~value_type();
}
- void destroy_n(pointer p, size_type n)
+ void destroy_n(value_type* p, size_type n)
{
- if(!has_trivial_destructor<value_type>::value)
- for(; n--; ++p) detail::get_pointer(p)->~value_type();
+ if(!trivial_dctr)
+ for(; n--; ++p) p->~value_type();
}
+
+ A &alloc()
+ { return members_; }
+
+ const A &alloc() const
+ { return members_; }
};
} //namespace detail {
@@ -197,192 +370,28 @@
/// @cond
typedef vector<T, A> self_t;
typedef detail::vector_alloc_holder<A> base_t;
- typedef detail::scoped_array_deallocator<A> dealloc_t;
/// @endcond
public:
//! The type of object, T, stored in the vector
- typedef T value_type;
+ typedef T value_type;
//! Pointer to T
- typedef typename A::pointer pointer;
+ typedef typename A::pointer pointer;
//! Const pointer to T
- typedef typename A::const_pointer const_pointer;
+ typedef typename A::const_pointer const_pointer;
//! Reference to T
- typedef typename A::reference reference;
+ typedef typename A::reference reference;
//! Const reference to T
- typedef typename A::const_reference const_reference;
+ typedef typename A::const_reference const_reference;
//! An unsigned integral type
- typedef typename A::size_type size_type;
+ typedef typename A::size_type size_type;
//! A signed integral type
- typedef typename A::difference_type difference_type;
+ typedef typename A::difference_type difference_type;
//! The allocator type
- typedef A allocator_type;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
-
- /// @cond
- private:
- //This shouldn't be needed but VC6.0 needs this
- typedef typename A::pointer vec_ptr;
- typedef typename A::const_pointer vec_cptr;
- typedef typename A::reference vec_ref;
- typedef typename A::const_reference vec_cref;
- typedef typename A::difference_type vec_diff;
-
-
- typedef typename base_t::allocator_v1 allocator_v1;
- typedef typename base_t::allocator_v2 allocator_v2;
- typedef typename base_t::alloc_version alloc_version;
-
- typedef constant_iterator<T, difference_type> cvalue_iterator;
- /// @endcond
- public:
-
- /// @cond
-
- //! Const iterator used to iterate through a vector.
- class const_iterator
- : public std::iterator<std::random_access_iterator_tag
- ,value_type
- ,vec_diff
- ,vec_cptr
- ,vec_cref>
- {
- /// @cond
- private:
- vec_ptr get_ptr() const { return m_ptr; }
-
- protected:
- vec_ptr m_ptr;
- explicit const_iterator(vec_ptr ptr) : m_ptr(ptr){}
- /// @endcond
- public:
- friend class vector<T, A>;
- typedef vec_diff difference_type;
-
- //Constructors
- const_iterator() : m_ptr(0){}
-
- //Pointer like operators
- const_reference operator*() const
- { return *m_ptr; }
-
- const_pointer operator->() const
- { return m_ptr; }
-
- const_reference operator[](difference_type off) const
- { return m_ptr[off]; }
-
- //Increment / Decrement
- const_iterator& operator++()
- { ++m_ptr; return *this; }
-
- const_iterator operator++(int)
- { vec_ptr tmp = m_ptr; ++*this; return const_iterator(tmp); }
-
- const_iterator& operator--()
- { --m_ptr; return *this; }
-
- const_iterator operator--(int)
- { vec_ptr tmp = m_ptr; --*this; return const_iterator(tmp); }
-
- //Arithmetic
- const_iterator& operator+=(difference_type off)
- { m_ptr += off; return *this; }
-
- const_iterator operator+(difference_type off) const
- { return const_iterator(m_ptr+off); }
-
- friend const_iterator operator+(difference_type off, const const_iterator& right)
- { return const_iterator(off + right.m_ptr); }
-
- const_iterator& operator-=(difference_type off)
- { m_ptr -= off; return *this; }
-
- const_iterator operator-(difference_type off) const
- { return const_iterator(m_ptr-off); }
-
- difference_type operator-(const const_iterator& right) const
- { return m_ptr - right.m_ptr; }
-
- //Comparison operators
- bool operator== (const const_iterator& r) const
- { return m_ptr == r.m_ptr; }
-
- bool operator!= (const const_iterator& r) const
- { return m_ptr != r.m_ptr; }
-
- bool operator< (const const_iterator& r) const
- { return m_ptr < r.m_ptr; }
-
- bool operator<= (const const_iterator& r) const
- { return m_ptr <= r.m_ptr; }
-
- bool operator> (const const_iterator& r) const
- { return m_ptr > r.m_ptr; }
-
- bool operator>= (const const_iterator& r) const
- { return m_ptr >= r.m_ptr; }
- };
-
- //! Iterator used to iterate through a vector
- class iterator
- : public const_iterator
- {
- protected:
- explicit iterator(vec_ptr ptr) : const_iterator(ptr){}
-
- public:
- friend class vector<T, A>;
- typedef vec_ptr pointer;
- typedef vec_ref reference;
-
- //Constructors
- iterator(){}
-
- //Pointer like operators
- reference operator*() const
- { return *this->m_ptr; }
-
- pointer operator->() const
- { return this->m_ptr; }
-
- reference operator[](difference_type off) const
- { return this->m_ptr[off]; }
-
- //Increment / Decrement
- iterator& operator++()
- { ++this->m_ptr; return *this; }
-
- iterator operator++(int)
- { pointer tmp = this->m_ptr; ++*this; return iterator(tmp); }
-
- iterator& operator--()
- { --this->m_ptr; return *this; }
-
- iterator operator--(int)
- { iterator tmp = *this; --*this; return iterator(tmp); }
-
- // Arithmetic
- iterator& operator+=(difference_type off)
- { this->m_ptr += off; return *this; }
-
- iterator operator+(difference_type off) const
- { return iterator(this->m_ptr+off); }
-
- friend iterator operator+(difference_type off, const iterator& right)
- { return iterator(off + right.m_ptr); }
-
- iterator& operator-=(difference_type off)
- { this->m_ptr -= off; return *this; }
-
- iterator operator-(difference_type off) const
- { return iterator(this->m_ptr-off); }
-
- difference_type operator-(const const_iterator& right) const
- { return *((const_iterator*)this) - right; }
- };
-
- /// @endcond
+ typedef A allocator_type;
+ //! The random access iterator
+ typedef detail::vector_iterator<pointer> iterator;
+ //! The random access const_iterator
+ typedef detail::vector_const_iterator<pointer> const_iterator;
//! Iterator used to iterate backwards through a vector.
typedef std::reverse_iterator<iterator>
@@ -390,6 +399,56 @@
//! Const iterator used to iterate backwards through a vector.
typedef std::reverse_iterator<const_iterator>
const_reverse_iterator;
+ //! The stored allocator type
+ typedef allocator_type stored_allocator_type;
+
+ /// @cond
+ private:
+
+ typedef typename base_t::allocator_v1 allocator_v1;
+ typedef typename base_t::allocator_v2 allocator_v2;
+ typedef typename base_t::alloc_version alloc_version;
+
+ typedef constant_iterator<T, difference_type> cvalue_iterator;
+ typedef repeat_iterator<T, difference_type> repeat_iterator;
+ typedef detail::move_iterator<repeat_iterator> repeat_move_it;
+ //This is the anti-exception array destructor
+ //to deallocate values already constructed
+ typedef typename detail::if_c
+ <base_t::trivial_dctr
+ ,detail::null_scoped_destructor_n<allocator_type>
+ ,detail::scoped_destructor_n<allocator_type>
+ >::type OldArrayDestructor;
+ //This is the anti-exception array destructor
+ //to destroy objects created with copy construction
+ typedef typename detail::if_c
+ <base_t::nothrow_copy
+ ,detail::null_scoped_destructor_n<allocator_type>
+ ,detail::scoped_destructor_n<allocator_type>
+ >::type UCopiedArrayDestructor;
+ //This is the anti-exception array deallocator
+ typedef typename detail::if_c
+ <base_t::nothrow_copy
+ ,detail::null_scoped_array_deallocator<allocator_type>
+ ,detail::scoped_array_deallocator<allocator_type>
+ >::type UCopiedArrayDeallocator;
+
+ //This is the optimized move iterator for copy constructors
+ //so that std::copy and similar can use memcpy
+ typedef typename detail::if_c
+ <base_t::trivial_copy
+ ,T*
+ ,detail::move_iterator<T*>
+ >::type copy_move_it;
+
+ //This is the optimized move iterator for assignments
+ //so that std::uninitialized_copy and similar can use memcpy
+ typedef typename detail::if_c
+ <base_t::trivial_assign
+ ,T*
+ ,detail::move_iterator<T*>
+ >::type assign_move_it;
+ /// @endcond
public:
@@ -430,28 +489,12 @@
//! <b>Complexity</b>: Constant.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
vector(const detail::moved_object<vector<T, A> >& mx)
- : base_t(move((base_t&)mx.get()))
- {
- vector<T, A> &x = mx.get();
- this->m_start = x.m_start;
- this->m_size = x.m_size;
- this->m_capacity = x.m_capacity;
- x.m_start = 0;
- x.m_size = 0;
- x.m_capacity = 0;
- }
+ : base_t(mx.get())
+ { this->swap(mx.get()); }
#else
vector(vector<T, A> && mx)
- : base_t(move((base_t&)mx))
- {
- vector<T, A> &x = mx;
- this->m_start = x.m_start;
- this->m_size = x.m_size;
- this->m_capacity = x.m_capacity;
- x.m_start = 0;
- x.m_size = 0;
- x.m_capacity = 0;
- }
+ : base_t(mx)
+ { this->swap(mx); }
#endif
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
@@ -481,7 +524,7 @@
//!
//! <b>Complexity</b>: Constant.
iterator begin()
- { return iterator(this->m_start); }
+ { return iterator(this->members_.m_start); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
//!
@@ -489,7 +532,7 @@
//!
//! <b>Complexity</b>: Constant.
const_iterator begin() const
- { return const_iterator(this->m_start); }
+ { return const_iterator(this->members_.m_start); }
//! <b>Effects</b>: Returns an iterator to the end of the vector.
//!
@@ -497,7 +540,7 @@
//!
//! <b>Complexity</b>: Constant.
iterator end()
- { return iterator(this->m_start + this->m_size); }
+ { return iterator(this->members_.m_start + this->members_.m_size); }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
//!
@@ -505,7 +548,7 @@
//!
//! <b>Complexity</b>: Constant.
const_iterator end() const
- { return const_iterator(this->m_start + this->m_size); }
+ { return const_iterator(this->members_.m_start + this->members_.m_size); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed vector.
@@ -552,7 +595,7 @@
//!
//! <b>Complexity</b>: Constant.
reference front()
- { return *this->m_start; }
+ { return *this->members_.m_start; }
//! <b>Requires</b>: !empty()
//!
@@ -563,7 +606,7 @@
//!
//! <b>Complexity</b>: Constant.
const_reference front() const
- { return *this->m_start; }
+ { return *this->members_.m_start; }
//! <b>Requires</b>: !empty()
//!
@@ -574,7 +617,7 @@
//!
//! <b>Complexity</b>: Constant.
reference back()
- { return this->m_start[this->m_size - 1]; }
+ { return this->members_.m_start[this->members_.m_size - 1]; }
//! <b>Requires</b>: !empty()
//!
@@ -585,7 +628,7 @@
//!
//! <b>Complexity</b>: Constant.
const_reference back() const
- { return this->m_start[this->m_size - 1]; }
+ { return this->members_.m_start[this->members_.m_size - 1]; }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
//!
@@ -593,7 +636,7 @@
//!
//! <b>Complexity</b>: Constant.
size_type size() const
- { return this->m_size; }
+ { return this->members_.m_size; }
//! <b>Effects</b>: Returns the largest possible size of the vector.
//!
@@ -601,7 +644,7 @@
//!
//! <b>Complexity</b>: Constant.
size_type max_size() const
- { return allocator_type::max_size(); }
+ { return this->alloc().max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -610,7 +653,7 @@
//!
//! <b>Complexity</b>: Constant.
size_type capacity() const
- { return this->m_capacity; }
+ { return this->members_.m_capacity; }
//! <b>Effects</b>: Returns true if the vector contains no elements.
//!
@@ -618,7 +661,7 @@
//!
//! <b>Complexity</b>: Constant.
bool empty() const
- { return !this->m_size; }
+ { return !this->members_.m_size; }
//! <b>Requires</b>: size() < n.
//!
@@ -629,7 +672,7 @@
//!
//! <b>Complexity</b>: Constant.
reference operator[](size_type n)
- { return this->m_start[n]; }
+ { return this->members_.m_start[n]; }
//! <b>Requires</b>: size() < n.
//!
@@ -640,7 +683,7 @@
//!
//! <b>Complexity</b>: Constant.
const_reference operator[](size_type n) const
- { return this->m_start[n]; }
+ { return this->members_.m_start[n]; }
//! <b>Requires</b>: size() < n.
//!
@@ -651,7 +694,7 @@
//!
//! <b>Complexity</b>: Constant.
reference at(size_type n)
- { this->priv_check_range(n); return this->m_start[n]; }
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
//! <b>Requires</b>: size() < n.
//!
@@ -662,7 +705,7 @@
//!
//! <b>Complexity</b>: Constant.
const_reference at(size_type n) const
- { this->priv_check_range(n); return this->m_start[n]; }
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
//! <b>Effects</b>: Returns a copy of the internal allocator.
//!
@@ -670,13 +713,13 @@
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const
- { return *this; }
+ { return this->alloc(); }
const stored_allocator_type &get_stored_allocator() const
- { return *this; }
+ { return this->alloc(); }
stored_allocator_type &get_stored_allocator()
- { return *this; }
+ { return this->alloc(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
//! effect. Otherwise, it is a request for allocation of additional memory.
@@ -694,27 +737,35 @@
std::pair<pointer, bool> ret =
this->allocation_command
(allocate_new | expand_fwd | expand_bwd,
- new_cap, new_cap, real_cap, this->m_start);
+ new_cap, new_cap, real_cap, this->members_.m_start);
//Check for forward expansion
- same_buffer_start = ret.second && this->m_start == ret.first;
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
if(same_buffer_start){
- this->m_capacity = real_cap;
+ this->members_.m_capacity = real_cap;
}
-
//If there is no forward expansion, move objects
- if (!same_buffer_start){
+ else{
//We will reuse insert code, so create a dummy input iterator
- detail::move_iterator<pointer> dummy_it(this->m_start);
+ copy_move_it dummy_it(detail::get_pointer(this->members_.m_start));
//Backwards (and possibly forward) expansion
if(ret.second){
this->priv_range_insert_expand_backwards
- (ret.first, real_cap, this->m_start, dummy_it, dummy_it, 0);
+ ( detail::get_pointer(ret.first)
+ , real_cap
+ , detail::get_pointer(this->members_.m_start)
+ , dummy_it
+ , dummy_it
+ , 0);
}
//New buffer
else{
this->priv_range_insert_new_allocation
- (ret.first, real_cap, this->m_start, dummy_it, dummy_it);
+ ( detail::get_pointer(ret.first)
+ , real_cap
+ , detail::get_pointer(this->members_.m_start)
+ , dummy_it
+ , dummy_it);
}
}
}
@@ -731,7 +782,7 @@
vector<T, A>& operator=(const vector<T, A>& x)
{
if (&x != this){
- this->assign(x.m_start, x.m_start + x.m_size);
+ this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size);
}
return *this;
}
@@ -801,10 +852,10 @@
//! <b>Complexity</b>: Amortized constant time.
void push_back(const T& x)
{
- if (this->m_size < this->m_capacity){
+ if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
- new(detail::get_pointer(this->m_start) + this->m_size)value_type(x);
- ++this->m_size;
+ new(detail::get_pointer(this->members_.m_start) + this->members_.m_size)value_type(x);
+ ++this->members_.m_size;
}
else{
this->insert(this->end(), x);
@@ -820,10 +871,10 @@
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void push_back(const detail::moved_object<T> & mx)
{
- if (this->m_size < this->m_capacity){
+ if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
- new(detail::get_pointer(this->m_start + this->m_size))value_type(mx);
- ++this->m_size;
+ new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx);
+ ++this->members_.m_size;
}
else{
this->insert(this->end(), mx);
@@ -832,10 +883,10 @@
#else
void push_back(T && mx)
{
- if (this->m_size < this->m_capacity){
+ if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
- new(detail::get_pointer(this->m_start + this->m_size))value_type(move(mx));
- ++this->m_size;
+ new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx));
+ ++this->members_.m_size;
}
else{
this->insert(this->end(), move(mx));
@@ -852,11 +903,11 @@
//! <b>Complexity</b>: Constant.
void swap(vector<T, A>& x)
{
- allocator_type &this_al = *this, &other_al = x;
+ allocator_type &this_al = this->alloc(), &other_al = x.alloc();
//Just swap internals
- detail::do_swap(this->m_start, x.m_start);
- detail::do_swap(this->m_size, x.m_size);
- detail::do_swap(this->m_capacity, x.m_capacity);
+ detail::do_swap(this->members_.m_start, x.members_.m_start);
+ detail::do_swap(this->members_.m_size, x.members_.m_size);
+ detail::do_swap(this->members_.m_capacity, x.members_.m_capacity);
if (this_al != other_al){
detail::do_swap(this_al, other_al);
@@ -897,7 +948,7 @@
//Just call more general insert(pos, size, value) and return iterator
size_type n = position - begin();
this->insert(position, (size_type)1, x);
- return iterator(this->m_start + n);
+ return iterator(this->members_.m_start + n);
}
//! <b>Requires</b>: position must be a valid iterator of *this.
@@ -911,26 +962,22 @@
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
iterator insert(iterator position, const detail::moved_object<T> &mx)
{
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef detail::move_iterator<r_iterator> move_it;
//Just call more general insert(pos, size, value) and return iterator
size_type n = position - begin();
this->insert(position
- ,move_it(r_iterator(mx.get(), 1))
- ,move_it(r_iterator()));
- return iterator(this->m_start + n);
+ ,repeat_move_it(repeat_iterator(mx.get(), 1))
+ ,repeat_move_it(repeat_iterator()));
+ return iterator(this->members_.m_start + n);
}
#else
iterator insert(iterator position, T &&mx)
{
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef detail::move_iterator<r_iterator> move_it;
//Just call more general insert(pos, size, value) and return iterator
size_type n = position - begin();
this->insert(position
- ,move_it(r_iterator(mx, 1))
- ,move_it(r_iterator()));
- return iterator(this->m_start + n);
+ ,repeat_move_it(repeat_iterator(mx, 1))
+ ,repeat_move_it(repeat_iterator()));
+ return iterator(this->members_.m_start + n);
}
#endif
@@ -969,8 +1016,8 @@
void pop_back()
{
//Destroy last element
- --this->m_size;
- this->destroy(this->m_start + this->m_size);
+ --this->members_.m_size;
+ this->destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size);
}
//! <b>Effects</b>: Erases the element at position pos.
@@ -981,16 +1028,13 @@
//! last element. Constant if pos is the first or the last element.
iterator erase(const_iterator position)
{
- size_type p_off = position.get_ptr() - this->m_start;
- if (p_off + 1 != this->m_size){
- //If not the last element, copy left [position, end()) elements
- copy_n(detail::make_move_iterator(this->m_start + (p_off + 1))
- ,this->m_size - (p_off + 1)
- ,this->m_start + p_off);
- }
- --this->m_size;
+ T *pos = detail::get_pointer(position.get_ptr());
+ T *beg = detail::get_pointer(this->members_.m_start);
+
+ std::copy(assign_move_it(pos + 1), assign_move_it(beg + this->members_.m_size), pos);
+ --this->members_.m_size;
//Destroy last element
- base_t::destroy(this->m_start + this->m_size);
+ base_t::destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size);
return iterator(position.get_ptr());
}
@@ -1001,19 +1045,17 @@
//! <b>Complexity</b>: Linear to the distance between first and last.
iterator erase(const_iterator first, const_iterator last)
{
- //Overwrite [last, end()) elements to first
- size_type f_off = first.get_ptr() - this->m_start;
- size_type l_off = last.get_ptr() - this->m_start;
- size_type n = l_off - f_off;
- size_type rem = this->m_size - l_off;
- size_type to_destroy = this->m_size - (f_off + rem);
- size_type destroy_off = f_off + rem;
-
- //Overwrite [last, end()) elements to first
- copy_n(detail::make_move_iterator(last.get_ptr()), rem, first.get_ptr());
- //Destroy remaining objects
- this->destroy_n(this->m_start + destroy_off, to_destroy);
- this->m_size -= n;
+ if (first != last){ // worth doing, copy down over hole
+ T* end_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
+ T* ptr = detail::get_pointer(std::copy
+ (assign_move_it(detail::get_pointer(last.get_ptr()))
+ ,assign_move_it(end_pos)
+ ,detail::get_pointer(first.get_ptr())
+ ));
+ size_type destroyed = (end_pos - ptr);
+ this->destroy_n(ptr, destroyed);
+ this->members_.m_size -= destroyed;
+ }
return iterator(first.get_ptr());
}
@@ -1025,10 +1067,10 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size, const T& x)
{
- pointer finish = this->m_start + this->m_size;
+ pointer finish = this->members_.m_start + this->members_.m_size;
if (new_size < size()){
//Destroy last elements
- this->erase(iterator(this->m_start + new_size), this->end());
+ this->erase(iterator(this->members_.m_start + new_size), this->end());
}
else{
//Insert new elements at the end
@@ -1046,16 +1088,16 @@
{
if (new_size < this->size()){
//Destroy last elements
- this->erase(iterator(this->m_start + new_size), this->end());
+ this->erase(iterator(this->members_.m_start + new_size), this->end());
}
else{
size_type n = new_size - this->size();
this->reserve(new_size);
- T *ptr = detail::get_pointer(this->m_start + this->m_size);
+ T *ptr = detail::get_pointer(this->members_.m_start + this->members_.m_size);
while(n--){
//Default construct
new(ptr++)T();
- ++this->m_size;
+ ++this->members_.m_size;
}
}
}
@@ -1068,8 +1110,10 @@
void clear()
{ this->priv_destroy_all(); }
+ /// @cond
+
//! <b>Effects</b>: Tries to deallocate the excess of memory created
- // with previous allocations. The size of the vector is unchanged
+ //! with previous allocations. The size of the vector is unchanged
//!
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
@@ -1077,11 +1121,10 @@
void shrink_to_fit()
{ priv_shrink_to_fit(alloc_version()); }
- /// @cond
private:
void priv_shrink_to_fit(allocator_v1)
{
- if(this->m_start){
+ if(this->members_.m_start){
if(!size()){
this->prot_deallocate();
}
@@ -1094,22 +1137,22 @@
void priv_shrink_to_fit(allocator_v2)
{
- if(this->m_start){
+ if(this->members_.m_start){
if(!size()){
this->prot_deallocate();
}
else{
size_type received_size;
- A::allocation_command(shrink_in_place, this->size(), this->capacity()
- ,received_size, this->m_start);
+ this->alloc().allocation_command(shrink_in_place, this->size(), this->capacity()
+ ,received_size, this->members_.m_start);
}
}
}
void priv_destroy_all()
{
- destroy_n(this->m_start, this->m_size);
- this->m_size = 0;
+ destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->members_.m_size = 0;
}
template <class FwdIt>
@@ -1119,10 +1162,10 @@
if (first != last){
size_type n = std::distance(first, last);
//Check if we have enough memory or try to expand current memory
- size_type remaining = this->m_capacity - this->m_size;
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
bool same_buffer_start;
std::pair<pointer, bool> ret;
- size_type real_cap = this->m_capacity;
+ size_type real_cap = this->members_.m_capacity;
//Check if we already have room
if (n <= remaining){
@@ -1134,132 +1177,143 @@
size_type new_cap = this->next_capacity(n);
ret = this->allocation_command
(allocate_new | expand_fwd | expand_bwd,
- this->m_size + n, new_cap, real_cap, this->m_start);
+ this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
//Check for forward expansion
- same_buffer_start = ret.second && this->m_start == ret.first;
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
if(same_buffer_start){
- this->m_capacity = real_cap;
+ this->members_.m_capacity = real_cap;
}
}
//If we had room or we have expanded forward
if (same_buffer_start){
this->priv_range_insert_expand_forward
- (pos, first, last, n);
+ (detail::get_pointer(pos), first, last, n);
}
//Backwards (and possibly forward) expansion
else if(ret.second){
this->priv_range_insert_expand_backwards
- (ret.first, real_cap, pos, first, last, n);
+ ( detail::get_pointer(ret.first)
+ , real_cap
+ , detail::get_pointer(pos)
+ , first
+ , last
+ , n);
}
//New buffer
else{
this->priv_range_insert_new_allocation
- (ret.first, real_cap, pos, first, last);
+ ( detail::get_pointer(ret.first)
+ , real_cap
+ , detail::get_pointer(pos)
+ , first
+ , last);
}
}
}
template <class FwdIt>
void priv_range_insert_expand_forward
- (pointer pos, FwdIt first, FwdIt last, size_type n)
+ (T* pos, FwdIt first, FwdIt last, size_type n)
{
- typedef detail::move_iterator<pointer> move_it;
//There is enough memory
- pointer old_finish = this->m_start + this->m_size;
+ T* old_finish = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
const size_type elems_after = old_finish - pos;
if (elems_after > n){
//New elements can be just copied.
//Move to uninitialized memory last objects
- boost::interprocess::n_uninitialized_copy
- (move_it(old_finish - n), move_it(old_finish), old_finish);
- this->m_size += n;
+ std::uninitialized_copy(copy_move_it(old_finish - n), copy_move_it(old_finish), old_finish);
+ this->members_.m_size += n;
//Copy previous to last objects to the initialized end
- std::copy_backward(move_it(pos), move_it(old_finish - n), old_finish);
+ std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish - n), old_finish);
//Insert new objects in the pos
- copy_n(first, n, pos);
+ std::copy(first, last, detail::get_pointer(pos));
}
else {
//The new elements don't fit in the [pos, end()) range. Copy
//to the beginning of the unallocated zone the last new elements.
FwdIt mid = first;
std::advance(mid, elems_after);
- boost::interprocess::n_uninitialized_copy(mid, last, old_finish);
- this->m_size += n - elems_after;
+ std::uninitialized_copy(mid, last, old_finish);
+ this->members_.m_size += n - elems_after;
//Copy old [pos, end()) elements to the uninitialized memory
- boost::interprocess::n_uninitialized_copy
- (move_it(pos), move_it(old_finish), this->m_start + this->m_size);
- this->m_size += elems_after;
+ std::uninitialized_copy
+ ( copy_move_it(detail::get_pointer(pos))
+ , copy_move_it(old_finish)
+ , detail::get_pointer(this->members_.m_start) + this->members_.m_size);
+ this->members_.m_size += elems_after;
//Copy first new elements in pos
- std::copy(first, mid, pos);
+ std::copy(first, mid, detail::get_pointer(pos));
}
}
template <class FwdIt>
void priv_range_insert_new_allocation
- (pointer new_start, size_type new_cap, pointer pos, FwdIt first, FwdIt last)
+ (T* new_start, size_type new_cap, T* pos, FwdIt first, FwdIt last)
{
- typedef detail::move_iterator<pointer> move_it;
- //Anti-exception rollback
- dealloc_t scoped_alloc(new_start, *this, new_cap);
- pointer new_finish = new_start;
- BOOST_TRY{
- //Initialize with [begin(), pos) old buffer
- //the start of the new buffer
- new_finish += boost::interprocess::n_uninitialized_copy
- (move_it(this->m_start), move_it(pos), new_start);
- //Initialize new objects, starting from previous point
- new_finish += boost::interprocess::n_uninitialized_copy
- (first, last, new_finish);
- //Initialize from the rest of the old buffer,
- //starting from previous point
- new_finish += boost::interprocess::n_uninitialized_copy
- (move_it(pos), move_it(this->m_start + this->m_size), new_finish);
- }
- BOOST_CATCH(...){
- this->destroy_n(new_start, new_finish - new_start);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ T* new_finish = new_start;
+ T *old_finish;
+ //Anti-exception rollbacks
+ UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
+ UCopiedArrayDestructor construted_values_destroyer(new_start, 0u);
+
+ //Initialize with [begin(), pos) old buffer
+ //the start of the new buffer
+ new_finish = std::uninitialized_copy
+ ( copy_move_it(detail::get_pointer(this->members_.m_start))
+ , copy_move_it(detail::get_pointer(pos))
+ , old_finish = new_finish);
+ construted_values_destroyer.increment_size(new_finish - old_finish);
+ //Initialize new objects, starting from previous point
+ new_finish = std::uninitialized_copy
+ (first, last, old_finish = new_finish);
+ construted_values_destroyer.increment_size(new_finish - old_finish);
+ //Initialize from the rest of the old buffer,
+ //starting from previous point
+ new_finish = std::uninitialized_copy
+ ( copy_move_it(detail::get_pointer(pos))
+ , copy_move_it(detail::get_pointer(this->members_.m_start) + this->members_.m_size)
+ , detail::get_pointer(new_finish));
+
+ //All construction successful, disable rollbacks
+ construted_values_destroyer.release();
scoped_alloc.release();
//Destroy and deallocate old elements
//If there is allocated memory, destroy and deallocate
- if(this->m_start != 0){
+ if(this->members_.m_start != 0){
if(!base_t::trivial_dctr_after_move)
- this->destroy_n(this->m_start, this->m_size);
- this->deallocate(this->m_start, this->m_capacity);
+ this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
}
- this->m_start = new_start;
- this->m_size = new_finish - new_start;
- this->m_capacity = new_cap;
+ this->members_.m_start = new_start;
+ this->members_.m_size = new_finish - new_start;
+ this->members_.m_capacity = new_cap;
}
template <class FwdIt>
void priv_range_insert_expand_backwards
- (pointer new_start, size_type new_capacity,
- pointer pos, FwdIt first, FwdIt last, size_type n)
+ (T* new_start, size_type new_capacity,
+ T* pos, FwdIt first, FwdIt last, size_type n)
{
- typedef detail::scoped_destructor_n<allocator_type> ValueArrayDestructor;
- typedef detail::move_iterator<pointer> move_it;
//Backup old data
- pointer old_start = this->m_start;
- pointer old_finish = this->m_start + this->m_size;
- size_type old_size = this->m_size;
+ T* old_start = detail::get_pointer(this->members_.m_start);
+ T* old_finish = old_start + this->members_.m_size;
+ size_type old_size = this->members_.m_size;
//We can have 8 possibilities:
- const size_type elemsbefore = (size_type)(pos - this->m_start);
+ const size_type elemsbefore = (size_type)(pos - old_start);
const size_type s_before = (size_type)(old_start - new_start);
//Update the vector buffer information to a safe state
- this->m_start = new_start;
- this->m_capacity = new_capacity;
- this->m_size = 0;
+ this->members_.m_start = new_start;
+ this->members_.m_capacity = new_capacity;
+ this->members_.m_size = 0;
//If anything goes wrong, this object will destroy
//all the old objects to fulfill previous vector state
- ValueArrayDestructor old_values_destroyer(old_start, old_size);
+ OldArrayDestructor old_values_destroyer(old_start, old_size);
//Check if s_before is so big that even copying the old data + new data
//there is a gap between the new data and the old data
@@ -1277,14 +1331,16 @@
//Copy first old values before pos, after that the
//new objects
boost::interprocess::uninitialized_copy_copy
- (move_it(old_start), move_it(pos), first, last, new_start);
- ValueArrayDestructor new_values_destroyer(new_start, elemsbefore);
+ (copy_move_it(old_start), copy_move_it(detail::get_pointer(pos)), first, last, detail::get_pointer(new_start));
+ UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
//Now initialize the rest of memory with the last old values
- boost::interprocess::uninitialized_copy(move_it(pos), move_it(old_finish)
- ,new_start + elemsbefore + n);
+ std::uninitialized_copy
+ ( copy_move_it(detail::get_pointer(pos))
+ , copy_move_it(old_finish)
+ , detail::get_pointer(new_start) + elemsbefore + n);
//All new elements correctly constructed, avoid new element destruction
new_values_destroyer.release();
- this->m_size = old_size + n;
+ this->members_.m_size = old_size + n;
//Old values destroyed automatically with "old_values_destroyer"
//when "old_values_destroyer" goes out of scope unless the have trivial
//destructor after move.
@@ -1306,28 +1362,31 @@
//Copy first old values before pos, after that the
//new objects
boost::interprocess::uninitialized_copy_copy
- (move_it(old_start), move_it(pos), first, last, new_start);
- ValueArrayDestructor new_values_destroyer(new_start, elemsbefore);
+ ( copy_move_it(old_start)
+ , copy_move_it(detail::get_pointer(pos))
+ , first, last, detail::get_pointer(new_start));
+ UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
size_type raw_gap = s_before - (elemsbefore + n);
//Now initialize the rest of s_before memory with the
//first of elements after new values
- boost::interprocess::uninitialized_copy
- (move_it(pos), move_it(pos + raw_gap), new_start + elemsbefore + n);
+ std::uninitialized_copy
+ ( copy_move_it(detail::get_pointer(pos))
+ , copy_move_it(detail::get_pointer(pos) + raw_gap)
+ , detail::get_pointer(new_start) + elemsbefore + n);
//All new elements correctly constructed, avoid new element destruction
new_values_destroyer.release();
//All new elements correctly constructed, avoid old element destruction
old_values_destroyer.release();
//Update size since we have a contiguous buffer
- this->m_size = old_size + s_before;
+ this->members_.m_size = old_size + s_before;
//Now copy remaining last objects in the old buffer begin
- pointer to_destroy =
- std::copy(move_it(pos + raw_gap), move_it(old_finish), old_start);
+ T *to_destroy = std::copy(assign_move_it(detail::get_pointer(pos) + raw_gap), assign_move_it(old_finish), old_start);
//Now destroy redundant elements except if they were moved and
//they have trivial destructor after move
size_type n_destroy = old_finish - to_destroy;
if(!base_t::trivial_dctr_after_move)
this->destroy_n(to_destroy, n_destroy);
- this->m_size -= n_destroy;
+ this->members_.m_size -= n_destroy;
}
else{
//Check if we have to do the insertion in two phases
@@ -1385,30 +1444,32 @@
//|___________|_____|_________|_____________________|
//
//Copy the first part of old_begin to raw_mem
- pointer start_n = old_start + difference_type(s_before);
- boost::interprocess::uninitialized_copy
- (move_it(old_start), move_it(start_n), new_start);
+ T *start_n = old_start + difference_type(s_before);
+ std::uninitialized_copy
+ ( copy_move_it(old_start)
+ , copy_move_it(start_n)
+ , detail::get_pointer(new_start));
//The buffer is all constructed until old_end,
//release destroyer and update size
old_values_destroyer.release();
- this->m_size = old_size + s_before;
+ this->members_.m_size = old_size + s_before;
//Now copy the second part of old_begin overwriting himself
- pointer next = std::copy(move_it(start_n), move_it(pos), old_start);
+ T* next = std::copy(assign_move_it(start_n), assign_move_it(detail::get_pointer(pos)), old_start);
if(do_after){
//Now copy the new_beg elements
- std::copy(first, before_end, next);
+ std::copy(first, before_end, detail::get_pointer(next));
}
else{
//Now copy the all the new elements
- pointer move_start = std::copy(first, last, next);
+ T* move_start = std::copy(first, last, detail::get_pointer(next));
//Now displace old_end elements
- pointer move_end = std::copy(move_it(pos), move_it(old_finish), move_start);
+ T* move_end = std::copy(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish), detail::get_pointer(move_start));
//Destroy remaining moved elements from old_end except if
//they have trivial destructor after being moved
difference_type n_destroy = s_before - n;
if(!base_t::trivial_dctr_after_move)
this->destroy_n(move_end, n_destroy);
- this->m_size -= n_destroy;
+ this->members_.m_size -= n_destroy;
}
}
else {
@@ -1438,11 +1499,13 @@
size_type n_new_init = difference_type(s_before) - elemsbefore;
std::advance(mid, n_new_init);
boost::interprocess::uninitialized_copy_copy
- (move_it(old_start), move_it(pos), first, mid, new_start);
+ ( copy_move_it(old_start)
+ , copy_move_it(detail::get_pointer(pos))
+ , first, mid, detail::get_pointer(new_start));
//The buffer is all constructed until old_end,
//release destroyer and update size
old_values_destroyer.release();
- this->m_size = old_size + s_before;
+ this->members_.m_size = old_size + s_before;
if(do_after){
//Copy new_beg part
@@ -1450,15 +1513,15 @@
}
else{
//Copy all new elements
- pointer move_start = std::copy(mid, last, old_start);
+ T* move_start = std::copy(mid, last, old_start);
//Displace old_end
- pointer move_end = std::copy(move_it(pos), move_it(old_finish), move_start);
+ T* move_end = std::copy(copy_move_it(detail::get_pointer(pos)), copy_move_it(old_finish), detail::get_pointer(move_start));
//Destroy remaining moved elements from old_end except if they
//have trivial destructor after being moved
difference_type n_destroy = s_before - n;
if(!base_t::trivial_dctr_after_move)
this->destroy_n(move_end, n_destroy);
- this->m_size -= n_destroy;
+ this->members_.m_size -= n_destroy;
}
}
@@ -1505,14 +1568,16 @@
//|__________________________|_________|________|_________|
//
//First copy the part of old_end raw_mem
- pointer finish_n = old_finish - difference_type(n_after);
- boost::interprocess::uninitialized_copy
- (move_it(finish_n), move_it(old_finish), old_finish);
- this->m_size += n_after;
+ T* finish_n = old_finish - difference_type(n_after);
+ std::uninitialized_copy
+ ( copy_move_it(detail::get_pointer(finish_n))
+ , copy_move_it(old_finish)
+ , old_finish);
+ this->members_.m_size += n_after;
//Displace the rest of old_end to the new position
- std::copy_backward(move_it(pos), move_it(finish_n), old_finish);
+ std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(detail::get_pointer(finish_n)), old_finish);
//Now overwrite with new_end
- std::copy(first, last, pos);
+ std::copy(first, last, detail::get_pointer(pos));
}
else {
//The raw_mem from end will divide new_end part
@@ -1531,10 +1596,13 @@
std::advance(mid, elemsafter);
//First initialize data in raw memory
boost::interprocess::uninitialized_copy_copy
- (mid, last, move_it(pos), move_it(old_finish), old_finish);
- this->m_size += n_after;
+ ( mid, last
+ , copy_move_it(detail::get_pointer(pos))
+ , copy_move_it(old_finish)
+ , old_finish);
+ this->members_.m_size += n_after;
//Now copy the part of new_end over constructed elements
- std::copy(first, mid, pos);
+ std::copy(first, mid, detail::get_pointer(pos));
}
}
}
@@ -1575,10 +1643,10 @@
{
size_type n = std::distance(first, last);
//Check if we have enough memory or try to expand current memory
- size_type remaining = this->m_capacity - this->m_size;
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
bool same_buffer_start;
std::pair<pointer, bool> ret;
- size_type real_cap = this->m_capacity;
+ size_type real_cap = this->members_.m_capacity;
if (n <= remaining){
same_buffer_start = true;
@@ -1588,76 +1656,76 @@
size_type new_cap = this->next_capacity(n);
ret = this->allocation_command
(allocate_new | expand_fwd | expand_bwd,
- this->size() + n, new_cap, real_cap, this->m_start);
- same_buffer_start = ret.second && this->m_start == ret.first;
+ this->size() + n, new_cap, real_cap, this->members_.m_start);
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
if(same_buffer_start){
- this->m_capacity = real_cap;
+ this->members_.m_capacity = real_cap;
}
}
if(same_buffer_start){
+ T *start = detail::get_pointer(this->members_.m_start);
if (this->size() >= n){
//There is memory, but there are more old elements than new ones
//Overwrite old elements with new ones
- copy_n(first, n, this->m_start);
+ std::copy(first, last, start);
//Destroy remaining old elements
- this->destroy_n(this->m_start + n, this->m_size - n);
- this->m_size = n;
+ this->destroy_n(start + n, this->members_.m_size - n);
+ this->members_.m_size = n;
}
else{
//There is memory, but there are less old elements than new ones
- //Overwrite old elements with new ones
+ //First overwrite some old elements with new ones
FwdIt mid = first;
std::advance(mid, this->size());
- std::copy(first, mid, this->m_start);
+ T *end = std::copy(first, mid, start);
//Initialize the remaining new elements in the uninitialized memory
- boost::interprocess::n_uninitialized_copy
- (mid, last, this->m_start + this->m_size);
- this->m_size = n;
+ std::uninitialized_copy(mid, last, end);
+ this->members_.m_size = n;
}
}
else if(!ret.second){
- dealloc_t scoped_alloc(ret.first, *this, real_cap);
- boost::interprocess::n_uninitialized_copy(first, last, ret.first);
+ UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
+ std::uninitialized_copy(first, last, detail::get_pointer(ret.first));
scoped_alloc.release();
//Destroy and deallocate old buffer
- if(this->m_start != 0){
- this->destroy_n(this->m_start, this->m_size);
- this->deallocate(this->m_start, this->m_capacity);
- }
- this->m_start = ret.first;
- this->m_size = n;
- this->m_capacity = real_cap;
+ if(this->members_.m_start != 0){
+ this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ }
+ this->members_.m_start = ret.first;
+ this->members_.m_size = n;
+ this->members_.m_capacity = real_cap;
}
else{
//Backwards expansion
//If anything goes wrong, this object will destroy
//all old objects
- typedef detail::scoped_destructor_n<allocator_type> ValueArrayDestructor;
- pointer old_start = this->m_start;
- size_type old_size = this->m_size;
- ValueArrayDestructor old_values_destroyer(old_start, old_size);
+ T *old_start = detail::get_pointer(this->members_.m_start);
+ size_type old_size = this->members_.m_size;
+ OldArrayDestructor old_values_destroyer(old_start, old_size);
//If something goes wrong size will be 0
//but holding the whole buffer
- this->m_size = 0;
- this->m_start = ret.first;
- this->m_capacity = real_cap;
+ this->members_.m_size = 0;
+ this->members_.m_start = ret.first;
+ this->members_.m_capacity = real_cap;
//Backup old buffer data
- size_type old_offset = old_start - ret.first;
+ size_type old_offset = old_start - detail::get_pointer(ret.first);
size_type first_count = min_value(n, old_offset);
- FwdIt mid = boost::interprocess::n_uninitialized_copy_n(first, first_count, ret.first);
+ FwdIt mid = boost::interprocess::n_uninitialized_copy_n
+ (first, first_count, detail::get_pointer(ret.first));
if(old_offset > n){
//All old elements will be destroyed by "old_values_destroyer"
- this->m_size = n;
+ this->members_.m_size = n;
}
else{
//We have constructed objects from the new begin until
//the old end so release the rollback destruction
old_values_destroyer.release();
- this->m_start = ret.first;
- this->m_size = first_count + old_size;
+ this->members_.m_start = ret.first;
+ this->members_.m_size = first_count + old_size;
//Now overwrite the old values
size_type second_count = min_value(old_size, n - first_count);
mid = copy_n(mid, second_count, old_start);
@@ -1666,15 +1734,17 @@
//uninitialized end
if(second_count == old_size){
boost::interprocess::n_uninitialized_copy_n
- (mid, n - first_count - second_count, old_start + old_size);
+ ( mid
+ , n - first_count - second_count
+ , old_start + old_size);
}
else{
//We have to destroy some old values
this->destroy_n
(old_start + second_count, old_size - second_count);
- this->m_size = n;
+ this->members_.m_size = n;
}
- this->m_size = n;
+ this->members_.m_size = n;
}
}
}
@@ -1706,36 +1776,6 @@
this->priv_range_insert(pos.get_ptr(), first, last, ItCat());
}
- template <class Integer>
- void priv_initialize_aux(Integer n, Integer value, detail::true_)
- {
- this->priv_range_initialize(cvalue_iterator(value, n),
- cvalue_iterator(),
- cvalue_iterator::iterator_category());
- }
-
- template <class InIt>
- void priv_initialize_aux(InIt first, InIt last,
- detail::false_)
- {
- //Dispatch depending on integer/iterator
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_range_initialize(first, last, ItCat());
- }
-
- template <class FwdIt>
- pointer priv_reserve_and_copy(size_type n, size_type &cap
- ,FwdIt first, FwdIt last)
- {
- //Allocate n element buffer and initialize from range
- pointer result = this->allocation_command(allocate_new, n, n, cap).first;
- dealloc_t scoped_alloc(result, *this, cap);
- boost::interprocess::n_uninitialized_copy(first, last, result);
- scoped_alloc.release();
- return result;
- }
-
void priv_check_range(size_type n) const
{
//If n is out of range, throw an out_of_range exception
@@ -1790,7 +1830,8 @@
#endif
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class T, class A>
struct is_movable<vector<T, A> >
{
Modified: trunk/boost/interprocess/creation_tags.hpp
==============================================================================
--- trunk/boost/interprocess/creation_tags.hpp (original)
+++ trunk/boost/interprocess/creation_tags.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -44,7 +44,7 @@
namespace detail {
enum create_enum_t
-{ DoCreate, DoOpen, DoCreateOrOpen };
+{ DoCreate, DoOpen, DoOpenOrCreate };
} //namespace detail {
Deleted: trunk/boost/interprocess/detail/basic_segment_manager.hpp
==============================================================================
--- trunk/boost/interprocess/detail/basic_segment_manager.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
+++ (empty file)
@@ -1,389 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2007. 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_BASIC_SEGMENT_MANAGER_HPP
-#define BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.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 <cstddef> //std::size_t
-#include <string> //char_traits
-#include <new> //std::nothrow
-#include <utility> //std::pair
-#ifndef BOOST_NO_EXCEPTIONS
-#include <exception>
-#endif
-
-/*!\file
- Describes the object placed in a memory segment that provides
- named object allocation capabilities for single-segment and
- multi-segment allocations.
-*/
-
-namespace boost{
-namespace interprocess{
-namespace detail{
-
-template<class MemoryAlgorithm>
-class mem_algo_deallocator
-{
- void * m_ptr;
- MemoryAlgorithm & m_algo;
-
- public:
- mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
- : m_ptr(ptr), m_algo(algo)
- {}
-
- void release()
- { m_ptr = 0; }
-
- ~mem_algo_deallocator()
- { if(m_ptr) m_algo.deallocate(m_ptr); }
-};
-
-//!An integer that describes the type of the
-//!instance constructed in memory
-enum instance_type { anonymous_type, named_type, unique_type, max_allocation_type };
-
-/// @cond
-struct block_header
-{
- std::size_t 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 allocation_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_alloc_type_sizeof_char
- ( ((unsigned char)allocation_type << 5u) |
- ((unsigned char)sizeof_char & 0x1F) )
- {};
-
-
- template<class T>
- block_header &operator= (const T& )
- { return *this; }
-
- std::size_t total_size() const
- {
- if(allocation_type() != detail::anonymous_type){
- return name_offset() + (m_num_char+1)*sizeof_char();
- }
- else{
- return value_offset() + m_value_bytes;
- }
- }
-
- template<class Header>
- std::size_t total_size_with_header() const
- {
- return get_rounded_size
- ( sizeof(Header)
- , detail::alignment_of<block_header>::value)
- + total_size();
- }
-
- std::size_t allocation_type() const
- { return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7; }
-
- std::size_t sizeof_char() const
- { return m_alloc_type_sizeof_char & (unsigned char)0x1F; }
-
- template<class CharType>
- CharType *name() const
- {
- return reinterpret_cast<CharType*>
- (detail::char_ptr_cast(this) + name_offset());
- }
-
- std::size_t name_length() const
- { return m_num_char; }
-
- std::size_t name_offset() const
- {
- return value_offset() + get_rounded_size(m_value_bytes, sizeof_char());
- }
-
- void *value() const
- {
- return detail::char_ptr_cast(this) + value_offset();
- }
-
- std::size_t value_offset() const
- {
- return get_rounded_size(sizeof(block_header), m_value_alignment);
- }
-
- template<class CharType>
- bool less(const block_header &b) const
- {
- return m_num_char < b.m_num_char ||
- (m_num_char < b.m_num_char &&
- std::char_traits<CharType>::compare
- (name<CharType>(), b.name<CharType>(), m_num_char) < 0);
- }
-
- template<class CharType>
- bool equal(const block_header &b) const
- {
- return m_num_char == b.m_num_char &&
- std::char_traits<CharType>::compare
- (name<CharType>(), b.name<CharType>(), m_num_char) == 0;
- }
-
- 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 *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
- {
- block_header * hdr =
- reinterpret_cast<block_header*>(detail::char_ptr_cast(value) -
- get_rounded_size(sizeof(block_header), algn));
- (void)sz;
- //Some sanity checks
- assert(hdr->m_value_alignment == algn);
- assert(hdr->m_value_bytes % sz == 0);
- return hdr;
- }
-
- template<class Header>
- static block_header *from_first_header(Header *header)
- {
- block_header * hdr =
- reinterpret_cast<block_header*>(detail::char_ptr_cast(header) +
- get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
- //Some sanity checks
- return hdr;
- }
-
- template<class Header>
- static Header *to_first_header(block_header *bheader)
- {
- Header * hdr =
- reinterpret_cast<Header*>(detail::char_ptr_cast(bheader) -
- get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
- //Some sanity checks
- return hdr;
- }
-};
-
-inline void array_construct(void *mem, std::size_t num, detail::in_place_interface &table)
-{
- //Try constructors
- std::size_t constructed = 0;
- BOOST_TRY{
- table.construct_n(mem, num, constructed);
- }
- //If there is an exception call destructors and erase index node
- BOOST_CATCH(...){
- std::size_t destroyed = 0;
- table.destroy_n(mem, constructed, destroyed);
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
-}
-
-template<class MemoryAlgorithm>
-class basic_segment_manager
- : private MemoryAlgorithm
-{
- public:
- typedef typename MemoryAlgorithm::void_pointer void_pointer;
- typedef typename MemoryAlgorithm::mutex_family mutex_family;
-
- MemoryAlgorithm &memory_algorithm()
- { return *this; }
-
- const MemoryAlgorithm &memory_algorithm() const
- { return *this; }
-
- enum { PayloadPerAllocation = MemoryAlgorithm::PayloadPerAllocation };
-
- basic_segment_manager(std::size_t size, std::size_t reserved_bytes)
- : MemoryAlgorithm(size, reserved_bytes)
- {
- assert((sizeof(basic_segment_manager<MemoryAlgorithm>) == sizeof(MemoryAlgorithm)));
- }
-
- //!Returns the size of the memory segment
- std::size_t get_size() const
- { return MemoryAlgorithm::get_size(); }
-
- //!Returns the number of unallocated bytes of the memory segment
- std::size_t get_free_memory() const
- { return MemoryAlgorithm::get_free_memory(); }
-
- //!Obtains the minimum size needed by the segment manager
- static std::size_t get_min_size (std::size_t size)
- { return MemoryAlgorithm::get_min_size(size); }
-
- //!Allocates nbytes bytes. This function is only used in
- //!single-segment management. Never throws
- void * allocate (std::size_t nbytes, std::nothrow_t)
- { return MemoryAlgorithm::allocate(nbytes); }
-
- //!Allocates nbytes bytes. This function is only used in
- //!single-segment management. Throws bad_alloc when fails
- void * allocate(std::size_t nbytes)
- {
- void * ret = MemoryAlgorithm::allocate(nbytes);
- if(!ret)
- throw bad_alloc();
- return ret;
- }
-
- //!Allocates nbytes bytes. This function is only used in
- //!single-segment management. Never throws
- void * allocate_aligned (std::size_t nbytes, std::size_t alignment, std::nothrow_t)
- { return MemoryAlgorithm::allocate_aligned(nbytes, alignment); }
-
- //!Allocates nbytes bytes. This function is only used in
- //!single-segment management. Throws bad_alloc when fails
- void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
- {
- void * ret = MemoryAlgorithm::allocate_aligned(nbytes, alignment);
- if(!ret)
- throw bad_alloc();
- return ret;
- }
-
- std::pair<void *, bool>
- allocation_command (allocation_type command, std::size_t limit_size,
- std::size_t preferred_size,std::size_t &received_size,
- void *reuse_ptr = 0, std::size_t backwards_multiple = 1)
- {
- std::pair<void *, bool> ret = MemoryAlgorithm::allocation_command
- ( command | nothrow_allocation, limit_size, preferred_size, received_size
- , reuse_ptr, backwards_multiple);
- if(!(command & nothrow_allocation) && !ret.first)
- throw bad_alloc();
- return ret;
- }
-
- //!Deallocates the bytes allocated with allocate/allocate_at_least()
- //!pointed by addr
- void deallocate (void *addr)
- { MemoryAlgorithm::deallocate(addr); }
-
- //!Increases managed memory in extra_size bytes more. This only works
- //!with single-segment management*
- void grow(std::size_t extra_size)
- { MemoryAlgorithm::grow(extra_size); }
-
- //!Returns the result of "all_memory_deallocated()" function
- //!of the used memory algorithm
- bool all_memory_deallocated()
- { return MemoryAlgorithm::all_memory_deallocated(); }
-
- //!Returns the result of "check_sanity()" function
- //!of the used memory algorithm
- bool check_sanity()
- { return MemoryAlgorithm::check_sanity(); }
-
- //!Writes to zero free memory (memory not yet allocated) of the memory algorithm
- void zero_free_memory()
- { MemoryAlgorithm::zero_free_memory(); }
-
- /// @cond
- protected:
- void * prot_anonymous_construct
- (std::size_t num, bool dothrow, detail::in_place_interface &table)
- {
- typedef detail::block_header block_header_t;
- block_header_t block_info ( table.size*num
- , table.alignment
- , detail::anonymous_type
- , 1
- , 0);
-
- //Allocate memory
- void *ptr_struct = this->allocate(block_info.total_size(), std::nothrow_t());
-
- //Check if there is enough memory
- if(!ptr_struct){
- if(dothrow){
- throw bad_alloc();
- }
- else{
- return 0;
- }
- }
-
- //Build scoped ptr to avoid leaks with constructor exception
- detail::mem_algo_deallocator<MemoryAlgorithm> mem(ptr_struct, *this);
-
- //Now construct the header
- block_header_t * hdr = new(ptr_struct) block_header_t(block_info);
- void *ptr = hdr->value();
-
- //Now call constructors
- detail::array_construct(ptr, num, table);
-
- //All constructors successful, we don't want erase memory
- mem.release();
- return ptr;
- }
-
- //!Calls the destructor and makes an anonymous deallocate
- bool prot_anonymous_destroy(const void *object, detail::in_place_interface &table)
- {
- if(!object)
- return false;
-
- //Get control data from associated with this object
- typedef detail::block_header block_header_t;
- block_header_t *ctrl_data = block_header_t::block_header_from_value(object, table.size, table.alignment);
-
- //-------------------------------
- //boost::interprocess::scoped_lock<rmutex> guard(m_header);
- //-------------------------------
-
- if(ctrl_data->allocation_type() != detail::anonymous_type){
- //This is not an anonymous object, the pointer is wrong!
- assert(0);
- return false;
- }
-
- //Call destructors and free memory
- //Build scoped ptr to avoid leaks with destructor exception
- std::size_t destroyed = 0;
- table.destroy_n((void*)object, ctrl_data->m_value_bytes/table.size, destroyed);
- this->deallocate(ctrl_data);
- return true;
- }
-};
-
-} //namespace detail {
-}} //namespace boost { namespace interprocess
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_BASIC_SEGMENT_MANAGER_HPP
-
Deleted: trunk/boost/interprocess/detail/gcd_lcm.hpp
==============================================================================
--- trunk/boost/interprocess/detail/gcd_lcm.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
+++ (empty file)
@@ -1,63 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Stephen Cleary 2000.
-// (C) Copyright Ion Gaztanaga 2007.
-//
-// 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.
-//
-// This file is a slightly modified file from Boost.Pool
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_DETAIL_GCD_LCM_HPP
-#define BOOST_INTERPROCESS_DETAIL_GCD_LCM_HPP
-
-namespace boost {
-namespace interprocess {
-namespace 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>
-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>
-Integer lcm(const Integer & A, const Integer & B)
-{
- Integer ret = A;
- ret /= gcd(A, B);
- ret *= B;
- return ret;
-}
-
-} // namespace detail
-} // namespace interprocess
-} // namespace boost
-
-#endif
Deleted: trunk/boost/interprocess/detail/generic_cast.hpp
==============================================================================
--- trunk/boost/interprocess/detail/generic_cast.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
+++ (empty file)
@@ -1,57 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztañaga 2005-2006. 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_GENERIC_CAST_HPP
-#define BOOST_INTERPROCESS_GENERIC_CAST_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/type_traits/is_pointer.hpp>
-
-
-namespace boost{
-namespace interprocess{
-
-template<class T>
-class cast_to;
-
-template<class T>
-class cast_to<T*>
-{
- public:
- template<class S>
- static T* using_static_cast(S *s)
- { return static_cast<T*>(s); }
-
- template<class S>
- static T* using_dynamic_cast(S *s)
- { return dynamic_cast<T*>(s); }
-
- template<class S>
- static T* using_const_cast(S *s)
- { return const_cast<T*>(s); }
-
- template<class S>
- static T* using_reinterpret_cast(S *s)
- { return reinterpret_cast<T*>(s); }
-};
-
-} //namespace interprocess{
-} //namespace boost{
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_GENERIC_CAST_HPP
-
Deleted: trunk/boost/interprocess/detail/null_create_func.hpp
==============================================================================
--- trunk/boost/interprocess/detail/null_create_func.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
+++ (empty file)
@@ -1,34 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2005-2007. 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_DETAIL_NULL_CREATION_FUNCTOR_HPP
-#define BOOST_INTERPROCESS_DETAIL_NULL_CREATION_FUNCTOR_HPP
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-namespace boost {
-namespace interprocess {
-namespace detail{
-
-/*!No-op functor*/
-struct null_func_t
-{
- bool operator()(const segment_info_t *, bool) const
- { return true; }
-};
-
-} //namespace detail{
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //BOOST_INTERPROCESS_DETAIL_NULL_CREATION_FUNCTOR_HPP
Modified: trunk/boost/interprocess/errors.hpp
==============================================================================
--- trunk/boost/interprocess/errors.hpp (original)
+++ trunk/boost/interprocess/errors.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -43,9 +43,8 @@
# endif //ifdef BOOST_HAS_UNISTD_H
#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
-/*!\file
- Describes the error numbering of interprocess classes
-*/
+//!\file
+//!Describes the error numbering of interprocess classes
namespace boost {
namespace interprocess {
Modified: trunk/boost/interprocess/exceptions.hpp
==============================================================================
--- trunk/boost/interprocess/exceptions.hpp (original)
+++ trunk/boost/interprocess/exceptions.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -21,16 +21,15 @@
#include <stdexcept>
#include <new>
-/*!\file
- Describes exceptions thrown by interprocess classes
-*/
+//!\file
+//!Describes exceptions thrown by interprocess classes
namespace boost {
namespace interprocess {
-/*!This class is the base class of all exceptions
- thrown by boost::interprocess*/
+//!This class is the base class of all exceptions
+//!thrown by boost::interprocess
class interprocess_exception : public std::exception
{
public:
@@ -79,8 +78,8 @@
/// @endcond
};
-/*!This is the exception thrown by shared interprocess_mutex family when a deadlock situation
- is detected or when using a interprocess_condition the interprocess_mutex is not locked*/
+//!This is the exception thrown by shared interprocess_mutex family when a deadlock situation
+//!is detected or when using a interprocess_condition the interprocess_mutex is not locked
class lock_exception : public interprocess_exception
{
public:
@@ -92,8 +91,8 @@
{ return "boost::interprocess::lock_exception"; }
};
-/*!This is the exception thrown by named interprocess_semaphore when a deadlock situation
- is detected or when an error is detected in the post/wait operation*/
+//!This is the exception thrown by named interprocess_semaphore when a deadlock situation
+//!is detected or when an error is detected in the post/wait operation
/*
class sem_exception : public interprocess_exception
{
@@ -106,8 +105,8 @@
{ return "boost::interprocess::sem_exception"; }
};
*/
-/*!This is the exception thrown by synchronization objects when there is
- an error in a wait() function*/
+//!This is the exception thrown by synchronization objects when there is
+//!an error in a wait() function
/*
class wait_exception : public interprocess_exception
{
@@ -117,8 +116,8 @@
};
*/
-/*!This exception is thrown when a named object is created
- in "open_only" mode and the resource was not already created*/
+//!This exception is thrown when a named object is created
+//!in "open_only" mode and the resource was not already created
/*
class not_previously_created : public interprocess_exception
{
@@ -127,7 +126,9 @@
{ return "boost::interprocess::not_previously_created"; }
};
*/
-/*!This exception is thrown when a memory request can't be fulfilled.*/
+
+//!This exception is thrown when a memory request can't be
+//!fulfilled.
class bad_alloc : public interprocess_exception
{
public:
Modified: trunk/boost/interprocess/file_mapping.hpp
==============================================================================
--- trunk/boost/interprocess/file_mapping.hpp (original)
+++ trunk/boost/interprocess/file_mapping.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,16 +23,15 @@
#include <cstdio> //std::remove
#include <string>
-/*!\file
- Describes file_mapping and mapped region classes
-*/
+//!\file
+//!Describes file_mapping and mapped region classes
namespace boost {
namespace interprocess {
-/*!A class that wraps a file-mapping that can be used to
- create mapped regions from the mapped files*/
+//!A class that wraps a file-mapping that can be used to
+//!create mapped regions from the mapped files
class file_mapping
{
/// @cond
@@ -42,18 +41,19 @@
/// @endcond
public:
- /*!Constructs an empty file mapping. Does not throw*/
+ //!Constructs an empty file mapping.
+ //!Does not throw
file_mapping();
- /*!Opens a file mapping of file "filename", starting in offset
- "file_offset", and the mapping's size will be "size". The mapping
- can be opened for read-only "read_only" or read-write "read_write"
- modes. Throws interprocess_exception on error.*/
+ //!Opens a file mapping of file "filename", starting in offset
+ //!"file_offset", and the mapping's size will be "size". The mapping
+ //!can be opened for read-only "read_only" or read-write "read_write"
+ //!modes. Throws interprocess_exception on error.
file_mapping(const char *filename, mode_t mode);
- /*!Moves the ownership of "moved"'s shared memory object to *this.
- After the call, "moved" does not represent any shared memory object.
- Does not throw*/
+ //!Moves the ownership of "moved"'s shared memory object to *this.
+ //!After the call, "moved" does not represent any shared memory object.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
file_mapping(detail::moved_object<file_mapping> &moved)
{ this->swap(moved.get()); }
@@ -62,9 +62,9 @@
{ this->swap(moved); }
#endif
- /*!Moves the ownership of "moved"'s shared memory to *this.
- After the call, "moved" does not represent any shared memory.
- Does not throw*/
+ //!Moves the ownership of "moved"'s shared memory to *this.
+ //!After the call, "moved" does not represent any shared memory.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
file_mapping &operator=
(detail::moved_object<file_mapping> &moved)
@@ -82,25 +82,29 @@
}
#endif
- /*!Swaps to file_mappings. Does not throw*/
+ //!Swaps to file_mappings.
+ //!Does not throw.
void swap(file_mapping &other);
- /*!Returns access mode*/
+ //!Returns access mode
+ //!used in the constructor
mode_t get_mode() const;
- /*!Get mapping handle*/
+ //!Obtains the mapping handle
+ //!to be used with mapped_region
mapping_handle_t get_mapping_handle() const;
- /*!Destroys the file mapping. All mapped regions created from this are still
- valid. Does not throw*/
+ //!Destroys the file mapping. All mapped regions created from this are still
+ //!valid. Does not throw
~file_mapping();
- /*!Returns the name of the file.*/
+ //!Returns the name of the file
+ //!used in the constructor.
const char *get_name() const;
/// @cond
private:
- /*!Closes a previously opened file mapping. Never throws.*/
+ //!Closes a previously opened file mapping. Never throws.
void priv_close();
file_handle_t m_handle;
mode_t m_mode;
Modified: trunk/boost/interprocess/indexes/flat_map_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/flat_map_index.hpp (original)
+++ trunk/boost/interprocess/indexes/flat_map_index.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -18,10 +18,9 @@
#include <boost/interprocess/containers/flat_map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
-/*!\file
- Describes index adaptor of boost::map container, to use it
- as name/shared memory index
-*/
+//!\file
+//!Describes index adaptor of boost::map container, to use it
+//!as name/shared memory index
//[flat_map_index
namespace boost { namespace interprocess {
Modified: trunk/boost/interprocess/indexes/iset_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/iset_index.hpp (original)
+++ trunk/boost/interprocess/indexes/iset_index.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -21,39 +21,34 @@
#include <boost/intrusive/set.hpp>
-/*!\file
- Describes index adaptor of boost::intrusive::set container, to use it
- as name/shared memory index
-*/
+//!\file
+//!Describes index adaptor of boost::intrusive::set container, to use it
+//!as name/shared memory index
-namespace boost { namespace interprocess {
+namespace boost {
+namespace interprocess {
/// @cond
-/*!Helper class to define typedefs from IndexTraits*/
+
+//!Helper class to define typedefs from IndexTraits
template <class MapConfig>
struct iset_index_aux
{
typedef typename
- MapConfig::segment_manager_base segment_manager_base;
+ MapConfig::segment_manager_base segment_manager_base;
typedef typename
- segment_manager_base::void_pointer void_pointer;
-
- typedef boost::intrusive::set_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , void_pointer> derivation_hook;
+ segment_manager_base::void_pointer void_pointer;
+ typedef typename bi::make_set_base_hook
+ <bi::void_pointer<void_pointer> >::type derivation_hook;
-// typedef typename MapConfig::intrusive_value_type intrusive_value_type;
-// typedef intrusive_value_type<derivation_hook>::type value_type;
typedef typename MapConfig::template
- intrusive_value_type<derivation_hook>::type value_type;
-
- typedef std::less<value_type> value_compare;
-
- typedef boost::intrusive::set
- <typename derivation_hook::template
- value_traits<value_type>, std::less<value_type> > index_t;
+ intrusive_value_type<derivation_hook>::type value_type;
+ typedef std::less<value_type> value_compare;
+ typedef typename bi::make_set
+ < value_type
+ , bi::base_hook<derivation_hook>
+ >::type index_t;
};
/// @endcond
@@ -107,14 +102,14 @@
public:
- /*!Constructor. Takes a pointer to the
- segment manager. Can throw*/
+ //!Constructor. Takes a pointer to the
+ //!segment manager. Can throw
iset_index(typename MapConfig::segment_manager_base *)
: index_type(/*typename index_aux::value_compare()*/)
{}
- /*!This reserves memory to optimize the insertion of n
- elements in the index*/
+ //!This reserves memory to optimize the insertion of n
+ //!elements in the index
void reserve(std::size_t)
{ /*Does nothing, map has not reserve or rehash*/ }
@@ -134,8 +129,9 @@
};
/// @cond
-/*!Trait class to detect if an index is an intrusive
- index.*/
+
+//!Trait class to detect if an index is an intrusive
+//!index.
template<class MapConfig>
struct is_intrusive_index
<boost::interprocess::iset_index<MapConfig> >
@@ -144,7 +140,8 @@
};
/// @endcond
-}} //namespace boost { namespace interprocess {
+} //namespace interprocess {
+} //namespace boost
#include <boost/interprocess/detail/config_end.hpp>
Modified: trunk/boost/interprocess/indexes/iunordered_set_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/iunordered_set_index.hpp (original)
+++ trunk/boost/interprocess/indexes/iunordered_set_index.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -41,20 +41,18 @@
typedef typename
segment_manager_base::void_pointer void_pointer;
- typedef boost::intrusive::unordered_set_base_hook
- < boost::intrusive::tag
- , boost::intrusive::safe_link
- , void_pointer> derivation_hook;
+ typedef typename bi::make_unordered_set_base_hook
+ < bi::void_pointer<void_pointer> >::type derivation_hook;
typedef typename MapConfig::template
- intrusive_value_type<derivation_hook>::type value_type;
+ intrusive_value_type<derivation_hook>::type value_type;
typedef typename MapConfig::
- intrusive_compare_key_type intrusive_compare_key_type;
+ intrusive_compare_key_type intrusive_compare_key_type;
- typedef std::equal_to<value_type> value_equal;
+ typedef std::equal_to<value_type> value_equal;
- typedef typename MapConfig::char_type char_type;
+ typedef typename MapConfig::char_type char_type;
struct equal_function
{
@@ -98,14 +96,14 @@
}
};
- typedef boost::intrusive::unordered_set
- <typename derivation_hook::template
- value_traits<value_type>, hash_function, equal_function, true> index_t;
-
- typedef typename index_t::bucket_type bucket_type;
-
+ typedef typename bi::make_unordered_set
+ < value_type
+ , bi::hash<hash_function>
+ , bi::equal<equal_function>
+ >::type index_t;
+ typedef typename index_t::bucket_type bucket_type;
typedef allocator
- <bucket_type, segment_manager_base> allocator_type;
+ <bucket_type, segment_manager_base> allocator_type;
struct allocator_holder
{
@@ -148,6 +146,7 @@
typedef typename index_type::value_type value_type;
typedef typename index_type::bucket_ptr bucket_ptr;
typedef typename index_type::bucket_type bucket_type;
+ typedef typename index_type::bucket_traits bucket_traits;
typedef typename index_type::size_type size_type;
/// @cond
@@ -176,10 +175,21 @@
return old_size;
std::size_t received_size;
if(!alloc.allocation_command
- (shrink_in_place | nothrow_allocation, old_size, new_size, received_size, buckets).first){
+ (try_shrink_in_place | nothrow_allocation, old_size, new_size, received_size, buckets).first){
return old_size;
}
+ for( bucket_type *p = detail::get_pointer(buckets) + received_size
+ , *pend = detail::get_pointer(buckets) + old_size
+ ; p != pend
+ ; ++p){
+ p->~bucket_type();
+ }
+
+ bucket_ptr shunk_p = alloc.allocation_command
+ (shrink_in_place | nothrow_allocation, received_size, received_size, received_size, buckets).first;
+ BOOST_ASSERT(buckets == shunk_p);
+
bucket_ptr buckets_init = buckets + received_size;
for(std::size_t i = 0; i < (old_size - received_size); ++i){
get_pointer(buckets_init++)->~bucket_type();
@@ -231,7 +241,7 @@
//!segment manager. Can throw
iunordered_set_index(segment_manager_base *mngr)
: allocator_holder(mngr)
- , index_type(&get_this_pointer()->init_bucket, 1)
+ , index_type(bucket_traits(&get_this_pointer()->init_bucket, 1))
{}
~iunordered_set_index()
@@ -265,7 +275,7 @@
}
//Rehashing does not throw, since neither the hash nor the
//comparison function can throw
- this->rehash(new_p, new_n);
+ this->rehash(bucket_traits(new_p, new_n));
if(new_p != old_p && old_p != bucket_ptr(&this->init_bucket)){
destroy_buckets(this->alloc, old_p, old_n);
}
@@ -275,34 +285,32 @@
//!previously allocated.
void shrink_to_fit()
{
- //size_type cur_size = this->size();
+ size_type cur_size = this->size();
size_type cur_count = this->bucket_count();
bucket_ptr old_p = this->bucket_pointer();
size_type sug_count;
if(!this->size() && old_p != bucket_ptr(&this->init_bucket)){
sug_count = 1;
- this->rehash(bucket_ptr(&this->init_bucket), 1);
+ this->rehash(bucket_traits(bucket_ptr(&this->init_bucket), 1));
destroy_buckets(this->alloc, old_p, cur_count);
}
else{
- /*
- sug_count = index_type::suggested_upper_bucket_count(cur_size);
+ sug_count = index_type::suggested_upper_bucket_count(cur_size);
- if(sug_count >= cur_count)
- return;
+ if(sug_count >= cur_count)
+ return;
- try{
- shrink_buckets(old_p, cur_count, this->alloc, sug_count);
- }
- catch(...){
- return;
- }
+ try{
+ shrink_buckets(old_p, cur_count, this->alloc, sug_count);
+ }
+ catch(...){
+ return;
+ }
- //Rehashing does not throw, since neither the hash nor the
- //comparison function can throw
- this->rehash(old_p, sug_count);
- */
+ //Rehashing does not throw, since neither the hash nor the
+ //comparison function can throw
+ this->rehash(bucket_traits(old_p, sug_count));
}
}
Modified: trunk/boost/interprocess/indexes/map_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/map_index.hpp (original)
+++ trunk/boost/interprocess/indexes/map_index.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -18,15 +18,16 @@
#include <utility>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/private_adaptive_pool.hpp>
-//#include <boost/interprocess/allocators/allocator.hpp>
-/*!\file
- Describes index adaptor of boost::map container, to use it
- as name/shared memory index
-*/
-namespace boost { namespace interprocess {
+//!\file
+//!Describes index adaptor of boost::map container, to use it
+//!as name/shared memory index
+
+namespace boost {
+namespace interprocess {
+namespace detail{
-/*!Helper class to define typedefs from IndexTraits*/
+//!Helper class to define typedefs from IndexTraits
template <class MapConfig>
struct map_index_aux
{
@@ -38,36 +39,38 @@
typedef private_adaptive_pool
<value_type,
typename MapConfig::
- segment_manager_base> allocator_type;
+ segment_manager_base> allocator_type;
typedef boost::interprocess::map
<key_type, mapped_type,
key_less, allocator_type> index_t;
};
-/*!Index type based in boost::interprocess::map. Just derives from boost::interprocess::map
- and defines the interface needed by managed memory segments*/
+} //namespace detail {
+
+//!Index type based in boost::interprocess::map. Just derives from boost::interprocess::map
+//!and defines the interface needed by managed memory segments
template <class MapConfig>
class map_index
//Derive class from map specialization
- : public map_index_aux<MapConfig>::index_t
+ : public detail::map_index_aux<MapConfig>::index_t
{
/// @cond
- typedef map_index_aux<MapConfig> index_aux;
- typedef typename index_aux::index_t base_type;
+ typedef detail::map_index_aux<MapConfig> index_aux;
+ typedef typename index_aux::index_t base_type;
typedef typename MapConfig::
segment_manager_base segment_manager_base;
/// @endcond
public:
- /*!Constructor. Takes a pointer to the
- segment manager. Can throw*/
+ //!Constructor. Takes a pointer to the
+ //!segment manager. Can throw
map_index(segment_manager_base *segment_mngr)
: base_type(typename index_aux::key_less(),
segment_mngr){}
- /*!This reserves memory to optimize the insertion of n
- elements in the index*/
+ //!This reserves memory to optimize the insertion of n
+ //!elements in the index
void reserve(std::size_t)
{ /*Does nothing, map has not reserve or rehash*/ }
@@ -78,9 +81,10 @@
};
/// @cond
-/*!Trait class to detect if an index is a node
- index. This allows more efficient operations
- when deallocating named objects.*/
+
+//!Trait class to detect if an index is a node
+//!index. This allows more efficient operations
+//!when deallocating named objects.
template<class MapConfig>
struct is_node_index
<boost::interprocess::map_index<MapConfig> >
Modified: trunk/boost/interprocess/indexes/null_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/null_index.hpp (original)
+++ trunk/boost/interprocess/indexes/null_index.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -15,14 +15,16 @@
#include <boost/interprocess/offset_ptr.hpp>
-/*!\file
- Describes a null index adaptor, so that if we don't want to construct
- named objects, we can use this null index type to save resources.
-*/
-
-namespace boost { namespace interprocess {
-
-/*!Null index type*/
+//!\file
+//!Describes a null index adaptor, so that if we don't want to construct
+//!named objects, we can use this null index type to save resources.
+
+namespace boost {
+namespace interprocess {
+
+//!Null index type
+//!used to save compilation time when
+//!named indexes are not needed.
template <class MapConfig>
class null_index
{
@@ -35,19 +37,27 @@
typedef void * iterator;
typedef const void * const_iterator;
+ //!begin() is equal
+ //!to end()
const_iterator begin() const
{ return const_iterator(0); }
+ //!begin() is equal
+ //!to end()
iterator begin()
{ return iterator(0); }
+ //!begin() is equal
+ //!to end()
const_iterator end() const
{ return const_iterator(0); }
+ //!begin() is equal
+ //!to end()
iterator end()
{ return iterator(0); }
- /*!Dummy function*/
+ //!Empty constructor
null_index(segment_manager_base *){}
};
Modified: trunk/boost/interprocess/indexes/unordered_map_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/unordered_map_index.hpp (original)
+++ trunk/boost/interprocess/indexes/unordered_map_index.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -20,14 +20,15 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/allocators/private_adaptive_pool.hpp>
-/*!\file
- Describes index adaptor of boost::unordered_map container, to use it
- as name/shared memory index
-*/
+//!\file
+//!Describes index adaptor of boost::unordered_map container, to use it
+//!as name/shared memory index
-namespace boost { namespace interprocess {
+namespace boost {
+namespace interprocess {
-/*!Helper class to define typedefs from IndexTraits*/
+//!Helper class to define typedefs from
+//!IndexTraits
template <class MapConfig>
struct unordered_map_index_aux
{
@@ -54,8 +55,8 @@
key_equal, allocator_type> index_t;
};
-/*!Index type based in unordered_map. Just derives from unordered_map and
- defines the interface needed by managed memory segments*/
+//!Index type based in unordered_map. Just derives from unordered_map and
+//!defines the interface needed by managed memory segments
template <class MapConfig>
class unordered_map_index
//Derive class from unordered_map specialization
@@ -69,16 +70,16 @@
/// @endcond
public:
- /*!Constructor. Takes a pointer to the
- segment manager. Can throw*/
+ //!Constructor. Takes a pointer to the
+ //!segment manager. Can throw
unordered_map_index(segment_manager_base *segment_mngr)
: base_type(0,
typename index_aux::hasher(),
typename index_aux::key_equal(),
segment_mngr){}
- /*!This reserves memory to optimize the insertion of n
- elements in the index*/
+ //!This reserves memory to optimize the insertion of n
+ //!elements in the index
void reserve(std::size_t n)
{ base_type::rehash(n); }
@@ -89,9 +90,10 @@
};
/// @cond
-/*!Trait class to detect if an index is a node
- index. This allows more efficient operations
- when deallocating named objects.*/
+
+//!Trait class to detect if an index is a node
+//!index. This allows more efficient operations
+//!when deallocating named objects.
template<class MapConfig>
struct is_node_index
<boost::interprocess::unordered_map_index<MapConfig> >
Modified: trunk/boost/interprocess/interprocess_fwd.hpp
==============================================================================
--- trunk/boost/interprocess/interprocess_fwd.hpp (original)
+++ trunk/boost/interprocess/interprocess_fwd.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -24,6 +24,17 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
+/// @cond
+
+namespace boost{
+namespace intrusive{
+}}
+
+namespace boost{
+namespace interprocess{
+namespace bi = boost::intrusive;
+}}
+
namespace std {
template <class T>
@@ -40,6 +51,8 @@
} //namespace std {
+/// @endcond
+
namespace boost { namespace interprocess {
//////////////////////////////////////////////////////////////////////////////
@@ -134,44 +147,26 @@
class offset_ptr;
//////////////////////////////////////////////////////////////////////////////
-// intersegment_ptr
-//////////////////////////////////////////////////////////////////////////////
-
-template <class Mutex>
-struct flat_map_intersegment;
-
-template <class T/*, class PT = flat_map_intersegment<interprocess_mutex> */>
-class intersegment_ptr;
-
-//////////////////////////////////////////////////////////////////////////////
// Memory allocation algorithms
//////////////////////////////////////////////////////////////////////////////
//Single segment memory allocation algorithms
template<class MutexFamily, class VoidMutex = offset_ptr<void> >
-class seq_fit;
-
-template<class MutexFamily, class VoidMutex = offset_ptr<void> >
class simple_seq_fit;
template<class MutexFamily, class VoidMutex = offset_ptr<void> >
class rbtree_best_fit;
-//Single segment memory allocation algorithms
-template<class MutexFamily, class VoidMutex = intersegment_ptr<void> >
-class multi_seq_fit;
-
-template<class MutexFamily, class VoidMutex = intersegment_ptr<void> >
-class multi_simple_seq_fit;
-
//////////////////////////////////////////////////////////////////////////////
// Index Types
//////////////////////////////////////////////////////////////////////////////
template<class IndexConfig> class flat_map_index;
-template<class IndexConfig> class map_index;
template<class IndexConfig> class iset_index;
+template<class IndexConfig> class iunordered_set_index;
+template<class IndexConfig> class map_index;
template<class IndexConfig> class null_index;
+template<class IndexConfig> class unordered_map_index;
//////////////////////////////////////////////////////////////////////////////
// Segment manager
@@ -204,7 +199,7 @@
wmanaged_external_buffer;
//////////////////////////////////////////////////////////////////////////////
-// Shared memory managed memory classes
+// managed memory classes
//////////////////////////////////////////////////////////////////////////////
template <class CharType
@@ -369,6 +364,12 @@
template<class T, class VoidPointer>
class intrusive_ptr;
+template<class T, class VoidAllocator, class Deleter>
+class shared_ptr;
+
+template<class T, class VoidAllocator, class Deleter>
+class weak_ptr;
+
//////////////////////////////////////////////////////////////////////////////
// IPC
//////////////////////////////////////////////////////////////////////////////
Modified: trunk/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- trunk/boost/interprocess/ipc/message_queue.hpp (original)
+++ trunk/boost/interprocess/ipc/message_queue.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -30,15 +30,15 @@
#include <cstring> //memcpy
-/*!\file
- Describes an inter-process message queue. This class allows sending
- messages between processes and allows blocking, non-blocking and timed
- sending and receiving.
-*/
+//!\file
+//!Describes an inter-process message queue. This class allows sending
+//!messages between processes and allows blocking, non-blocking and timed
+//!sending and receiving.
namespace boost{ namespace interprocess{
-/*!A class that allows sending messages between processes.*/
+//!A class that allows sending messages
+//!between processes.
class message_queue
{
/// @cond
@@ -50,94 +50,101 @@
public:
- /*!Creates a process shared message queue with name "name". For this message queue,
- the maximum number of messages will be "max_num_msg" and the maximum message size
- will be "max_msg_size".*/
+ //!Creates a process shared message queue with name "name". For this message queue,
+ //!the maximum number of messages will be "max_num_msg" and the maximum message size
+ //!will be "max_msg_size".
message_queue(create_only_t create_only,
const char *name,
std::size_t max_num_msg,
std::size_t max_msg_size);
- /*!Opens or creates a process shared message queue with name "name".
- If the queue is created, the maximum number of messages will be "max_num_msg"
- and the maximum message size will be "max_msg_size". If queue was previously
- created the queue will be opened and "max_num_msg" and "max_msg_size" parameters
- are ignored.*/
+ //!Opens or creates a process shared message queue with name "name".
+ //!If the queue is created, the maximum number of messages will be "max_num_msg"
+ //!and the maximum message size will be "max_msg_size". If queue was previously
+ //!created the queue will be opened and "max_num_msg" and "max_msg_size" parameters
+ //!are ignored.
message_queue(open_or_create_t open_or_create,
const char *name,
std::size_t max_num_msg,
std::size_t max_msg_size);
- /*!Opens a previously created process shared message queue with name "name".
- If the was not previously created or there are no free resources, the
- function returns false.*/
+ //!Opens a previously created process shared message queue with name "name".
+ //!If the was not previously created or there are no free resources, the
+ //!function returns false.
message_queue(open_only_t open_only,
const char *name);
- /*!Destructor. Never throws*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. All opened message queues are still
+ //!valid after destruction. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the message queue from the system
+ //!use remove().
~message_queue();
- /*!Sends a message stored in buffer "buffer" with size "buffer_size" in the
- message queue with priority "priority". If the message queue is full
- the sender is blocked. Throws interprocess_error on error.*/
+ //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
+ //!message queue with priority "priority". If the message queue is full
+ //!the sender is blocked. Throws interprocess_error on error.*/
void send (const void *buffer, std::size_t buffer_size,
unsigned int priority);
- /*!Sends a message stored in buffer "buffer" with size "buffer_size" through the
- message queue with priority "priority". If the message queue is full
- the sender is not blocked and returns false, otherwise returns true.
- Throws interprocess_error on error.*/
+ //!Sends a message stored in buffer "buffer" with size "buffer_size" through the
+ //!message queue with priority "priority". If the message queue is full
+ //!the sender is not blocked and returns false, otherwise returns true.
+ //!Throws interprocess_error on error.
bool try_send (const void *buffer, std::size_t buffer_size,
unsigned int priority);
- /*!Sends a message stored in buffer "buffer" with size "buffer_size" in the
- message queue with priority "priority". If the message queue is full
- the sender is retries until time "abs_time" is reached. Returns true if
- the message has been successfully sent. Returns false if timeout is reached.
- Throws interprocess_error on error.*/
+ //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
+ //!message queue with priority "priority". If the message queue is full
+ //!the sender is retries until time "abs_time" is reached. Returns true if
+ //!the message has been successfully sent. Returns false if timeout is reached.
+ //!Throws interprocess_error on error.
bool timed_send (const void *buffer, std::size_t buffer_size,
unsigned int priority, const boost::posix_time::ptime& abs_time);
- /*!Receives a message from the message queue. The message is stored in buffer
- "buffer", which has size "buffer_size". The received message has size
- "recvd_size" and priority "priority". If the message queue is full
- the sender is blocked. Throws interprocess_error on error.*/
+ //!Receives a message from the message queue. The message is stored in buffer
+ //!"buffer", which has size "buffer_size". The received message has size
+ //!"recvd_size" and priority "priority". If the message queue is full
+ //!the sender is blocked. Throws interprocess_error on error.
void receive (void *buffer, std::size_t buffer_size,
std::size_t &recvd_size,unsigned int &priority);
- /*!Receives a message from the message queue. The message is stored in buffer
- "buffer", which has size "buffer_size". The received message has size
- "recvd_size" and priority "priority". If the message queue is full
- the sender is not blocked and returns false, otherwise returns true.
- Throws interprocess_error on error.*/
+ //!Receives a message from the message queue. The message is stored in buffer
+ //!"buffer", which has size "buffer_size". The received message has size
+ //!"recvd_size" and priority "priority". If the message queue is full
+ //!the sender is not blocked and returns false, otherwise returns true.
+ //!Throws interprocess_error on error.
bool try_receive (void *buffer, std::size_t buffer_size,
std::size_t &recvd_size,unsigned int &priority);
- /*!Receives a message from the message queue. The message is stored in buffer
- "buffer", which has size "buffer_size". The received message has size
- "recvd_size" and priority "priority". If the message queue is full
- the sender is retries until time "abs_time" is reached. Returns true if
- the message has been successfully sent. Returns false if timeout is reached.
- Throws interprocess_error on error.*/
+ //!Receives a message from the message queue. The message is stored in buffer
+ //!"buffer", which has size "buffer_size". The received message has size
+ //!"recvd_size" and priority "priority". If the message queue is full
+ //!the sender is retries until time "abs_time" is reached. Returns true if
+ //!the message has been successfully sent. Returns false if timeout is reached.
+ //!Throws interprocess_error on error.
bool timed_receive (void *buffer, std::size_t buffer_size,
std::size_t &recvd_size,unsigned int &priority,
const boost::posix_time::ptime &abs_time);
- /*!Returns the maximum number of messages allowed by the queue. The message
- queue must be opened or created previously. Otherwise, returns 0.
- Never throws*/
+ //!Returns the maximum number of messages allowed by the queue. The message
+ //!queue must be opened or created previously. Otherwise, returns 0.
+ //!Never throws
std::size_t get_max_msg() const;
- /*!Returns the maximum size of message allowed by the queue. The message
- queue must be opened or created previously. Otherwise, returns 0.
- Never throws*/
+ //!Returns the maximum size of message allowed by the queue. The message
+ //!queue must be opened or created previously. Otherwise, returns 0.
+ //!Never throws
std::size_t get_max_msg_size() const;
- /*!Returns the number of messages currently stored.
- Never throws*/
+ //!Returns the number of messages currently stored.
+ //!Never throws
std::size_t get_num_msg();
- /*!Removes the message queue from the system. Never throws*/
+ //!Removes the message queue from the system.
+ //!Returns false on error. Never throws
static bool remove(const char *name);
/// @cond
@@ -152,7 +159,8 @@
const void *buffer, std::size_t buffer_size,
unsigned int priority, const ptime &abs_time);
- /*!Returns the needed memory size for the shared message queue. Never throws*/
+ //!Returns the needed memory size for the shared message queue.
+ //!Never throws
static std::size_t get_mem_size(std::size_t max_msg_size, std::size_t max_num_msg);
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
@@ -163,17 +171,17 @@
namespace detail {
-/*!This header is the prefix of each message in the queue*/
+//!This header is the prefix of each message in the queue
class msg_hdr_t
{
public:
std::size_t len; // Message length
unsigned int priority;// Message priority
- /*!Returns the data buffer associated with this this message*/
+ //!Returns the data buffer associated with this this message
void * data(){ return this+1; } //
};
-/*!This functor is the predicate to order stored messages by priority*/
+//!This functor is the predicate to order stored messages by priority
class priority_functor
{
public:
@@ -182,75 +190,74 @@
{ return msg1->priority < msg2->priority; }
};
-/*!This header is placed in the beginning of the shared memory and contains
- the data to control the queue. This class initializes the shared memory
- in the following way: in ascending memory address with proper alignment
- fillings:
-
- -> mq_hdr_t:
- Main control block that controls the rest of the elements
-
- -> offset_ptr<msg_hdr_t> index [max_num_msg]
- An array of pointers with size "max_num_msg" called index. Each pointer
- points to a preallocated message. The elements of this array are
- reordered in runtime in the following way:
-
- When the current number of messages is "cur_num_msg", the first
- "cur_num_msg" pointers point to inserted messages and the rest
- point to free messages. The first "cur_num_msg" pointers are
- ordered by the priority of the pointed message and by insertion order
- if two messages have the same priority. So the next message to be
- used in a "receive" is pointed by index [cur_num_msg-1] and the first free
- message ready to be used in a "send" operation is index [cur_num_msg].
- This transforms index in a fixed size priority queue with an embedded free
- message queue.
-
- -> struct message_t
- {
- msg_hdr_t header;
- char[max_msg_size] data;
- } messages [max_num_msg];
-
- An array of buffers of preallocated messages, each one prefixed with the
- msg_hdr_t structure. Each of this message is pointed by one pointer of
- the index structure.
-*/
+//!This header is placed in the beginning of the shared memory and contains
+//!the data to control the queue. This class initializes the shared memory
+//!in the following way: in ascending memory address with proper alignment
+//!fillings:
+//!
+//!-> mq_hdr_t:
+//! Main control block that controls the rest of the elements
+//!
+//!-> offset_ptr<msg_hdr_t> index [max_num_msg]
+//! An array of pointers with size "max_num_msg" called index. Each pointer
+//! points to a preallocated message. The elements of this array are
+//! reordered in runtime in the following way:
+//!
+//! When the current number of messages is "cur_num_msg", the first
+//! "cur_num_msg" pointers point to inserted messages and the rest
+//! point to free messages. The first "cur_num_msg" pointers are
+//! ordered by the priority of the pointed message and by insertion order
+//! if two messages have the same priority. So the next message to be
+//! used in a "receive" is pointed by index [cur_num_msg-1] and the first free
+//! message ready to be used in a "send" operation is index [cur_num_msg].
+//! This transforms index in a fixed size priority queue with an embedded free
+//! message queue.
+//!
+//!-> struct message_t
+//! {
+//! msg_hdr_t header;
+//! char[max_msg_size] data;
+//! } messages [max_num_msg];
+//!
+//! An array of buffers of preallocated messages, each one prefixed with the
+//! msg_hdr_t structure. Each of this message is pointed by one pointer of
+//! the index structure.
class mq_hdr_t
: public detail::priority_functor
{
typedef offset_ptr<msg_hdr_t> msg_hdr_ptr_t;
public:
- /*!Constructor. This object must be constructed in the beginning of the
- shared memory of the size returned by the function "get_mem_size".
- This constructor initializes the needed resources and creates
- the internal structures like the priority index. This can throw.*/
+ //!Constructor. This object must be constructed in the beginning of the
+ //!shared memory of the size returned by the function "get_mem_size".
+ //!This constructor initializes the needed resources and creates
+ //!the internal structures like the priority index. This can throw.*/
mq_hdr_t(std::size_t max_num_msg, std::size_t max_msg_size)
: m_max_num_msg(max_num_msg),
m_max_msg_size(max_msg_size),
m_cur_num_msg(0)
{ this->initialize_memory(); }
- /*!Returns the inserted message with top priority*/
+ //!Returns the inserted message with top priority
msg_hdr_t * top_msg()
{ return mp_index[m_cur_num_msg-1].get(); }
- /*!Returns true if the message queue is full*/
+ //!Returns true if the message queue is full
bool is_full() const
{ return m_cur_num_msg == m_max_num_msg; }
- /*!Returns true if the message queue is empty*/
+ //!Returns true if the message queue is empty
bool is_empty() const
{ return !m_cur_num_msg; }
- /*!Frees the top priority message and saves it in the free message list*/
+ //!Frees the top priority message and saves it in the free message list
void free_top_msg()
{ --m_cur_num_msg; }
- /*!Returns the first free msg of the free message queue*/
+ //!Returns the first free msg of the free message queue
msg_hdr_t * free_msg()
{ return mp_index[m_cur_num_msg].get(); }
- /*!Inserts the first free message in the priority queue*/
+ //!Inserts the first free message in the priority queue
void queue_free_msg()
{
//Get free msg
@@ -266,9 +273,9 @@
++m_cur_num_msg;
}
- /*!Returns the number of bytes needed to construct a message queue with
- "max_num_size" maximum number of messages and "max_msg_size" maximum
- message size. Never throws.*/
+ //!Returns the number of bytes needed to construct a message queue with
+ //!"max_num_size" maximum number of messages and "max_msg_size" maximum
+ //!message size. Never throws.
static std::size_t get_mem_size
(std::size_t max_msg_size, std::size_t max_num_msg)
{
@@ -282,8 +289,8 @@
detail::managed_open_or_create_impl<shared_memory_object>::ManagedOpenOrCreateUserOffset;
}
- /*!Initializes the memory structures to preallocate messages and constructs the
- message index. Never throws.*/
+ //!Initializes the memory structures to preallocate messages and constructs the
+ //!message index. Never throws.
void initialize_memory()
{
const std::size_t
@@ -330,8 +337,8 @@
};
-/*!This is the atomic functor to be executed when creating or opening
- shared memory. Never throws*/
+//!This is the atomic functor to be executed when creating or opening
+//!shared memory. Never throws
class initialization_func_t
{
public:
@@ -384,11 +391,6 @@
detail::initialization_func_t (max_num_msg, max_msg_size))
{}
- /*!Opens or creates a process shared message queue with name "name".
- If the queue is created, the maximum number of messages will be "max_num_msg"
- and the maximum message size will be "max_msg_size". If queue was previously
- created the queue will be opened and "max_num_msg" and "max_msg_size" parameters
- are ignored. If there are no free resources, the function returns false.*/
inline message_queue::message_queue(open_or_create_t open_or_create,
const char *name,
std::size_t max_num_msg,
@@ -403,9 +405,6 @@
detail::initialization_func_t (max_num_msg, max_msg_size))
{}
- /*!Opens a previously created process shared message queue with name "name".
- If the was not previously created or there are no free resources, the
- function returns false.*/
inline message_queue::message_queue(open_only_t open_only,
const char *name)
//Create shared memory and execute functor atomically
Modified: trunk/boost/interprocess/managed_external_buffer.hpp
==============================================================================
--- trunk/boost/interprocess/managed_external_buffer.hpp (original)
+++ trunk/boost/interprocess/managed_external_buffer.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -21,9 +21,8 @@
#include <boost/interprocess/detail/managed_memory_impl.hpp>
#include <boost/interprocess/detail/move.hpp>
-/*!\file
- Describes a named user memory allocation user class.
-*/
+//!\file
+//!Describes a named user memory allocation user class.
namespace boost {
namespace interprocess {
@@ -60,7 +59,7 @@
(open_only_t, void *addr, std::size_t size)
{
if(!base_t::open_impl(addr, size)){
- throw interprocess_exception();//return false;
+ throw interprocess_exception();
}
}
Modified: trunk/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_heap_memory.hpp (original)
+++ trunk/boost/interprocess/managed_heap_memory.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,9 +23,8 @@
#include <boost/interprocess/detail/managed_memory_impl.hpp>
#include <boost/detail/no_exceptions_support.hpp>
-/*!\file
- Describes a named heap memory allocation user class.
-*/
+//!\file
+//!Describes a named heap memory allocation user class.
namespace boost {
namespace interprocess {
@@ -85,7 +84,8 @@
//!Constructor. Never throws.
basic_managed_heap_memory(){}
- //!Destructor. Calls priv_close. Never throws.
+ //!Destructor. Liberates the heap memory holding the managed data.
+ //!Never throws.
~basic_managed_heap_memory()
{ this->priv_close(); }
Modified: trunk/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- trunk/boost/interprocess/managed_mapped_file.hpp (original)
+++ trunk/boost/interprocess/managed_mapped_file.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,18 +23,15 @@
#include <boost/interprocess/detail/file_wrapper.hpp>
#include <boost/interprocess/detail/move.hpp>
-/*!\file
- Describes a named shared memory object allocation user class.
-*/
+//!\file
+//!Describes a named shared memory object allocation user class.
namespace boost {
-
namespace interprocess {
-
-/*!A basic shared memory named object creation class. Initializes the
- shared memory segment. Inherits all basic functionality from
- basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
+//!A basic shared memory named object creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
+//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>
template
<
class CharType,
@@ -57,28 +54,29 @@
/// @endcond
public: //functions
- /*!Creates shared memory and creates and places the segment manager.
- This can throw.*/
+
+ //!Creates shared memory and creates and places the segment manager.
+ //!This can throw.
basic_managed_mapped_file(create_only_t create_only, const char *name,
std::size_t size, const void *addr = 0)
: m_mfile(create_only, name, size, read_write, addr,
create_open_func_t(get_this_pointer(), detail::DoCreate))
{}
- /*!Creates shared memory and creates and places the segment manager if
- segment was not created. If segment was created it connects to the
- segment.
- This can throw.*/
+ //!Creates shared memory and creates and places the segment manager if
+ //!segment was not created. If segment was created it connects to the
+ //!segment.
+ //!This can throw.
basic_managed_mapped_file (open_or_create_t open_or_create,
const char *name, std::size_t size,
const void *addr = 0)
: m_mfile(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoCreateOrOpen))
+ detail::DoOpenOrCreate))
{}
- /*!Connects to a created shared memory and it's the segment manager.
- Never throws.*/
+ //!Connects to a created shared memory and it's the segment manager.
+ //!Never throws.
basic_managed_mapped_file (open_only_t open_only, const char* name,
const void *addr = 0)
: m_mfile(open_only, name, read_write, addr,
@@ -86,7 +84,8 @@
detail::DoOpen))
{}
- /*!Moves the ownership of "moved"'s managed memory to *this. Does not throw*/
+ //!Moves the ownership of "moved"'s managed memory to *this.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_managed_mapped_file
(detail::moved_object<basic_managed_mapped_file> &moved)
@@ -96,7 +95,8 @@
{ this->swap(moved); }
#endif
- /*!Moves the ownership of "moved"'s managed memory to *this. Does not throw*/
+ //!Moves the ownership of "moved"'s managed memory to *this.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_managed_mapped_file &operator=
(detail::moved_object<basic_managed_mapped_file> &moved)
@@ -106,30 +106,36 @@
{ this->swap(moved); return *this; }
#endif
- /*!Destructor. Never throws.*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~basic_managed_mapped_file()
{}
- /*!Swaps the ownership of the managed mapped memories managed by *this and other.
- Never throws.*/
+ //!Swaps the ownership of the managed mapped memories managed by *this and other.
+ //!Never throws.
void swap(basic_managed_mapped_file &other)
{
base_t::swap(other);
m_mfile.swap(other.m_mfile);
}
- /*!Flushes cached data to file. Never throws*/
+ //!Flushes cached data to file.
+ //!Never throws
bool flush()
{ return m_mfile.flush(); }
- /*!Tries to resize mapped file so that we have room for
- more objects.
- WARNING: The memory mapping can change. To be able to use
- this function, all pointers constructed in this buffer
- must be offset pointers. Otherwise, the result is undefined.
- Returns true if the growth has been successful, so you will
- have some extra bytes to allocate new objects. If returns
- false, the heap allocation has failed.*/
+ //!Tries to resize mapped file so that we have room for
+ //!more objects.
+ //!WARNING: The memory mapping can change. To be able to use
+ //!this function, all pointers constructed in this buffer
+ //!must be offset pointers. Otherwise, the result is undefined.
+ //!Returns true if the growth has been successful, so you will
+ //!have some extra bytes to allocate new objects. If returns
+ //!false, the heap allocation has failed.
/*
bool grow(std::size_t extra_bytes)
{
Modified: trunk/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_shared_memory.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,17 +23,16 @@
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/creation_tags.hpp>
-/*!\file
- Describes a named shared memory object allocation user class.
-*/
+//!\file
+//!Describes a named shared memory object allocation user class.
namespace boost {
namespace interprocess {
-/*!A basic shared memory named object creation class. Initializes the
- shared memory segment. Inherits all basic functionality from
- basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
+//!A basic shared memory named object creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
+//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>*/
template
<
class CharType,
@@ -59,7 +58,13 @@
/// @endcond
public: //functions
- //!Destructor. Calls close. Never throws.
+
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~basic_managed_shared_memory()
{}
@@ -82,7 +87,7 @@
: base_t()
, base2_t(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoCreateOrOpen))
+ detail::DoOpenOrCreate))
{}
//!Connects to a created shared memory and it's the segment manager.
@@ -95,7 +100,8 @@
detail::DoOpen))
{}
- //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
+ //!Moves the ownership of "moved"'s managed memory to *this.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_managed_shared_memory
(detail::moved_object<basic_managed_shared_memory> &moved)
@@ -105,7 +111,8 @@
{ this->swap(moved); }
#endif
- //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
+ //!Moves the ownership of "moved"'s managed memory to *this.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_managed_shared_memory &operator=
(detail::moved_object<basic_managed_shared_memory> &moved)
Modified: trunk/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_windows_shared_memory.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,25 +23,23 @@
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/detail/move.hpp>
-/*!\file
- Describes a named shared memory object allocation user class.
-*/
+//!\file
+//!Describes a named shared memory object allocation user class.
namespace boost {
namespace interprocess {
-/*!A basic managed windows shared memory creation class. Initializes the
- shared memory segment. Inherits all basic functionality from
- basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>
- Unlike basic_managed_shared_memory, it has
- no kernel persistence and the shared memory is destroyed
- when all processes destroy all their windows_shared_memory
- objects and mapped regions for the same shared memory
- or the processes end/crash.
-
- Warning: basic_managed_windows_shared_memory and
- basic_managed_shared_memory can't communicate between them.
-*/
+//!A basic managed windows shared memory creation class. Initializes the
+//!shared memory segment. Inherits all basic functionality from
+//!basic_managed_memory_impl<CharType, AllocationAlgorithm, IndexType>
+//!Unlike basic_managed_shared_memory, it has
+//!no kernel persistence and the shared memory is destroyed
+//!when all processes destroy all their windows_shared_memory
+//!objects and mapped regions for the same shared memory
+//!or the processes end/crash.
+//!
+//!Warning: basic_managed_windows_shared_memory and
+//!basic_managed_shared_memory can't communicate between them.
template
<
class CharType,
@@ -83,7 +81,7 @@
const void *addr = 0)
: m_wshm(open_or_create, name, size, read_write, addr,
create_open_func_t(get_this_pointer(),
- detail::DoCreateOrOpen))
+ detail::DoOpenOrCreate))
{}
//!Connects to a created shared memory and it's the segment manager.
@@ -95,7 +93,8 @@
detail::DoOpen))
{}
- //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
+ //!Moves the ownership of "moved"'s managed memory to *this.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_managed_windows_shared_memory
(detail::moved_object<basic_managed_windows_shared_memory> &moved)
@@ -105,7 +104,8 @@
{ this->swap(moved); }
#endif
- //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
+ //!Moves the ownership of "moved"'s managed memory to *this.
+ //!Does not throw
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
basic_managed_windows_shared_memory &operator=
(detail::moved_object<basic_managed_windows_shared_memory> &moved)
@@ -116,7 +116,11 @@
{ this->swap(moved); return *this; }
#endif
- //!Destructor. Never throws.
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. All mapped regions are still valid after
+ //!destruction. When all mapped regions and basic_managed_windows_shared_memory
+ //!objects referring the shared memory are destroyed, the
+ //!operating system will destroy the shared memory.
~basic_managed_windows_shared_memory()
{}
Modified: trunk/boost/interprocess/mapped_region.hpp
==============================================================================
--- trunk/boost/interprocess/mapped_region.hpp (original)
+++ trunk/boost/interprocess/mapped_region.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -36,15 +36,14 @@
#endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
-/*!\file
- Describes memory_mappable and mapped region classes
-*/
+//!\file
+//!Describes memory_mappable and mapped region classes
namespace boost {
namespace interprocess {
-/*!The mapped_region class represents a portion or region created from a
- memory_mappable object.*/
+//!The mapped_region class represents a portion or region created from a
+//!memory_mappable object.
class mapped_region
{
/// @cond
@@ -55,10 +54,10 @@
public:
- /*!Creates a mapping region of the mapped memory "mapping", starting in
- offset "offset", and the mapping's size will be "size". The mapping
- can be opened for read-only "read_only" or read-write
- "read_write.*/
+ //!Creates a mapping region of the mapped memory "mapping", starting in
+ //!offset "offset", and the mapping's size will be "size". The mapping
+ //!can be opened for read-only "read_only" or read-write
+ //!"read_write.
template<class MemoryMappable>
mapped_region(const MemoryMappable& mapping
,mode_t mode
@@ -66,54 +65,58 @@
,std::size_t size = 0
,const void *address = 0);
- /*!Default constructor. Address and size and offset will be 0. Does not throw*/
+ //!Default constructor. Address and size and offset will be 0.
+ //!Does not throw
mapped_region();
- /*!Move constructor. *this will be constructed taking ownership of "other"'s
- region and "other" will be left in default constructor state.*/
+ //!Move constructor. *this will be constructed taking ownership of "other"'s
+ //!region and "other" will be left in default constructor state.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
mapped_region(detail::moved_object<mapped_region> other);
#else
mapped_region(mapped_region &&other);
#endif
- /*!Destroys the mapped region. Does not throw*/
+ //!Destroys the mapped region.
+ //!Does not throw
~mapped_region();
- /*!Move assignment. If *this owns a memory mapped region, it will be
- destroyed and it will take ownership of "other"'s memory mapped region.*/
+ //!Move assignment. If *this owns a memory mapped region, it will be
+ //!destroyed and it will take ownership of "other"'s memory mapped region.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
mapped_region &operator=(detail::moved_object<mapped_region> other);
#else
mapped_region &operator=(mapped_region &&other);
#endif
- /*!Returns the size of the mapping. Note for windows users: If
- windows_shared_memory is mapped using 0 as the size, it returns 0
- because the size is unknown. Never throws.*/
+ //!Returns the size of the mapping. Note for windows users: If
+ //!windows_shared_memory is mapped using 0 as the size, it returns 0
+ //!because the size is unknown. Never throws.
std::size_t get_size() const;
- /*!Returns the base address of the mapping. Never throws.*/
+ //!Returns the base address of the mapping.
+ //!Never throws.
void* get_address() const;
- /*!Returns the offset of the mapping from the beginning of the
- mapped memory. Never throws.*/
+ //!Returns the offset of the mapping from the beginning of the
+ //!mapped memory. Never throws.
offset_t get_offset() const;
- /*!Flushes to the disk a byte range within the mapped memory.
- Never throws*/
+ //!Flushes to the disk a byte range within the mapped memory.
+ //!Never throws
bool flush(std::size_t mapping_offset = 0, std::size_t numbytes = 0);
- /*!Swaps the mapped_region with another mapped region*/
+ //!Swaps the mapped_region with another
+ //!mapped region
void swap(mapped_region &other);
- /*!Returns the size of the page. This size is the minimum memory that
- will be used by the system when mapping a memory mappable source.*/
+ //!Returns the size of the page. This size is the minimum memory that
+ //!will be used by the system when mapping a memory mappable source.
static std::size_t get_page_size();
/// @cond
private:
- /*!Closes a previously opened memory mapping. Never throws.*/
+ //!Closes a previously opened memory mapping. Never throws
void priv_close();
template<int dummy>
@@ -521,7 +524,8 @@
}
/// @cond
-/*!No-op functor*/
+
+//!No-op functor
struct null_mapped_region_function
{
bool operator()(void *, std::size_t , bool) const
Added: trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,498 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2007. 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_DETAIL_MEM_ALGO_COMMON_HPP
+#define BOOST_INTERPROCESS_DETAIL_MEM_ALGO_COMMON_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/allocators/allocation_type.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+
+//!\file
+//!Implements common operations for memory algorithms.
+
+namespace boost {
+namespace interprocess {
+namespace detail {
+
+template<class VoidPointer>
+struct multi_allocation_next
+{
+ typedef typename detail::
+ pointer_to_other<VoidPointer, multi_allocation_next>::type
+ multi_allocation_next_ptr;
+
+ multi_allocation_next(multi_allocation_next_ptr n)
+ : next_(n)
+ {}
+ multi_allocation_next_ptr next_;
+};
+
+//!This iterator is returned by "allocate_many" functions so that
+//!the user can access the multiple buffers allocated in a single call
+template<class VoidPointer>
+class basic_multiallocation_iterator
+ : public std::iterator<std::input_iterator_tag, char *>
+{
+ void unspecified_bool_type_func() const {}
+ typedef void (basic_multiallocation_iterator::*unspecified_bool_type)() const;
+ typedef typename detail::
+ pointer_to_other
+ <VoidPointer, multi_allocation_next<VoidPointer> >::type
+ multi_allocation_next_ptr;
+
+ public:
+ typedef char * value_type;
+ typedef value_type & reference;
+ typedef value_type * pointer;
+
+ basic_multiallocation_iterator()
+ : next_alloc_(0)
+ {}
+
+ basic_multiallocation_iterator(multi_allocation_next_ptr next)
+ : next_alloc_(next)
+ {}
+
+ basic_multiallocation_iterator &operator=(const basic_multiallocation_iterator &other)
+ { next_alloc_ = other.next_alloc_; return *this; }
+
+ public:
+ basic_multiallocation_iterator& operator++()
+ { next_alloc_.next_ = detail::get_pointer(next_alloc_.next_->next_); return *this; }
+
+ basic_multiallocation_iterator operator++(int)
+ {
+ basic_multiallocation_iterator result(next_alloc_.next_);
+ ++*this;
+ return result;
+ }
+
+ bool operator== (const basic_multiallocation_iterator& other) const
+ { return next_alloc_.next_ == other.next_alloc_.next_; }
+
+ bool operator!= (const basic_multiallocation_iterator& other) const
+ { return !operator== (other); }
+
+ value_type operator*() const
+ {
+ value_type v = (char*)detail::get_pointer(next_alloc_.next_);
+ return v;
+ }
+
+ operator unspecified_bool_type() const
+ { return next_alloc_.next_? &basic_multiallocation_iterator::unspecified_bool_type_func : 0; }
+
+ pointer operator->() const
+ { return &operator*(); }
+
+ private:
+ multi_allocation_next<VoidPointer> next_alloc_;
+};
+
+
+//!This class implements several allocation functions shared by different algorithms
+//!(aligned allocation, multiple allocation...).
+template<class MemoryAlgorithm>
+class memory_algorithm_common
+{
+ public:
+ typedef typename MemoryAlgorithm::void_pointer void_pointer;
+ typedef typename MemoryAlgorithm::block_ctrl block_ctrl;
+ typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator;
+ typedef multi_allocation_next<void_pointer> multi_allocation_next_t;
+ typedef typename multi_allocation_next_t::
+ multi_allocation_next_ptr multi_allocation_next_ptr;
+ typedef memory_algorithm_common<MemoryAlgorithm> this_type;
+
+ static const std::size_t Alignment = MemoryAlgorithm::Alignment;
+ static const std::size_t MinBlockUnits = MemoryAlgorithm::MinBlockUnits;
+ static const std::size_t AllocatedCtrlBytes = MemoryAlgorithm::AllocatedCtrlBytes;
+ static const std::size_t AllocatedCtrlUnits = MemoryAlgorithm::AllocatedCtrlUnits;
+ static const std::size_t BlockCtrlBytes = MemoryAlgorithm::BlockCtrlBytes;
+ static const std::size_t BlockCtrlUnits = MemoryAlgorithm::BlockCtrlUnits;
+
+ static void check_alignment(const void *ptr)
+ {
+ (void)ptr;
+ BOOST_ASSERT(((std::size_t)ptr) % Alignment == 0);
+ }
+
+ static std::size_t ceil_units(std::size_t size)
+ { return detail::get_rounded_size(size, Alignment)/Alignment; }
+
+ static std::size_t floor_units(std::size_t size)
+ { return size/Alignment; }
+
+ static std::size_t multiple_of_units(std::size_t size)
+ { return detail::get_rounded_size(size, Alignment); }
+
+ static multiallocation_iterator allocate_many
+ (MemoryAlgorithm *memory_algo, std::size_t elem_bytes, std::size_t n_elements)
+ {
+ return this_type::priv_allocate_many(memory_algo, &elem_bytes, n_elements, 0);
+ }
+
+ static multiallocation_iterator allocate_many
+ ( MemoryAlgorithm *memory_algo
+ , const std::size_t *elem_sizes
+ , std::size_t n_elements
+ , std::size_t sizeof_element)
+ {
+ return this_type::priv_allocate_many(memory_algo, elem_sizes, n_elements, sizeof_element);
+ }
+
+ static void* allocate_aligned
+ (MemoryAlgorithm *memory_algo, std::size_t nbytes, std::size_t alignment)
+ {
+ //Ensure power of 2
+ if ((alignment & (alignment - std::size_t(1u))) != 0){
+ //Alignment is not power of two
+ BOOST_ASSERT((alignment & (alignment - std::size_t(1u))) != 0);
+ return 0;
+ }
+
+ std::size_t real_size;
+ if(alignment <= Alignment){
+ return memory_algo->priv_allocate(allocate_new, nbytes, nbytes, real_size).first;
+ }
+
+ //We can find a aligned portion if we allocate a chunk that has alignment
+ //nbytes + alignment bytes or more.
+ std::size_t minimum_allocation = max_value
+ ( nbytes + alignment, std::size_t(MinBlockUnits*Alignment));
+ //Since we will split that chunk, we must request a bit more memory
+ //if the alignment is near the beginning of the buffer, because otherwise,
+ //there is no space for a new chunk before the alignment.
+ //
+ // ____ Aligned here
+ // |
+ // -----------------------------------------------------
+ // | MBU |
+ // -----------------------------------------------------
+ std::size_t request =
+ minimum_allocation + (MinBlockUnits*Alignment - AllocatedCtrlBytes);
+
+ //Now allocate the buffer
+ void *buffer = memory_algo->priv_allocate(allocate_new, request, request, real_size).first;
+ if(!buffer){
+ return 0;
+ }
+ else if ((((std::size_t)(buffer)) % alignment) == 0){
+ //If we are lucky and the buffer is aligned, just split it and
+ //return the high part
+ block_ctrl *first = memory_algo->priv_get_block(buffer);
+ std::size_t old_size = first->m_size;
+ const std::size_t first_min_units =
+ max_value(ceil_units(nbytes) + AllocatedCtrlUnits, std::size_t(MinBlockUnits));
+ //We can create a new block in the end of the segment
+ if(old_size >= (first_min_units + MinBlockUnits)){
+ block_ctrl *second = new((char*)first + Alignment*first_min_units) block_ctrl;
+ first->m_size = first_min_units;
+ second->m_size = old_size - first->m_size;
+ BOOST_ASSERT(second->m_size >= MinBlockUnits);
+ memory_algo->priv_mark_new_allocated_block(first);
+ //memory_algo->priv_tail_size(first, first->m_size);
+ memory_algo->priv_mark_new_allocated_block(second);
+ memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(second));
+ }
+ return buffer;
+ }
+
+ //Buffer not aligned, find the aligned part.
+ //
+ // ____ Aligned here
+ // |
+ // -----------------------------------------------------
+ // | MBU +more | ACB |
+ // -----------------------------------------------------
+ char *pos = (char*)
+ ((std::size_t)((char*)buffer +
+ //This is the minimum size of (2)
+ (MinBlockUnits*Alignment - AllocatedCtrlBytes) +
+ //This is the next MBU for the aligned memory
+ AllocatedCtrlBytes +
+ //This is the alignment trick
+ alignment - 1) & -alignment);
+
+ //Now obtain the address of the blocks
+ block_ctrl *first = memory_algo->priv_get_block(buffer);
+ block_ctrl *second = memory_algo->priv_get_block(pos);
+
+ //Set the new size of the first block
+ std::size_t old_size = first->m_size;
+ first->m_size = ((char*)second - (char*)first)/Alignment;
+ memory_algo->priv_mark_new_allocated_block(first);
+
+ //Now check if we can create a new buffer in the end
+ //
+ // __"second" block
+ // | __Aligned here
+ // | | __"third" block
+ // -----------|-----|-----|------------------------------
+ // | MBU +more | ACB | (3) | BCU |
+ // -----------------------------------------------------
+ //This size will be the minimum size to be able to create a
+ //new chunk in the end.
+ const std::size_t second_min_units = max_value(std::size_t(MinBlockUnits),
+ ceil_units(nbytes) + AllocatedCtrlUnits );
+
+ //Check if we can create a new block (of size MinBlockUnits) in the end of the segment
+ if((old_size - first->m_size) >= (second_min_units + MinBlockUnits)){
+ //Now obtain the address of the end block
+ block_ctrl *third = new ((char*)second + Alignment*second_min_units)block_ctrl;
+ second->m_size = second_min_units;
+ third->m_size = old_size - first->m_size - second->m_size;
+ BOOST_ASSERT(third->m_size >= MinBlockUnits);
+ memory_algo->priv_mark_new_allocated_block(second);
+ memory_algo->priv_mark_new_allocated_block(third);
+ memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(third));
+ }
+ else{
+ second->m_size = old_size - first->m_size;
+ memory_algo->priv_mark_new_allocated_block(second);
+ }
+
+ memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(first));
+ return memory_algo->priv_get_user_buffer(second);
+ }
+
+ static bool try_shrink
+ (MemoryAlgorithm *memory_algo, void *ptr
+ ,const std::size_t max_size, const std::size_t preferred_size
+ ,std::size_t &received_size)
+ {
+ //Obtain the real block
+ block_ctrl *block = memory_algo->priv_get_block(ptr);
+ std::size_t old_block_units = block->m_size;
+
+ //The block must be marked as allocated
+ BOOST_ASSERT(memory_algo->priv_is_allocated_block(block));
+
+ //Check if alignment and block size are right
+ check_alignment(ptr);
+
+ //Put this to a safe value
+ received_size = (old_block_units - AllocatedCtrlUnits)*Alignment;
+
+ //Now translate it to Alignment units
+ const std::size_t max_user_units = floor_units(max_size);
+ const std::size_t preferred_user_units = ceil_units(preferred_size);
+
+ //Check if rounded max and preferred are possible correct
+ if(max_user_units < preferred_user_units)
+ return false;
+
+ //Check if the block is smaller than the requested minimum
+ std::size_t old_user_units = old_block_units - AllocatedCtrlUnits;
+
+ if(old_user_units < preferred_user_units)
+ return false;
+
+ //If the block is smaller than the requested minimum
+ if(old_user_units == preferred_user_units)
+ return true;
+
+ std::size_t shrunk_user_units =
+ ((BlockCtrlUnits - AllocatedCtrlUnits) > preferred_user_units)
+ ? (BlockCtrlUnits - AllocatedCtrlUnits)
+ : preferred_user_units;
+
+ //Some parameter checks
+ if(max_user_units < shrunk_user_units)
+ return false;
+
+ //We must be able to create at least a new empty block
+ if((old_user_units - shrunk_user_units) < BlockCtrlUnits ){
+ return false;
+ }
+
+ //Update new size
+ received_size = shrunk_user_units*Alignment;
+ return true;
+ }
+
+ static bool shrink
+ (MemoryAlgorithm *memory_algo, void *ptr
+ ,const std::size_t max_size, const std::size_t preferred_size
+ ,std::size_t &received_size)
+ {
+ //Obtain the real block
+ block_ctrl *block = memory_algo->priv_get_block(ptr);
+ std::size_t old_block_units = block->m_size;
+
+ if(!try_shrink
+ (memory_algo, ptr, max_size, preferred_size, received_size)){
+ return false;
+ }
+
+ //Check if the old size was just the shrunk size (no splitting)
+ if((old_block_units - AllocatedCtrlUnits) == ceil_units(preferred_size))
+ return true;
+
+ //Now we can just rewrite the size of the old buffer
+ block->m_size = received_size/Alignment + AllocatedCtrlUnits;
+ BOOST_ASSERT(block->m_size >= BlockCtrlUnits);
+ memory_algo->priv_mark_new_allocated_block(block);
+
+ //We create the new block
+ block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
+ (detail::char_ptr_cast(block) + block->m_size*Alignment)) block_ctrl;
+
+ //Write control data to simulate this new block was previously allocated
+ //and deallocate it
+ new_block->m_size = old_block_units - block->m_size;
+ BOOST_ASSERT(new_block->m_size >= BlockCtrlUnits);
+ memory_algo->priv_mark_new_allocated_block(new_block);
+ memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(new_block));
+ return true;
+ }
+
+ private:
+ static multiallocation_iterator priv_allocate_many
+ ( MemoryAlgorithm *memory_algo
+ , const std::size_t *elem_sizes
+ , std::size_t n_elements
+ , std::size_t sizeof_element)
+ {
+ //Note: sizeof_element == 0 indicates that we want to
+ //allocate n_elements of the same size "*elem_sizes"
+
+ //Calculate the total size of all requests
+ std::size_t total_request_units = 0;
+ std::size_t elem_units;
+ if(!sizeof_element){
+ elem_units = memory_algo->priv_get_total_units(*elem_sizes);
+ total_request_units = n_elements*elem_units;
+ }
+ else{
+ for(std::size_t i = 0; i < n_elements; ++i){
+ elem_units = memory_algo->priv_get_total_units(elem_sizes[i]*sizeof_element);
+ total_request_units += elem_units;
+ }
+ }
+
+ multi_allocation_next_ptr first = 0, previous;
+ std::size_t low_idx = 0;
+ while(low_idx < n_elements){
+ std::size_t total_bytes = total_request_units*Alignment - AllocatedCtrlBytes;
+ std::size_t min_allocation = (!sizeof_element)
+ ? elem_units
+ : memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element);
+ min_allocation = min_allocation*Alignment - AllocatedCtrlBytes;
+
+ std::size_t received_size;
+ std::pair<void *, bool> ret = memory_algo->priv_allocate
+ (allocate_new, min_allocation, total_bytes, received_size, 0);
+ if(!ret.first){
+ break;
+ }
+
+ block_ctrl *block = memory_algo->priv_get_block(ret.first);
+ std::size_t received_units = block->m_size;
+ char *block_address = (char*)block;
+
+ std::size_t total_used_units = 0;
+ while(total_used_units < received_units){
+ if(sizeof_element){
+ elem_units = memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element);
+ }
+ if(total_used_units + elem_units > received_units)
+ break;
+ total_request_units -= elem_units;
+ //This is the position where the new block must be created
+ block_ctrl *new_block = new(block_address)block_ctrl;
+
+ //The last block should take all the remaining space
+ if((low_idx + 1) == n_elements ||
+ (total_used_units + elem_units +
+ ((!sizeof_element)
+ ? elem_units
+ : memory_algo->priv_get_total_units(elem_sizes[low_idx+1]*sizeof_element))
+ ) > received_units){
+ //By default, the new block will use the rest of the buffer
+ new_block->m_size = received_units - total_used_units;
+ memory_algo->priv_mark_new_allocated_block(new_block);
+
+ //If the remaining units are bigger than needed and we can
+ //split it obtaining a new free memory block do it.
+ if((received_units - total_used_units) >= (elem_units + MemoryAlgorithm::BlockCtrlUnits)){
+ std::size_t shrunk_received;
+ std::size_t shrunk_request = elem_units*Alignment - AllocatedCtrlBytes;
+ bool ret = shrink
+ (memory_algo
+ ,memory_algo->priv_get_user_buffer(new_block)
+ ,shrunk_request
+ ,shrunk_request
+ ,shrunk_received);
+ //Shrink must always succeed with passed parameters
+ BOOST_ASSERT(ret);
+ //Some sanity checks
+ BOOST_ASSERT(shrunk_request == shrunk_received);
+ BOOST_ASSERT(elem_units == (shrunk_request/Alignment + AllocatedCtrlUnits));
+ //"new_block->m_size" must have been reduced to elem_units by "shrink"
+ BOOST_ASSERT(new_block->m_size == elem_units);
+ //Now update the total received units with the reduction
+ received_units = elem_units + total_used_units;
+ }
+ }
+ else{
+ new_block->m_size = elem_units;
+ memory_algo->priv_mark_new_allocated_block(new_block);
+ }
+
+ block_address += new_block->m_size*Alignment;
+ total_used_units += new_block->m_size;
+ multi_allocation_next_ptr p = new(memory_algo->priv_get_user_buffer(new_block))multi_allocation_next_t(0);
+ if(!first){
+ first = p;
+ }
+ else{
+ previous->next_ = p;
+ }
+ previous = p;
+ ++low_idx;
+ }
+ //Sanity check
+ BOOST_ASSERT(total_used_units == received_units);
+ }
+
+ if(low_idx != n_elements){
+ while(first){
+ multi_allocation_next_ptr prev = first;
+ first = first->next_;
+ memory_algo->priv_deallocate(detail::get_pointer(prev));
+ }
+ return multiallocation_iterator();
+ }
+ else{
+ return multiallocation_iterator(first);
+ }
+ return multiallocation_iterator(first);
+ }
+};
+
+} //namespace detail {
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_DETAIL_MEM_ALGO_COMMON_HPP
Modified: trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -27,6 +27,7 @@
#include <boost/interprocess/detail/min_max.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <algorithm>
#include <utility>
#include <cstring>
@@ -34,16 +35,13 @@
#include <assert.h>
#include <new>
-/*!\file
- Describes sequential fit algorithm used to allocate objects in shared memory.
- This class is intended as a base class for single segment and multi-segment
- implementations.
-*/
+//!\file
+//!Describes sequential fit algorithm used to allocate objects in shared memory.
+//!This class is intended as a base class for single segment and multi-segment
+//!implementations.
namespace boost {
-
namespace interprocess {
-
namespace detail {
//!This class implements the simple sequential fit algorithm with a simply
@@ -59,13 +57,15 @@
simple_seq_fit_impl &operator=(const simple_seq_fit_impl &);
public:
- class multiallocation_iterator;
//!Shared interprocess_mutex family used for the rest of the Interprocess framework
typedef MutexFamily mutex_family;
//!Pointer type to be used with the rest of the Interprocess framework
typedef VoidPointer void_pointer;
+ typedef detail::basic_multiallocation_iterator
+ <void_pointer> multiallocation_iterator;
+
private:
class block_ctrl;
typedef typename detail::
@@ -89,18 +89,6 @@
std::size_t get_total_bytes() const
{ return this->m_size*Alignment; }
-
- static block_ctrl *get_block_from_addr(void *addr)
- {
- return reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(addr) - BlockCtrlBytes);
- }
-
- void *get_addr() const
- {
- return reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(this) + BlockCtrlBytes);
- }
};
//!Shared interprocess_mutex to protect memory allocate/deallocate
@@ -118,83 +106,12 @@
std::size_t m_size;
} m_header;
- friend class multiallocation_iterator;
+ friend class detail::basic_multiallocation_iterator<void_pointer>;
+ friend class detail::memory_algorithm_common<simple_seq_fit_impl>;
- public:
- class multiallocation_iterator
- : public std::iterator<std::bidirectional_iterator_tag, char *>
- {
- void unspecified_bool_type_func() const {}
- typedef void (multiallocation_iterator::*unspecified_bool_type)() const;
-
- public:
- typedef char * value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
-
- multiallocation_iterator()
- : block_(0), n_elements_ (0)
- {}
-
- multiallocation_iterator(void *many_allocation, std::size_t n_elements)
- : block_(static_cast<block_ctrl*>(many_allocation)), n_elements_ (n_elements)
- {}
-
- multiallocation_iterator &operator=(const multiallocation_iterator &other)
- { block_ = other.block_; n_elements_ = other.n_elements_; return *this; }
-
- public:
- multiallocation_iterator& operator++()
- {
- --n_elements_;
- block_ = (block_ctrl*)((char*)block_ + block_->m_size*Alignment);
- return *this;
- }
-
- multiallocation_iterator operator++(int)
- {
- multiallocation_iterator result(block_, n_elements_);
- ++*this;
- return result;
- }
-
- multiallocation_iterator& operator--()
- {
- ++n_elements_;
- block_ = (block_ctrl*)((char*)block_ - block_->m_size*Alignment);
- return *this;
- }
-
- multiallocation_iterator operator--(int)
- {
- multiallocation_iterator result(block_, n_elements_);
- --*this;
- return result;
- }
-
- bool operator== (const multiallocation_iterator& other) const
- { return n_elements_ == other.n_elements_; }
-
- bool operator!= (const multiallocation_iterator& other) const
- { return !operator== (other); }
-
- value_type operator*() const
- {
- value_type v = (char*)block_ + BlockCtrlBytes;
- return v;
- }
-
- operator unspecified_bool_type() const
- { return n_elements_? &multiallocation_iterator::unspecified_bool_type_func : 0; }
-
- pointer operator->() const
- { return &operator*(); }
-
- private:
- block_ctrl *block_;
- std::size_t n_elements_;
- };
+ typedef detail::memory_algorithm_common<simple_seq_fit_impl> algo_impl_t;
+ public:
//!Constructor. "size" is the total size of the managed memory segment,
//!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit_impl)
//!offset that the allocator should not use at all.
@@ -214,7 +131,7 @@
/// @cond
//!Multiple element allocation, same size
- multiallocation_iterator allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements);
+ multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements);
//!Multiple element allocation, different size
multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
@@ -257,10 +174,12 @@
void* allocate_aligned (std::size_t nbytes, std::size_t alignment);
private:
- std::pair<void*, bool>
- priv_allocation_command(allocation_type command, std::size_t limit_size,
- std::size_t preferred_size,std::size_t &received_size,
- void *reuse_ptr, std::size_t sizeof_object);
+
+ //!Obtains the pointer returned to the user from the block control
+ static void *priv_get_user_buffer(const block_ctrl *block);
+
+ //!Obtains the block control structure of the user buffer
+ static block_ctrl *priv_get_block(const void *ptr);
//!Real allocation algorithm with min allocation option
std::pair<void *, bool> priv_allocate(allocation_type command
@@ -269,13 +188,12 @@
,std::size_t &received_size
,void *reuse_ptr = 0);
- //!Common function to implement the previous two
- multiallocation_iterator priv_allocate_many
- (const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
-
- multiallocation_iterator priv_allocate_many
- ( std::size_t elem_size, std::size_t min_elements
- , std::size_t preferred_elements, std::size_t &received_elements);
+ std::pair<void *, bool> priv_allocation_command(allocation_type command
+ ,std::size_t min_size
+ ,std::size_t preferred_size
+ ,std::size_t &received_size
+ ,void *reuse_ptr
+ ,std::size_t sizeof_object);
//!Returns the number of total units that a user buffer
//!of "userbytes" bytes really occupies (including header)
@@ -285,6 +203,9 @@
//!Returns 0 if next block is not free.
block_ctrl *priv_next_block_if_free(block_ctrl *ptr);
+ //!Check if this block is free (not allocated)
+ bool priv_is_allocated_block(block_ctrl *ptr);
+
//!Returns previous block's if it's free.
//!Returns 0 if previous block is not free.
std::pair<block_ctrl*, block_ctrl*>priv_prev_block_if_free(block_ctrl *ptr);
@@ -302,13 +223,8 @@
,void *reuse_ptr
,bool only_preferred_backwards);
- //!Real shrink function implementation
- bool priv_shrink(void *ptr
- ,std::size_t max_size, std::size_t preferred_size
- ,std::size_t &received_size);
-
//!Real private aligned allocation function
- void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment);
+ //void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment);
//!Checks if block has enough memory and splits/unlinks the block
//!returning the address to the users
@@ -322,10 +238,15 @@
//!Makes a new memory portion available for allocation
void priv_add_segment(void *addr, std::size_t size);
- enum { Alignment = detail::alignment_of<detail::max_align>::value };
- enum { BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value };
- enum { BlockCtrlSize = BlockCtrlBytes/Alignment };
- enum { MinBlockSize = BlockCtrlSize + Alignment };
+ void priv_mark_new_allocated_block(block_ctrl *block);
+
+ static const std::size_t Alignment = detail::alignment_of<detail::max_align>::value;
+ static const std::size_t BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
+ static const std::size_t BlockCtrlUnits = BlockCtrlBytes/Alignment;
+ static const std::size_t MinBlockUnits = BlockCtrlUnits;
+ static const std::size_t MinBlockSize = MinBlockUnits*Alignment;
+ static const std::size_t AllocatedCtrlBytes = BlockCtrlBytes;
+ static const std::size_t AllocatedCtrlUnits = BlockCtrlUnits;
public:
static const std::size_t PayloadPerAllocation = BlockCtrlBytes;
@@ -376,10 +297,31 @@
new_block->m_next = 0;
new_block->m_size = (m_header.m_size - old_end)/Alignment;
m_header.m_allocated += new_block->m_size*Alignment;
- this->priv_deallocate(detail::char_ptr_cast(new_block) + BlockCtrlBytes);
+ this->priv_deallocate(priv_get_user_buffer(new_block));
+}
+
+template<class MutexFamily, class VoidPointer>
+inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::
+ priv_mark_new_allocated_block(block_ctrl *new_block)
+{
+ new_block->m_next = 0;
+}
+
+template<class MutexFamily, class VoidPointer>
+inline
+typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *
+ simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_get_block(const void *ptr)
+{
+ return reinterpret_cast<block_ctrl*>(detail::char_ptr_cast(ptr) - AllocatedCtrlBytes);
}
template<class MutexFamily, class VoidPointer>
+inline
+void *simple_seq_fit_impl<MutexFamily, VoidPointer>::
+ priv_get_user_buffer(const typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *block)
+{ return detail::char_ptr_cast(block) + AllocatedCtrlBytes; }
+
+template<class MutexFamily, class VoidPointer>
inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_add_segment(void *addr, std::size_t size)
{
//Check size
@@ -393,7 +335,7 @@
//Simulate this block was previously allocated
m_header.m_allocated += new_block->m_size*Alignment;
//Return block and insert it in the free block list
- this->priv_deallocate(detail::char_ptr_cast(new_block) + BlockCtrlBytes);
+ this->priv_deallocate(priv_get_user_buffer(new_block));
}
template<class MutexFamily, class VoidPointer>
@@ -438,9 +380,9 @@
//Iterate through all free portions
do{
//Just clear user the memory part reserved for the user
- std::memset( detail::char_ptr_cast(block) + BlockCtrlBytes
+ std::memset( priv_get_user_buffer(block)
, 0
- , block->m_size*Alignment - BlockCtrlBytes);
+ , block->get_user_bytes());
block = detail::get_pointer(block->m_next);
}
while(block != &m_header.m_root);
@@ -484,7 +426,7 @@
template<class MutexFamily, class VoidPointer>
inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
allocate(std::size_t nbytes)
-{
+{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
@@ -499,7 +441,8 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- return priv_allocate_aligned(nbytes, alignment);
+ return algo_impl_t::
+ allocate_aligned(this, nbytes, alignment);
}
template<class MutexFamily, class VoidPointer>
@@ -509,6 +452,11 @@
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr)
{
+ if(command & try_shrink_in_place){
+ bool success =
+ algo_impl_t::try_shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
+ return std::pair<T *, bool> ((success ? reuse_ptr : 0), true);
+ }
std::pair<void*, bool> ret = priv_allocation_command
(command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
@@ -518,7 +466,7 @@
template<class MutexFamily, class VoidPointer>
inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_allocation_command (allocation_type command, std::size_t limit_size,
- std::size_t preferred_size,std::size_t &received_size,
+ std::size_t preferred_size, std::size_t &received_size,
void *reuse_ptr, std::size_t sizeof_object)
{
command &= ~expand_bwd;
@@ -550,8 +498,8 @@
//to be modified
//Obtain the real size of the block
block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) - BlockCtrlBytes);
- return block->m_size*Alignment - BlockCtrlBytes;
+ (priv_get_block(detail::char_ptr_cast(ptr)));
+ return block->get_user_bytes();
}
template<class MutexFamily, class VoidPointer>
@@ -564,7 +512,7 @@
,bool only_preferred_backwards)
{
typedef std::pair<block_ctrl *, block_ctrl *> prev_block_t;
- block_ctrl *reuse = block_ctrl::get_block_from_addr(reuse_ptr);
+ block_ctrl *reuse = priv_get_block(reuse_ptr);
received_size = 0;
if(this->size(reuse_ptr) > min_size){
@@ -608,12 +556,12 @@
(detail::char_ptr_cast(reuse) - needs_backwards - BlockCtrlBytes);
new_block->m_next = 0;
new_block->m_size =
- BlockCtrlSize + (needs_backwards + extra_forward)/Alignment;
+ BlockCtrlUnits + (needs_backwards + extra_forward)/Alignment;
prev->m_size =
- (prev->get_total_bytes() - needs_backwards)/Alignment - BlockCtrlSize;
+ (prev->get_total_bytes() - needs_backwards)/Alignment - BlockCtrlUnits;
received_size = needs_backwards + extra_forward;
m_header.m_allocated += needs_backwards + BlockCtrlBytes;
- return new_block->get_addr();
+ return priv_get_user_buffer(new_block);
}
else{
//Just merge the whole previous block
@@ -625,7 +573,7 @@
prev_2_block->m_next = prev->m_next;
prev->m_size = reuse->m_size + prev->m_size;
prev->m_next = 0;
- return prev->get_addr();
+ priv_get_user_buffer(prev);
}
}
}
@@ -635,12 +583,13 @@
template<class MutexFamily, class VoidPointer>
inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator
simple_seq_fit_impl<MutexFamily, VoidPointer>::
- allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements)
+ allocate_many(std::size_t elem_bytes, std::size_t num_elements)
{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- return priv_allocate_many(elem_size, min_elements, preferred_elements, received_elements);
+ return algo_impl_t::
+ allocate_many(this, elem_bytes, num_elements);
}
template<class MutexFamily, class VoidPointer>
@@ -651,121 +600,16 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- return priv_allocate_many(elem_sizes, n_elements, sizeof_element);
-}
-
-template<class MutexFamily, class VoidPointer>
-typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator
- simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_allocate_many
- (const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
-{
- //Calculate the total size of all requests
- std::size_t total_request_units;
- total_request_units = 0;
- for(std::size_t i = 0; i < n_elements; ++i){
- std::size_t preferred_units = priv_get_total_units(elem_sizes[i]*sizeof_element);
- total_request_units += preferred_units;
- }
-
- std::size_t total_bytes = total_request_units*Alignment - BlockCtrlBytes;
-
- std::size_t received_size;
- std::pair<void *, bool> ret = priv_allocate
- (allocate_new, total_bytes, total_bytes, received_size, 0);
- if(!ret.first){
- return multiallocation_iterator();
- }
-
- block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ret.first) - BlockCtrlBytes);
- std::size_t received_units = block->m_size;
- char *block_address = (char*)block;
-
- total_request_units = 0;
-
- {
- std::size_t preferred_units;
- //If all have the same size, we don't need calculate it
- //every iteration
- for(std::size_t i = 0; i < n_elements; ++i){
- //If all have different size, we have to calculate it each iteration
- preferred_units = priv_get_total_units(elem_sizes[i]*sizeof_element);
- //This is the position where the new block must be created
- block_ctrl *new_block = new(block_address)block_ctrl;
- //The last block should take all the remaining space
- if((i + 1) == n_elements){
- new_block->m_size = received_units - total_request_units;
- }
- else{
- new_block->m_size = preferred_units;
- }
- //assert(new_block->m_size >= BlockCtrlUnits);
- new_block->m_next = 0;
- block_address += new_block->m_size*Alignment;
- total_request_units += new_block->m_size;
- }
- assert(total_request_units == received_units);
- }
- return multiallocation_iterator(block, n_elements);
-}
-
-template<class MutexFamily, class VoidPointer>
-typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator
- simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_allocate_many
- ( std::size_t elem_size, std::size_t min_elements
- , std::size_t preferred_elements, std::size_t &received_elements)
-{
- //Calculate the total size of all requests
- const std::size_t elem_units = priv_get_total_units(elem_size);
- const std::size_t total_min_usr_units = min_elements*elem_units - BlockCtrlSize;
- const std::size_t total_preferred_usr_units = preferred_elements*elem_units - BlockCtrlSize;
-
- std::size_t received_size;
- std::pair<void *, bool> ret = priv_allocate
- ( allocate_new, total_min_usr_units*Alignment
- , total_preferred_usr_units*Alignment, received_size, 0);
- if(!ret.first){
- received_elements = (received_size + BlockCtrlBytes)/elem_units;
- return multiallocation_iterator();
- }
-
- block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ret.first) - BlockCtrlBytes);
- std::size_t received_units = block->m_size;
- char *block_address = (char*)block;
-
- received_elements = received_units/elem_units;
- if(received_elements > preferred_elements){
- received_elements = preferred_elements;
- }
- std::size_t total_request_units = 0;
- {
- for(std::size_t i = 0; i < received_elements; ++i){
- //If all have different size, we have to calculate it each iteration
- //This is the position where the new block must be created
- block_ctrl *new_block = new(block_address)block_ctrl;
- //The last block should take all the remaining space
- if((i + 1) == received_elements){
- new_block->m_size = received_units - (received_elements-1)*elem_units;
- }
- else{
- new_block->m_size = elem_units;
- }
- //assert(new_block->m_size >= BlockCtrlUnits);
- new_block->m_next = 0;
- block_address += new_block->m_size*Alignment;
- total_request_units += new_block->m_size;
- }
- assert(total_request_units == received_units);
- }
- return multiallocation_iterator(block, received_elements);
+ return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
}
template<class MutexFamily, class VoidPointer>
inline std::size_t simple_seq_fit_impl<MutexFamily, VoidPointer>::
priv_get_total_units(std::size_t userbytes)
{
- return detail::get_rounded_size(userbytes, Alignment)/Alignment + BlockCtrlSize;
+ std::size_t s = detail::get_rounded_size(userbytes, Alignment)/Alignment;
+ if(!s) ++s;
+ return BlockCtrlUnits + s;
}
template<class MutexFamily, class VoidPointer>
@@ -778,7 +622,7 @@
{
if(command & shrink_in_place){
bool success =
- this->priv_shrink(reuse_ptr, limit_size, preferred_size, received_size);
+ algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
}
typedef std::pair<void *, bool> return_type;
@@ -788,7 +632,7 @@
return return_type(0, false);
//Number of units to request (including block_ctrl header)
- std::size_t nunits = detail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlSize;
+ std::size_t nunits = detail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlUnits;
//Get the root and the first memory block
block_ctrl *prev = &m_header.m_root;
@@ -796,7 +640,7 @@
block_ctrl *root = &m_header.m_root;
block_ctrl *biggest_block = 0;
block_ctrl *prev_biggest_block = 0;
- std::size_t biggest_size = limit_size;
+ std::size_t biggest_size = 0;
//Expand in place
//reuse_ptr, limit_size, preferred_size, received_size
@@ -827,12 +671,15 @@
//Bad luck finding preferred_size, now if we have any biggest_block
//try with this block
if(biggest_block){
- received_size = biggest_block->m_size*Alignment - BlockCtrlSize;
- nunits = detail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlSize;
+ std::size_t limit_units = detail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlUnits;
+ if(biggest_block->m_size < limit_units)
+ return return_type(0, false);
+
+ received_size = biggest_block->m_size*Alignment - BlockCtrlUnits;
void *ret = this->priv_check_and_allocate
- (nunits, prev_biggest_block, biggest_block, received_size);
- if(ret)
- return return_type(ret, false);
+ (biggest_block->m_size, prev_biggest_block, biggest_block, received_size);
+ assert(ret != 0);
+ return return_type(ret, false);
}
}
//Now try to expand both sides with min size
@@ -843,6 +690,11 @@
return return_type(0, false);
}
+template<class MutexFamily, class VoidPointer> inline
+bool simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_is_allocated_block
+ (typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *block)
+{ return block->m_next == 0; }
+
template<class MutexFamily, class VoidPointer>
inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *
simple_seq_fit_impl<MutexFamily, VoidPointer>::
@@ -907,8 +759,7 @@
,std::size_t &received_size)
{
//Obtain the real size of the block
- block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) - BlockCtrlBytes);
+ block_ctrl *block = reinterpret_cast<block_ctrl*>(priv_get_block(ptr));
std::size_t old_block_size = block->m_size;
//All used blocks' next is marked with 0 so check it
@@ -925,7 +776,7 @@
if(min_size > preferred_size)
return false;
- std::size_t data_size = old_block_size - BlockCtrlSize;
+ std::size_t data_size = old_block_size - BlockCtrlUnits;
if(data_size >= min_size)
return true;
@@ -941,7 +792,7 @@
//Now we can expand this block further than before
received_size = merged_size*Alignment - BlockCtrlBytes;
- if(merged_size < (min_size + BlockCtrlSize)){
+ if(merged_size < (min_size + BlockCtrlUnits)){
return false;
}
@@ -961,7 +812,7 @@
prev->m_next = block;
//Now use check and allocate to do the allocation logic
- preferred_size += BlockCtrlSize;
+ preferred_size += BlockCtrlUnits;
std::size_t nunits = preferred_size < merged_size ? preferred_size : merged_size;
//This must success since nunits is less than merged_size!
@@ -974,114 +825,6 @@
return true;
}
-template<class MutexFamily, class VoidPointer>
-inline bool simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_shrink (void *ptr
- ,std::size_t max_size
- ,std::size_t preferred_size
- ,std::size_t &received_size)
-{
- //Obtain the real size of the block
- block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) - BlockCtrlBytes);
- std::size_t block_size = block->m_size;
-
- //All used blocks' next is marked with 0 so check it
- assert(block->m_next == 0);
-
- //Put this to a safe value
- received_size = block_size*Alignment - BlockCtrlBytes;
-
- //Now translate it to Alignment units
- max_size = max_size/Alignment;
- preferred_size = detail::get_rounded_size(preferred_size, Alignment)/Alignment;
-
- //Some parameter checks
- if(max_size < preferred_size)
- return false;
-
- std::size_t data_size = block_size - BlockCtrlSize;
-
- if(data_size < preferred_size)
- return false;
-
- if(data_size == preferred_size)
- return true;
-
- //We must be able to create at least a new empty block
- if((data_size - preferred_size) < BlockCtrlSize){
- return false;
- }
-
- //Now we can just rewrite the size of the old buffer
- block->m_size = preferred_size + BlockCtrlSize;
-
- //Update new size
- received_size = preferred_size*Alignment;
-
- //We create the new block
- block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + block->m_size*Alignment);
-
- //Write control data to simulate this new block was previously allocated
- block->m_next = 0;
- block->m_size = data_size - preferred_size;
-
- //Now deallocate the new block to insert it in the free list
- this->priv_deallocate(detail::char_ptr_cast(block)+BlockCtrlBytes);
- return true;
-}
-
-template<class MutexFamily, class VoidPointer>
-inline void* simple_seq_fit_impl<MutexFamily, VoidPointer>::
- priv_allocate_aligned(std::size_t nbytes, std::size_t alignment)
-{
- //Ensure power of 2
- if ((alignment & (alignment - std::size_t(1u))) != 0){
- //Alignment is not power of two
- assert((alignment & (alignment - std::size_t(1u))) != 0);
- return 0;
- }
-
- std::size_t ignore;
- if(alignment <= Alignment){
- return priv_allocate(allocate_new, nbytes, nbytes, ignore).first;
- }
-
- std::size_t request =
- nbytes + alignment + MinBlockSize*Alignment - BlockCtrlBytes;
- void *buffer = priv_allocate(allocate_new, request, request, ignore).first;
- if(!buffer)
- return 0;
- else if ((((std::size_t)(buffer)) % alignment) == 0)
- return buffer;
-
- char *aligned_portion = (char*)
- ((std::size_t)((char*)buffer + alignment - 1) & -alignment);
-
- char *pos = ((aligned_portion - (char*)buffer) >= (MinBlockSize*Alignment)) ?
- aligned_portion : (aligned_portion + alignment);
-
-
- block_ctrl *first = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(buffer) - BlockCtrlBytes);
-
- block_ctrl *second = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(pos) - BlockCtrlBytes);
-
- std::size_t old_size = first->m_size;
-
- first->m_size = ((char*)second - (char*)first)/Alignment;
- second->m_size = old_size - first->m_size;
-
- //Write control data to simulate this new block was previously allocated
- second->m_next = 0;
-
- //Now deallocate the new block to insert it in the free list
- this->priv_deallocate(detail::char_ptr_cast(first) + BlockCtrlBytes);
- return detail::char_ptr_cast(second) + BlockCtrlBytes;
-}
-
template<class MutexFamily, class VoidPointer> inline
void* simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_check_and_allocate
(std::size_t nunits
@@ -1089,7 +832,7 @@
,typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl* block
,std::size_t &received_size)
{
- std::size_t upper_nunits = nunits + BlockCtrlSize;
+ std::size_t upper_nunits = nunits + BlockCtrlUnits;
bool found = false;
if (block->m_size > upper_nunits){
@@ -1116,13 +859,13 @@
//We need block_ctrl for deallocation stuff, so
//return memory user can overwrite
m_header.m_allocated += block->m_size*Alignment;
- received_size = block->m_size*Alignment - BlockCtrlBytes;
+ received_size = block->get_user_bytes();
//Mark the block as allocated
block->m_next = 0;
//Check alignment
assert(((detail::char_ptr_cast(block) - detail::char_ptr_cast(this))
% Alignment) == 0 );
- return detail::char_ptr_cast(block)+BlockCtrlBytes;
+ return priv_get_user_buffer(block);
}
return 0;
}
@@ -1146,10 +889,9 @@
//by memory address to allow block merging.
//Pointer next always points to the first
//(lower address) block
- block_ctrl_ptr prev = &m_header.m_root;
- block_ctrl_ptr pos = m_header.m_root.m_next;
- block_ctrl_ptr block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(addr) - BlockCtrlBytes);
+ block_ctrl * prev = &m_header.m_root;
+ block_ctrl * pos = detail::get_pointer(m_header.m_root.m_next);
+ block_ctrl * block = reinterpret_cast<block_ctrl*>(priv_get_block(addr));
//All used blocks' next is marked with 0 so check it
assert(block->m_next == 0);
@@ -1170,7 +912,7 @@
//in each process
while((detail::get_pointer(pos) != &m_header.m_root) && (block > pos)){
prev = pos;
- pos = pos->m_next;
+ pos = detail::get_pointer(pos->m_next);
}
//Try to combine with upper block
Modified: trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -19,6 +19,7 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
#include <boost/interprocess/allocators/allocation_type.hpp>
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
@@ -39,11 +40,10 @@
#include <assert.h>
#include <new>
-/*!\file
- Describes a best-fit algorithm based in an intrusive red-black tree used to allocate
- objects in shared memory. This class is intended as a base class for single segment
- and multi-segment implementations.
-*/
+//!\file
+//!Describes a best-fit algorithm based in an intrusive red-black tree used to allocate
+//!objects in shared memory. This class is intended as a base class for single segment
+//!and multi-segment implementations.
namespace boost {
namespace interprocess {
@@ -65,20 +65,25 @@
typedef MutexFamily mutex_family;
//!Pointer type to be used with the rest of the Interprocess framework
typedef VoidPointer void_pointer;
+ typedef detail::basic_multiallocation_iterator
+ <void_pointer> multiallocation_iterator;
/// @cond
- class multiallocation_iterator;
-
private:
struct block_ctrl;
typedef typename detail::
- pointer_to_other<void_pointer, block_ctrl>::type block_ctrl_ptr;
+ pointer_to_other<void_pointer, block_ctrl>::type block_ctrl_ptr;
+ typedef typename detail::
+ pointer_to_other<void_pointer, char>::type char_ptr;
- typedef boost::intrusive::set_base_hook
- < boost::intrusive::tag
- , boost::intrusive::normal_link
- , VoidPointer> TreeHook;
+ typedef typename bi::make_set_base_hook
+ < bi::void_pointer<VoidPointer>
+ , bi::link_mode<bi::normal_link> >::type TreeHook;
+
+ typedef detail::multi_allocation_next<void_pointer> multi_allocation_next_t;
+ typedef typename multi_allocation_next_t::
+ multi_allocation_next_ptr multi_allocation_next_ptr;
struct SizeHolder
{
@@ -113,11 +118,10 @@
};
//!Shared interprocess_mutex to protect memory allocate/deallocate
- typedef typename MutexFamily::mutex_type interprocess_mutex;
-
- typedef boost::intrusive::multiset
- <typename TreeHook::template value_traits<block_ctrl> > Imultiset;
- typedef typename Imultiset::iterator imultiset_iterator;
+ typedef typename MutexFamily::mutex_type interprocess_mutex;
+ typedef typename bi::make_multiset
+ <block_ctrl, bi::base_hook<TreeHook> >::type Imultiset;
+ typedef typename Imultiset::iterator imultiset_iterator;
//!This struct includes needed data and derives from
//!interprocess_mutex to allow EBO when using null interprocess_mutex
@@ -133,84 +137,12 @@
std::size_t m_size;
} m_header;
- friend class multiallocation_iterator;
-
+ friend class detail::basic_multiallocation_iterator<void_pointer>;
+ friend class detail::memory_algorithm_common<rbtree_best_fit>;
+
+ typedef detail::memory_algorithm_common<rbtree_best_fit> algo_impl_t;
public:
- class multiallocation_iterator
- : public std::iterator<std::bidirectional_iterator_tag, char *>
- {
- void unspecified_bool_type_func() const {}
- typedef void (multiallocation_iterator::*unspecified_bool_type)() const;
-
- public:
- typedef char * value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
-
- multiallocation_iterator()
- : block_(0), n_elements_ (0)
- {}
-
- multiallocation_iterator(void *many_allocation, std::size_t n_elements)
- : block_(static_cast<block_ctrl*>(many_allocation)), n_elements_ (n_elements)
- {}
-
- multiallocation_iterator &operator=(const multiallocation_iterator &other)
- { block_ = other.block_; n_elements_ = other.n_elements_; return *this; }
-
- public:
- multiallocation_iterator& operator++()
- {
- --n_elements_;
- block_ = (block_ctrl*)((char*)block_ + block_->m_size*Alignment);
- return *this;
- }
-
- multiallocation_iterator operator++(int)
- {
- multiallocation_iterator result(block_, n_elements_);
- ++*this;
- return result;
- }
-
- multiallocation_iterator& operator--()
- {
- ++n_elements_;
- block_ = (block_ctrl*)((char*)block_ - block_->m_prev_size*Alignment);
- return *this;
- }
-
- multiallocation_iterator operator--(int)
- {
- multiallocation_iterator result(block_, n_elements_);
- --*this;
- return result;
- }
-
- bool operator== (const multiallocation_iterator& other) const
- { return n_elements_ == other.n_elements_; }
-
- bool operator!= (const multiallocation_iterator& other) const
- { return !operator== (other); }
-
- value_type operator*() const
- {
- value_type v = (char*)priv_get_user_buffer(block_);
- return v;
- }
-
- operator unspecified_bool_type() const
- { return n_elements_? &multiallocation_iterator::unspecified_bool_type_func : 0; }
-
- pointer operator->() const
- { return &operator*(); }
-
- private:
- block_ctrl *block_;
- std::size_t n_elements_;
- };
-
/// @endcond
//!Constructor. "size" is the total size of the managed memory segment,
@@ -234,7 +166,7 @@
//Experimental. Dont' use
//!Multiple element allocation, same size
- multiallocation_iterator allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements);
+ multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements);
//!Multiple element allocation, different size
multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
@@ -292,14 +224,6 @@
,void *reuse_ptr = 0
,std::size_t backwards_multiple = 1);
- //!Common function to implement multiple allocation
- multiallocation_iterator priv_allocate_many
- (const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_elements);
-
- multiallocation_iterator priv_allocate_many
- ( std::size_t elem_size, std::size_t min_elements
- , std::size_t preferred_elements, std::size_t &received_elements);
-
//!Obtains the block control structure of the user buffer
static block_ctrl *priv_get_block(const void *ptr);
@@ -310,18 +234,6 @@
//!of "userbytes" bytes really occupies (including header)
static std::size_t priv_get_total_units(std::size_t userbytes);
- //!Translates a size to a number of units (ceiling the result)
- static std::size_t priv_ceil_units(std::size_t size);
-
- //!Translates a size to a number of units (flooring the result)
- static std::size_t priv_floor_units(std::size_t size);
-
- //!Rounds the size (ceiling) to a multiple of units
- static std::size_t priv_multiple_of_units(std::size_t size);
-
- //!Asserts if the alignment is not correct
- static void priv_check_alignment(const void *ptr);
-
//!Real expand function implementation
bool priv_expand(void *ptr
,const std::size_t min_size, const std::size_t preferred_size
@@ -336,16 +248,11 @@
,bool only_preferred_backwards
,std::size_t backwards_multiple);
- //!Real shrink function implementation
- bool priv_shrink(void *ptr
- ,const std::size_t max_size, const std::size_t preferred_size
- ,std::size_t &received_size);
-
//!Set the size in the tail of the block
void priv_tail_size(block_ctrl *ptr, std::size_t size);
//!Real private aligned allocation function
- void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment);
+ //void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment);
//!Get the size in the tail of the block
std::size_t priv_tail_size(block_ctrl *ptr);
@@ -376,15 +283,17 @@
//!Makes a new memory portion available for allocation
void priv_add_segment(void *addr, std::size_t size);
- enum { Alignment = detail::alignment_of<detail::max_align>::value };
- enum { AlignmentMask = (Alignment - 1) };
- enum { BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value };
- enum { BlockCtrlUnits = BlockCtrlBytes/Alignment };
- enum { AllocatedCtrlBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value };
- enum { AllocatedCtrlUnits = AllocatedCtrlBytes/Alignment };
- enum { EndCtrlBlockBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value };
- enum { EndCtrlBlockUnits = EndCtrlBlockBytes/Alignment };
- enum { MinBlockUnits = BlockCtrlUnits };
+ void priv_mark_new_allocated_block(block_ctrl *block);
+
+ static const std::size_t Alignment = detail::alignment_of<detail::max_align>::value;
+ static const std::size_t AlignmentMask = (Alignment - 1);
+ static const std::size_t BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
+ static const std::size_t BlockCtrlUnits = BlockCtrlBytes/Alignment;
+ static const std::size_t AllocatedCtrlBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
+ static const std::size_t AllocatedCtrlUnits = AllocatedCtrlBytes/Alignment;
+ static const std::size_t EndCtrlBlockBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
+ static const std::size_t EndCtrlBlockUnits = EndCtrlBlockBytes/Alignment;
+ static const std::size_t MinBlockUnits = BlockCtrlUnits;
//Make sure the maximum alignment is power of two
BOOST_STATIC_ASSERT((0 == (Alignment & (Alignment - std::size_t(1u)))));
@@ -404,7 +313,7 @@
//Now write calculate the offset of the first big block that will
//cover the whole segment
- std::size_t block1_off = priv_multiple_of_units(sizeof(*this)+extra_hdr_bytes);
+ std::size_t block1_off = algo_impl_t::multiple_of_units(sizeof(*this)+extra_hdr_bytes);
assert(get_min_size(extra_hdr_bytes) <= size);
priv_add_segment(detail::char_ptr_cast(this) + block1_off, size - block1_off);
@@ -423,7 +332,7 @@
{
//Get the address of the first block
std::size_t block1_off =
- priv_multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
+ algo_impl_t::multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
block_ctrl *first_block = reinterpret_cast<block_ctrl *>
(detail::char_ptr_cast(this) + block1_off);
@@ -449,11 +358,9 @@
new_end_block->m_size = (detail::char_ptr_cast(first_block) -
detail::char_ptr_cast(new_end_block))/Alignment;
assert(first_block == priv_next_block(new_end_block));
- priv_mark_as_allocated_block(new_end_block);
new_end_block->m_end = 1;
+ priv_mark_new_allocated_block(new_end_block);
- //This will update the link of the first block
- priv_tail_size(new_end_block, new_end_block->m_size);
assert(new_end_block == priv_prev_block(first_block));
//The old end block is the new block
@@ -463,9 +370,8 @@
detail::char_ptr_cast(new_block))/Alignment;
new_block->m_prev_size = old_end_prev;
assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
+ priv_mark_new_allocated_block(new_block);
assert(priv_next_block(new_block) == new_end_block);
- priv_mark_as_allocated_block(new_block);
m_header.m_allocated += new_block->m_size*Alignment;
@@ -519,6 +425,14 @@
}
template<class MutexFamily, class VoidPointer>
+inline void rbtree_best_fit<MutexFamily, VoidPointer>::
+ priv_mark_new_allocated_block(block_ctrl *new_block)
+{
+ priv_tail_size(new_block, new_block->m_size);
+ priv_mark_as_allocated_block(new_block);
+}
+
+template<class MutexFamily, class VoidPointer>
inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::get_size() const
{ return m_header.m_size; }
@@ -526,14 +440,14 @@
inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::get_free_memory() const
{
return m_header.m_size - m_header.m_allocated -
- priv_multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
+ algo_impl_t::multiple_of_units(sizeof(*this) + m_header.m_extra_hdr_bytes);
}
template<class MutexFamily, class VoidPointer>
inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
get_min_size (std::size_t extra_hdr_bytes)
{
- return (priv_ceil_units(sizeof(rbtree_best_fit) + extra_hdr_bytes) +
+ return (algo_impl_t::ceil_units(sizeof(rbtree_best_fit) + extra_hdr_bytes) +
MinBlockUnits + EndCtrlBlockUnits)*Alignment;
}
@@ -545,7 +459,7 @@
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
std::size_t block1_off =
- priv_multiple_of_units(sizeof(*this)+m_header.m_extra_hdr_bytes);
+ algo_impl_t::multiple_of_units(sizeof(*this)+m_header.m_extra_hdr_bytes);
return m_header.m_allocated == 0 &&
m_header.m_imultiset.begin() != m_header.m_imultiset.end() &&
@@ -576,7 +490,7 @@
}
std::size_t block1_off =
- priv_multiple_of_units(sizeof(*this)+m_header.m_extra_hdr_bytes);
+ algo_impl_t::multiple_of_units(sizeof(*this)+m_header.m_extra_hdr_bytes);
//Check free bytes are less than size
if(free_memory > (m_header.m_size - block1_off)){
@@ -599,11 +513,11 @@
template<class MutexFamily, class VoidPointer>
inline void* rbtree_best_fit<MutexFamily, VoidPointer>::
allocate_aligned(std::size_t nbytes, std::size_t alignment)
-{
+{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- return priv_allocate_aligned(nbytes, alignment);
+ return algo_impl_t::allocate_aligned(this, nbytes, alignment);
}
template<class MutexFamily, class VoidPointer>
@@ -613,6 +527,11 @@
std::size_t preferred_size,std::size_t &received_size,
T *reuse_ptr)
{
+ if(command & try_shrink_in_place){
+ bool success =
+ algo_impl_t::try_shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
+ return std::pair<T *, bool> ((success ? reuse_ptr : 0), true);
+ }
std::pair<void*, bool> ret = priv_allocation_command
(command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
@@ -701,7 +620,7 @@
//Sanity check
assert(reuse->m_size == priv_tail_size(reuse));
- priv_check_alignment(reuse);
+ algo_impl_t::check_alignment(reuse);
block_ctrl *prev_block;
@@ -712,7 +631,7 @@
//Some sanity checks
assert(prev_block->m_size == priv_tail_size(prev_block));
- priv_check_alignment(prev_block);
+ algo_impl_t::check_alignment(prev_block);
//Let's calculate the number of extra bytes of data before the current
//block's begin. The value is a multiple of backwards_multiple
@@ -748,14 +667,13 @@
(detail::char_ptr_cast(reuse) - needs_backwards_aligned);
//Erase old previous block, since we will change it
- m_header.m_imultiset.erase(Imultiset::iterator_to(*prev_block));
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
//Free old previous buffer
new_block->m_size =
AllocatedCtrlUnits + (needs_backwards_aligned + received_size)/Alignment;
assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_allocated_block(new_block);
+ priv_mark_new_allocated_block(new_block);
prev_block->m_size = (detail::char_ptr_cast(new_block) -
detail::char_ptr_cast(prev_block))/Alignment;
@@ -769,7 +687,7 @@
m_header.m_allocated += needs_backwards_aligned;
//Check alignment
- priv_check_alignment(new_block);
+ algo_impl_t::check_alignment(new_block);
//If the backwards expansion has remaining bytes in the
//first bytes, fill them with a pattern
@@ -783,7 +701,7 @@
else if(prev_block->m_size >= needs_backwards_aligned/Alignment &&
0 == (prev_block->m_size % lcm)) {
//Erase old previous block, since we will change it
- m_header.m_imultiset.erase(Imultiset::iterator_to(*prev_block));
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
//Just merge the whole previous block
const std::size_t needs_backwards_aligned = prev_block->m_size*Alignment;
@@ -794,9 +712,7 @@
//Now update sizes
prev_block->m_size = prev_block->m_size + reuse->m_size;
assert(prev_block->m_size >= BlockCtrlUnits);
- priv_tail_size(prev_block, prev_block->m_size);
- priv_mark_as_allocated_block(prev_block);
- priv_check_alignment(prev_block);
+ priv_mark_new_allocated_block(prev_block);
//If the backwards expansion has remaining bytes in the
//first bytes, fill them with a pattern
@@ -814,134 +730,14 @@
}
template<class MutexFamily, class VoidPointer>
-inline void* rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_allocate_aligned(std::size_t nbytes, std::size_t alignment)
-{
- //Ensure power of 2
- if ((alignment & (alignment - std::size_t(1u))) != 0){
- //Alignment is not power of two
- assert((alignment & (alignment - std::size_t(1u))) != 0);
- return 0;
- }
-
- std::size_t real_size;
- if(alignment <= Alignment){
- return priv_allocate(allocate_new, nbytes, nbytes, real_size).first;
- }
-
- //We can find a aligned portion if we allocate a chunk that has alignment
- //nbytes + alignment bytes or more.
- std::size_t minimum_allocation = max_value(nbytes + alignment, std::size_t(MinBlockUnits*Alignment));
- //Since we will split that chunk, we must request a bit more memory
- //if the alignment is near the beginning of the buffer, because otherwise,
- //there is no space for a new chunk before the alignment.
- //
- // ____ Aligned here
- // |
- // -----------------------------------------------------
- // | MBU |
- // -----------------------------------------------------
- std::size_t request =
- minimum_allocation + (MinBlockUnits*Alignment - AllocatedCtrlBytes);
-
- //Now allocate the buffer
- void *buffer = priv_allocate(allocate_new, request, request, real_size).first;
- if(!buffer){
- return 0;
- }
- else if ((((std::size_t)(buffer)) % alignment) == 0){
- //If we are lucky and the buffer is aligned, just split it and
- //return the high part
- block_ctrl *first = priv_get_block(buffer);
- std::size_t old_size = first->m_size;
- const std::size_t first_min_units =
- max_value(priv_ceil_units(nbytes) + AllocatedCtrlUnits, std::size_t(MinBlockUnits));
- //We can create a new block in the end of the segment
- if(old_size >= (first_min_units + MinBlockUnits)){
- block_ctrl *second = new((char*)first + Alignment*first_min_units) block_ctrl;
- first->m_size = first_min_units;
- second->m_size = old_size - first->m_size;
- BOOST_ASSERT(second->m_size >= MinBlockUnits);
- priv_tail_size(first, first->m_size);
- priv_tail_size(second, second->m_size);
- priv_mark_as_allocated_block(second);
- this->priv_deallocate(priv_get_user_buffer(second));
- }
- return buffer;
- }
-
- //Buffer not aligned, find the aligned part.
- //
- // ____ Aligned here
- // |
- // -----------------------------------------------------
- // | MBU +more | ACB |
- // -----------------------------------------------------
- char *pos = (char*)
- ((std::size_t)((char*)buffer +
- //This is the minimum size of (2)
- (MinBlockUnits*Alignment - AllocatedCtrlBytes) +
- //This is the next MBU for the aligned memory
- AllocatedCtrlBytes +
- //This is the alignment trick
- alignment - 1) & -alignment);
-
- //Now obtain the address of the blocks
- block_ctrl *first = priv_get_block(buffer);
- block_ctrl *second = priv_get_block(pos);
-
- //Set the new size of the first block
- std::size_t old_size = first->m_size;
- first->m_size = ((char*)second - (char*)first)/Alignment;
- priv_tail_size(first, first->m_size);
- priv_mark_as_allocated_block(first);
-
- //Now check if we can create a new buffer in the end
- //
- // __"second" block
- // | __Aligned here
- // | | __"third" block
- // -----------|-----|-----|------------------------------
- // | MBU +more | ACB | (3) | BCU |
- // -----------------------------------------------------
- //This size will be the minimum size to be able to create a
- //new chunk in the end.
- const std::size_t second_min_units = max_value(std::size_t(MinBlockUnits),
- priv_ceil_units(nbytes) + AllocatedCtrlUnits );
-
- //Check if we can create a new block (of size MinBlockUnits) in the end of the segment
- if((old_size - first->m_size) >= (second_min_units + MinBlockUnits)){
- //Now obtain the address of the end block
- block_ctrl *third = new ((char*)second + Alignment*second_min_units)block_ctrl;
- second->m_size = second_min_units;
- third->m_size = old_size - first->m_size - second->m_size;
- BOOST_ASSERT(third->m_size >= MinBlockUnits);
- priv_tail_size(second, second->m_size);
- priv_tail_size(third, third->m_size);
- priv_mark_as_allocated_block(second);
- priv_mark_as_allocated_block(third);
- this->priv_deallocate(priv_get_user_buffer(third));
- }
- else{
- second->m_size = old_size - first->m_size;
- priv_tail_size(second, second->m_size);
- priv_mark_as_allocated_block(second);
- }
-
- this->priv_deallocate(priv_get_user_buffer(first));
- return priv_get_user_buffer(second);
-}
-
-template<class MutexFamily, class VoidPointer>
inline typename rbtree_best_fit<MutexFamily, VoidPointer>::multiallocation_iterator
rbtree_best_fit<MutexFamily, VoidPointer>::
- allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements)
+ allocate_many(std::size_t elem_bytes, std::size_t num_elements)
{
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- received_elements = min_elements;
- return priv_allocate_many(elem_size, min_elements, preferred_elements, received_elements);
+ return algo_impl_t::allocate_many(this, elem_bytes, num_elements);
}
template<class MutexFamily, class VoidPointer>
@@ -952,7 +748,7 @@
//-----------------------
boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
//-----------------------
- return priv_allocate_many(elem_sizes, n_elements, sizeof_element);
+ return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
}
template<class MutexFamily, class VoidPointer>
@@ -969,9 +765,10 @@
if(command & shrink_in_place){
bool success =
- this->priv_shrink(reuse_ptr, limit_size, preferred_size, received_size);
+ algo_impl_t::shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
}
+
typedef std::pair<void *, bool> return_type;
received_size = 0;
@@ -1019,112 +816,6 @@
}
template<class MutexFamily, class VoidPointer>
-typename rbtree_best_fit<MutexFamily, VoidPointer>::multiallocation_iterator
- rbtree_best_fit<MutexFamily, VoidPointer>::priv_allocate_many
- (const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
-{
- //Calculate the total size of all requests
- std::size_t total_request_units;
- total_request_units = 0;
- for(std::size_t i = 0; i < n_elements; ++i){
- std::size_t preferred_units = priv_get_total_units(elem_sizes[i]*sizeof_element);
- total_request_units += preferred_units;
- }
-
- std::size_t total_bytes = total_request_units*Alignment - AllocatedCtrlBytes;
-
- std::size_t received_size;
- std::pair<void *, bool> ret = priv_allocate
- (allocate_new, total_bytes, total_bytes, received_size, 0);
- if(!ret.first){
- return multiallocation_iterator();
- }
-
- block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ret.first) - AllocatedCtrlBytes);
- std::size_t received_units = block->m_size;
- char *block_address = (char*)block;
-
- total_request_units = 0;
-
- {
- std::size_t preferred_units;
- //If all have the same size, we don't need calculate it
- //every iteration
- for(std::size_t i = 0; i < n_elements; ++i){
- //If all have different size, we have to calculate it each iteration
- preferred_units = priv_get_total_units(elem_sizes[i]*sizeof_element);
- //This is the position where the new block must be created
- block_ctrl *new_block = new(block_address)block_ctrl;
- //The last block should take all the remaining space
- if((i + 1) == n_elements){
- new_block->m_size = received_units - total_request_units;
- }
- else{
- new_block->m_size = preferred_units;
- }
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_allocated_block(new_block);
- block_address += new_block->m_size*Alignment;
- total_request_units += new_block->m_size;
- }
- assert(total_request_units == received_units);
- }
- return multiallocation_iterator(block, n_elements);
-}
-
-template<class MutexFamily, class VoidPointer>
-typename rbtree_best_fit<MutexFamily, VoidPointer>::multiallocation_iterator
- rbtree_best_fit<MutexFamily, VoidPointer>::priv_allocate_many
- ( std::size_t elem_size, std::size_t min_elements
- , std::size_t preferred_elements, std::size_t &received_elements)
-{
- //Calculate the total size of all requests
- const std::size_t elem_units = priv_get_total_units(elem_size);
- const std::size_t total_min_usr_units = min_elements*elem_units - AllocatedCtrlUnits;
- const std::size_t total_preferred_usr_units = preferred_elements*elem_units - AllocatedCtrlUnits;
-
- std::size_t received_size;
- std::pair<void *, bool> ret = priv_allocate
- ( allocate_new, total_min_usr_units*Alignment
- , total_preferred_usr_units*Alignment, received_size, 0);
- if(!ret.first){
- received_elements = (received_size + AllocatedCtrlBytes)/elem_units;
- return multiallocation_iterator();
- }
-
- block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ret.first) - AllocatedCtrlBytes);
- std::size_t received_units = block->m_size;
- char *block_address = (char*)block;
-
- received_elements = received_units/elem_units;
- if(received_elements > preferred_elements){
- received_elements = preferred_elements;
- }
- std::size_t total_request_units = 0;
- {
- for(std::size_t i = 0; i < received_elements; ++i){
- //If all have different size, we have to calculate it each iteration
- //This is the position where the new block must be created
- block_ctrl *new_block = new(block_address)block_ctrl;
- //The last block should take all the remaining space
- if((i + 1) == received_elements){
- new_block->m_size = received_units - (received_elements-1)*elem_units;
- }
- else{
- new_block->m_size = elem_units;
- }
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_allocated_block(new_block);
- block_address += new_block->m_size*Alignment;
- total_request_units += new_block->m_size;
- }
- assert(total_request_units == received_units);
- }
- return multiallocation_iterator(block, received_elements);
-}
-template<class MutexFamily, class VoidPointer>
inline
typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *
rbtree_best_fit<MutexFamily, VoidPointer>::priv_get_block(const void *ptr)
@@ -1149,44 +840,6 @@
}
template<class MutexFamily, class VoidPointer>
-inline
-std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_ceil_units(std::size_t size)
-{
- return detail::get_rounded_size(size, Alignment)/Alignment;
-}
-
-template<class MutexFamily, class VoidPointer>
-inline
-std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_floor_units(std::size_t size)
-{ return size/Alignment; }
-
-template<class MutexFamily, class VoidPointer>
-inline
-std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_multiple_of_units(std::size_t size)
-{ return detail::get_rounded_size(size, Alignment); }
-
-template<class MutexFamily, class VoidPointer>
-inline
-void rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_check_alignment(const void *ptr)
-{
- const std::size_t remaining(std::size_t(ptr) & AlignmentMask);
- if(remaining){
- const void *p = (void*)(std::size_t(ptr) & ~AlignmentMask);
- (void)p;
- for(std::size_t i = 1; i < remaining; ++i){
- BOOST_ASSERT(detail::char_ptr_cast(p)[i] == (char)i);
- }
- }
- else{
- BOOST_ASSERT(((std::size_t)ptr) % Alignment == 0);
- }
-}
-
-template<class MutexFamily, class VoidPointer>
bool rbtree_best_fit<MutexFamily, VoidPointer>::
priv_expand (void *ptr
,const std::size_t min_size
@@ -1207,8 +860,8 @@
return true;
//Now translate it to Alignment units
- const std::size_t min_user_units = priv_ceil_units(min_size);
- const std::size_t preferred_user_units = priv_ceil_units(preferred_size);
+ const std::size_t min_user_units = algo_impl_t::ceil_units(min_size);
+ const std::size_t preferred_user_units = algo_impl_t::ceil_units(preferred_size);
//Some parameter checks
assert(min_user_units <= preferred_user_units);
@@ -1240,7 +893,7 @@
//Check if we can split the next one in two parts
if((merged_units - intended_units) >= BlockCtrlUnits){
//Now we have to update the data in the tree
- m_header.m_imultiset.erase(Imultiset::iterator_to(*next_block));
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block));
//This block is bigger than needed, split it in
//two blocks, the first one will be merged and
@@ -1267,7 +920,7 @@
//There is no free space to create a new node: just merge both blocks
else{
//Now we have to update the data in the tree
- m_header.m_imultiset.erase(Imultiset::iterator_to(*next_block));
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block));
//Write the new length
block->m_size = merged_units;
@@ -1280,80 +933,6 @@
return true;
}
-template<class MutexFamily, class VoidPointer>
-bool rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_shrink (void *ptr
- ,const std::size_t max_size
- ,const std::size_t preferred_size
- ,std::size_t &received_size)
-{
- //Obtain the real block
- block_ctrl *block = priv_get_block(ptr);
- std::size_t old_block_units = block->m_size;
-
- //The block must be marked as allocated
- assert(priv_is_allocated_block(block));
-
- //Check if alignment and block size are right
- priv_check_alignment(ptr);
-
- //Put this to a safe value
- received_size = (old_block_units - AllocatedCtrlUnits)*Alignment;
-
- //Now translate it to Alignment units
- const std::size_t max_user_units = priv_floor_units(max_size);
- const std::size_t preferred_user_units = priv_ceil_units(preferred_size);
-
- //Check if rounded max and preferred are possible correct
- if(max_user_units < preferred_user_units)
- return false;
-
- //Check if the block is smaller than the requested minimum
- std::size_t old_user_units = old_block_units - AllocatedCtrlUnits;
-
- if(old_user_units < preferred_user_units)
- return false;
-
- //If the block is smaller than the requested minimum
- if(old_user_units == preferred_user_units)
- return true;
-
- std::size_t shrunk_user_units =
- ((BlockCtrlUnits - AllocatedCtrlUnits) > preferred_user_units)
- ? (BlockCtrlUnits - AllocatedCtrlUnits)
- : preferred_user_units;
-
- //Some parameter checks
- if(max_user_units < shrunk_user_units)
- return false;
-
- //We must be able to create at least a new empty block
- if((old_user_units - shrunk_user_units) < BlockCtrlUnits ){
- return false;
- }
-
- //Now we can just rewrite the size of the old buffer
- block->m_size = shrunk_user_units + AllocatedCtrlUnits;
- assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, block->m_size);
-
- //Update new size
- received_size = shrunk_user_units*Alignment;
-
- //We create the new block
- block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + block->m_size*Alignment)) block_ctrl;
-
- //Write control data to simulate this new block was previously allocated
- //and deallocate it
- priv_mark_as_allocated_block(new_block);
- new_block->m_size = old_block_units - block->m_size;
- assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
- this->priv_deallocate(priv_get_user_buffer(new_block));
- return true;
-}
-
template<class MutexFamily, class VoidPointer> inline
void rbtree_best_fit<MutexFamily, VoidPointer>::priv_tail_size
(typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *ptr, std::size_t size)
@@ -1404,8 +983,8 @@
,std::size_t &received_size)
{
std::size_t upper_nunits = nunits + BlockCtrlUnits;
- imultiset_iterator ittree = Imultiset::iterator_to(*block);
-
+ imultiset_iterator it_old = Imultiset::s_iterator_to(*block);
+/*
if (block->m_size >= upper_nunits){
//Now we have to update the data in the tree
m_header.m_imultiset.erase(ittree);
@@ -1436,7 +1015,49 @@
assert(0);
return 0;
}
+*/
+ if (block->m_size >= upper_nunits){
+ //This block is bigger than needed, split it in
+ //two blocks, the first's size will be "units" and
+ //the second's size "block->m_size-units"
+ std::size_t block_old_size = block->m_size;
+ block->m_size = nunits;
+ assert(block->m_size >= BlockCtrlUnits);
+ priv_tail_size(block, block->m_size);
+
+ //This is the remaining block
+ block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
+ (detail::char_ptr_cast(block) + Alignment*nunits))block_ctrl;
+ new_block->m_size = block_old_size - nunits;
+ assert(new_block->m_size >= BlockCtrlUnits);
+ priv_tail_size(new_block, new_block->m_size);
+ priv_mark_as_free_block(new_block);
+ imultiset_iterator it_hint;
+ if(it_old == m_header.m_imultiset.begin()
+ || (--imultiset_iterator(it_old))->m_size < new_block->m_size){
+ //option a: slow but secure
+ //m_header.m_imultiset.insert(m_header.m_imultiset.erase(it_old), *new_block);
+ //option b: Construct an empty node and swap
+ //Imultiset::init_node(*new_block);
+ //block->swap_nodes(*new_block);
+ //option c: replace the node directly
+ m_header.m_imultiset.replace_node(Imultiset::s_iterator_to(*it_old), *new_block);
+ }
+ else{
+ //Now we have to update the data in the tree
+ m_header.m_imultiset.erase(it_old);
+ m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *new_block);
+ }
+
+ }
+ else if (block->m_size >= nunits){
+ m_header.m_imultiset.erase(it_old);
+ }
+ else{
+ assert(0);
+ return 0;
+ }
//We need block_ctrl for deallocation stuff, so
//return memory user can overwrite
m_header.m_allocated += block->m_size*Alignment;
@@ -1446,7 +1067,7 @@
priv_mark_as_allocated_block(block);
//Check alignment
- priv_check_alignment(block);
+ algo_impl_t::check_alignment(block);
//Clear the memory occupied by the tree hook, since this won't be
//cleared with zero_free_memory
@@ -1477,7 +1098,7 @@
assert(block->m_size == priv_tail_size(block));
//Check if alignment and block size are right
- priv_check_alignment(addr);
+ algo_impl_t::check_alignment(addr);
std::size_t block_old_size = Alignment*block->m_size;
assert(m_header.m_allocated >= block_old_size);
@@ -1496,7 +1117,7 @@
block->m_size += next_block->m_size;
assert(block->m_size >= BlockCtrlUnits);
priv_tail_size(block, block->m_size);
- m_header.m_imultiset.erase(Imultiset::iterator_to(*next_block));
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block));
}
//Get the previous block
@@ -1510,7 +1131,7 @@
prev_block->m_size += block->m_size;
assert(prev_block->m_size >= BlockCtrlUnits);
priv_tail_size(prev_block, prev_block->m_size);
- m_header.m_imultiset.erase(Imultiset::iterator_to(*prev_block));
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
block_to_insert = prev_block;
}
Modified: trunk/boost/interprocess/mem_algo/simple_seq_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/simple_seq_fit.hpp (original)
+++ trunk/boost/interprocess/mem_algo/simple_seq_fit.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -22,15 +22,14 @@
#include <boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp>
#include <boost/interprocess/offset_ptr.hpp>
-/*!\file
- Describes sequential fit algorithm used to allocate objects in shared memory.
-*/
+//!\file
+//!Describes sequential fit algorithm used to allocate objects in shared memory.
namespace boost {
namespace interprocess {
-/*!This class implements the simple sequential fit algorithm with a simply
- linked list of free buffers.*/
+//!This class implements the simple sequential fit algorithm with a simply
+//!linked list of free buffers.
template<class MutexFamily, class VoidPointer>
class simple_seq_fit
: public detail::simple_seq_fit_impl<MutexFamily, VoidPointer>
@@ -40,9 +39,9 @@
/// @endcond
public:
- /*!Constructor. "size" is the total size of the managed memory segment,
- "extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit)
- offset that the allocator should not use at all.*/
+ //!Constructor. "size" is the total size of the managed memory segment,
+ //!"extra_hdr_bytes" indicates the extra bytes beginning in the sizeof(simple_seq_fit)
+ //!offset that the allocator should not use at all.*/
simple_seq_fit (std::size_t size, std::size_t extra_hdr_bytes)
: base_t(size, extra_hdr_bytes){}
};
Modified: trunk/boost/interprocess/offset_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/offset_ptr.hpp (original)
+++ trunk/boost/interprocess/offset_ptr.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -25,10 +25,10 @@
#include <boost/assert.hpp>
#include <iterator>
-/*!\file
- Describes a smart pointer that stores the offset between this pointer and
- target pointee, called offset_ptr.
-*/
+//!\file
+//!Describes a smart pointer that stores the offset between this pointer and
+//!target pointee, called offset_ptr.
+
namespace boost {
//Predeclarations
@@ -40,12 +40,12 @@
namespace interprocess {
-/*!A smart pointer that stores the offset between between the pointer and the
- the object it points. This allows offset allows special properties, since
- the pointer is independent from the address address of the pointee, if the
- pointer and the pointee are still separated by the same offset. This feature
- converts offset_ptr in a smart pointer that can be placed in shared memory and
- memory mapped files mapped in different addresses in every process.*/
+//!A smart pointer that stores the offset between between the pointer and the
+//!the object it points. This allows offset allows special properties, since
+//!the pointer is independent from the address address of the pointee, if the
+//!pointer and the pointee are still separated by the same offset. This feature
+//!converts offset_ptr in a smart pointer that can be placed in shared memory and
+//!memory mapped files mapped in different addresses in every process.
template <class PointedType>
class offset_ptr
{
@@ -98,113 +98,134 @@
public: //Public Functions
- /*!Constructor from raw pointer (allows "0" pointer conversion). Never throws.*/
+ //!Constructor from raw pointer (allows "0" pointer conversion).
+ //!Never throws.
offset_ptr(pointer ptr = 0) { this->set_offset(ptr); }
- /*!Constructor from other pointer. Never throws.*/
+ //!Constructor from other pointer.
+ //!Never throws.
template <class T>
offset_ptr(T *ptr)
{ pointer p (ptr); (void)p; this->set_offset(p); }
- /*!Constructor from other offset_ptr */
+ //!Constructor from other offset_ptr
+ //!Never throws.
offset_ptr(const offset_ptr& ptr)
{ this->set_offset(ptr.get()); }
- /*!Constructor from other offset_ptr. If pointers of pointee types are
- convertible, offset_ptrs will be convertibles. Never throws.*/
+ //!Constructor from other offset_ptr. If pointers of pointee types are
+ //!convertible, offset_ptrs will be convertibles. Never throws.
template<class T2>
offset_ptr(const offset_ptr<T2> &ptr)
{ pointer p(ptr.get()); (void)p; this->set_offset(p); }
- /*!Emulates static_cast operator. Never throws. */
+ //!Emulates static_cast operator.
+ //!Never throws.
template<class Y>
offset_ptr(const offset_ptr<Y> & r, detail::static_cast_tag)
{ this->set_offset(static_cast<PointedType*>(r.get())); }
- /*!Emulates const_cast operator. Never throws.*/
+ //!Emulates const_cast operator.
+ //!Never throws.
template<class Y>
offset_ptr(const offset_ptr<Y> & r, detail::const_cast_tag)
{ this->set_offset(const_cast<PointedType*>(r.get())); }
- /*!Emulates dynamic_cast operator. Never throws.*/
+ //!Emulates dynamic_cast operator.
+ //!Never throws.
template<class Y>
offset_ptr(const offset_ptr<Y> & r, detail::dynamic_cast_tag)
{ this->set_offset(dynamic_cast<PointedType*>(r.get())); }
- /*!Emulates reinterpret_cast operator. Never throws.*/
+ //!Emulates reinterpret_cast operator.
+ //!Never throws.
template<class Y>
offset_ptr(const offset_ptr<Y> & r, detail::reinterpret_cast_tag)
{ this->set_offset(reinterpret_cast<PointedType*>(r.get())); }
- /*!Obtains raw pointer from offset. Never throws.*/
+ //!Obtains raw pointer from offset.
+ //!Never throws.
pointer get()const
{ return (pointer)this->get_pointer(); }
- /*!Pointer-like -> operator. It can return 0 pointer. Never throws.*/
+ //!Pointer-like -> operator. It can return 0 pointer.
+ //!Never throws.
pointer operator->() const
{ return this->get(); }
- /*!Dereferencing operator, if it is a null offset_ptr behavior
- is undefined. Never throws.*/
+ //!Dereferencing operator, if it is a null offset_ptr behavior
+ //! is undefined. Never throws.
reference operator* () const
{ return *(this->get()); }
- /*!Indexing operator. Never throws.*/
+ //!Indexing operator.
+ //!Never throws.
reference operator[](std::ptrdiff_t idx) const
{ return this->get()[idx]; }
- /*!Assignment from pointer (saves extra conversion). Never throws.*/
+ //!Assignment from pointer (saves extra conversion).
+ //!Never throws.
offset_ptr& operator= (pointer from)
{ this->set_offset(from); return *this; }
- /*!Assignment from other offset_ptr. Never throws.*/
+ //!Assignment from other offset_ptr.
+ //!Never throws.
offset_ptr& operator= (const offset_ptr & pt)
{ pointer p(pt.get()); (void)p; this->set_offset(p); return *this; }
- /*!Assignment from related offset_ptr. If pointers of pointee types
- are assignable, offset_ptrs will be assignable. Never throws.*/
+ //!Assignment from related offset_ptr. If pointers of pointee types
+ //! are assignable, offset_ptrs will be assignable. Never throws.
template <class T2>
offset_ptr& operator= (const offset_ptr<T2> & pt)
{ pointer p(pt.get()); this->set_offset(p); return *this; }
- /*!offset_ptr + std::ptrdiff_t. Never throws.*/
+ //!offset_ptr + std::ptrdiff_t.
+ //!Never throws.
offset_ptr operator+ (std::ptrdiff_t offset) const
{ return offset_ptr(this->get()+offset); }
- /*!offset_ptr - std::ptrdiff_t. Never throws.*/
+ //!offset_ptr - std::ptrdiff_t.
+ //!Never throws.
offset_ptr operator- (std::ptrdiff_t offset) const
{ return offset_ptr(this->get()-offset); }
- /*!offset_ptr += std::ptrdiff_t. Never throws.*/
+ //!offset_ptr += std::ptrdiff_t.
+ //!Never throws.
offset_ptr &operator+= (std::ptrdiff_t offset)
{ this->inc_offset(offset * sizeof (PointedType)); return *this; }
- /*!offset_ptr -= std::ptrdiff_t. Never throws.*/
+ //!offset_ptr -= std::ptrdiff_t.
+ //!Never throws.
offset_ptr &operator-= (std::ptrdiff_t offset)
{ this->dec_offset(offset * sizeof (PointedType)); return *this; }
- /*!++offset_ptr. Never throws.*/
+ //!++offset_ptr.
+ //!Never throws.
offset_ptr& operator++ (void)
{ this->inc_offset(sizeof (PointedType)); return *this; }
- /*!offset_ptr++. Never throws.*/
+ //!offset_ptr++.
+ //!Never throws.
offset_ptr operator++ (int)
{ offset_ptr temp(*this); ++*this; return temp; }
- /*!--offset_ptr. Never throws.*/
+ //!--offset_ptr.
+ //!Never throws.
offset_ptr& operator-- (void)
{ this->dec_offset(sizeof (PointedType)); return *this; }
- /*!offset_ptr--. Never throws.*/
+ //!offset_ptr--.
+ //!Never throws.
offset_ptr operator-- (int)
{ offset_ptr temp(*this); --*this; return temp; }
- /*!safe bool conversion operator. Never throws.*/
+ //!safe bool conversion operator.
+ //!Never throws.
operator unspecified_bool_type() const
{ return this->get()? &self_t::unspecified_bool_type_func : 0; }
- /*!Not operator. Not needed in theory, but improves portability.
- Never throws.*/
+ //!Not operator. Not needed in theory, but improves portability.
+ //!Never throws
bool operator! () const
{ return this->get() == 0; }
/*
@@ -217,65 +238,76 @@
*/
};
-/*!offset_ptr<T1> == offset_ptr<T2>. Never throws.*/
+//!offset_ptr<T1> == offset_ptr<T2>.
+//!Never throws.
template<class T1, class T2>
inline bool operator== (const offset_ptr<T1> &pt1,
const offset_ptr<T2> &pt2)
{ return pt1.get() == pt2.get(); }
-/*!offset_ptr<T1> != offset_ptr<T2>. Never throws.*/
+//!offset_ptr<T1> != offset_ptr<T2>.
+//!Never throws.
template<class T1, class T2>
inline bool operator!= (const offset_ptr<T1> &pt1,
const offset_ptr<T2> &pt2)
{ return pt1.get() != pt2.get(); }
-/*!offset_ptr<T1> < offset_ptr<T2>. Never throws.*/
+//!offset_ptr<T1> < offset_ptr<T2>.
+//!Never throws.
template<class T1, class T2>
inline bool operator< (const offset_ptr<T1> &pt1,
const offset_ptr<T2> &pt2)
{ return pt1.get() < pt2.get(); }
-/*!offset_ptr<T1> <= offset_ptr<T2>. Never throws.*/
+//!offset_ptr<T1> <= offset_ptr<T2>.
+//!Never throws.
template<class T1, class T2>
inline bool operator<= (const offset_ptr<T1> &pt1,
const offset_ptr<T2> &pt2)
{ return pt1.get() <= pt2.get(); }
-/*!offset_ptr<T1> > offset_ptr<T2>. Never throws.*/
+//!offset_ptr<T1> > offset_ptr<T2>.
+//!Never throws.
template<class T1, class T2>
inline bool operator> (const offset_ptr<T1> &pt1,
const offset_ptr<T2> &pt2)
{ return pt1.get() > pt2.get(); }
-/*!offset_ptr<T1> >= offset_ptr<T2>. Never throws.*/
+//!offset_ptr<T1> >= offset_ptr<T2>.
+//!Never throws.
template<class T1, class T2>
inline bool operator>= (const offset_ptr<T1> &pt1,
const offset_ptr<T2> &pt2)
{ return pt1.get() >= pt2.get(); }
-/*!operator<< */
+//!operator<<
+//!for offset ptr
template<class E, class T, class Y>
inline std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, offset_ptr<Y> const & p)
{ return os << p.get(); }
-/*!operator>> */
+//!operator>>
+//!for offset ptr
template<class E, class T, class Y>
inline std::basic_istream<E, T> & operator>>
(std::basic_istream<E, T> & os, offset_ptr<Y> & p)
{ Y * tmp; return os >> tmp; p = tmp; }
-/*!std::ptrdiff_t + offset_ptr */
+//!std::ptrdiff_t + offset_ptr
+//!operation
template<class T>
inline offset_ptr<T> operator+(std::ptrdiff_t diff, const offset_ptr<T>& right)
{ return right + diff; }
-/*!offset_ptr - offset_ptr */
+//!offset_ptr - offset_ptr
+//!operation
template<class T, class T2>
inline std::ptrdiff_t operator- (const offset_ptr<T> &pt, const offset_ptr<T2> &pt2)
{ return pt.get()- pt2.get(); }
-/*!swap specialization */
+//!swap specialization
+//!for offset_ptr
template<class T>
inline void swap (boost::interprocess::offset_ptr<T> &pt,
boost::interprocess::offset_ptr<T> &pt2)
@@ -343,8 +375,8 @@
//#if !defined(_MSC_VER) || (_MSC_VER >= 1400)
namespace interprocess {
//#endif
-/*!get_pointer() enables boost::mem_fn to recognize offset_ptr.
- Never throws.*/
+//!get_pointer() enables boost::mem_fn to recognize offset_ptr.
+//!Never throws.
template<class T>
inline T * get_pointer(boost::interprocess::offset_ptr<T> const & p)
{ return p.get(); }
Modified: trunk/boost/interprocess/segment_manager.hpp
==============================================================================
--- trunk/boost/interprocess/segment_manager.hpp (original)
+++ trunk/boost/interprocess/segment_manager.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -30,6 +30,8 @@
#include <boost/interprocess/offset_ptr.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <cstddef> //std::size_t
#include <string> //char_traits
#include <new> //std::nothrow
@@ -118,10 +120,9 @@
//Experimental. Dont' use.
//!Allocates n_elements of
//!elem_size bytes. Throws bad_alloc on failure.
- multiallocation_iterator allocate_many
- (std::size_t elem_bytes, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements)
+ multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements)
{
- multiallocation_iterator ret = MemoryAlgorithm::allocate_many(elem_bytes, min_elements, preferred_elements, received_elements);
+ multiallocation_iterator ret = MemoryAlgorithm::allocate_many(elem_bytes, num_elements);
if(!ret) throw bad_alloc();
return ret;
}
@@ -138,8 +139,8 @@
//!Allocates n_elements of
//!elem_size bytes. Returns a default constructed iterator on failure.
- multiallocation_iterator allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements, std::nothrow_t)
- { return MemoryAlgorithm::allocate_many(elem_size, min_elements, preferred_elements, received_elements); }
+ multiallocation_iterator allocate_many(std::size_t elem_bytes, std::size_t num_elements, std::nothrow_t)
+ { return MemoryAlgorithm::allocate_many(elem_bytes, num_elements); }
//!Allocates n_elements, each one of
//!element_lenghts[i]*sizeof_element bytes.
@@ -208,7 +209,8 @@
bool check_sanity()
{ return MemoryAlgorithm::check_sanity(); }
- //!Writes to zero free memory (memory not yet allocated) of the memory algorithm
+ //!Writes to zero free memory (memory not yet allocated)
+ //!of the memory algorithm
void zero_free_memory()
{ MemoryAlgorithm::zero_free_memory(); }
@@ -612,6 +614,35 @@
(m_header.m_unique_index.end(), unique_transform());
}
+ //!This is the default allocator to allocate types T
+ //!from this managed segment
+ template<class T>
+ struct allocator
+ {
+ typedef boost::interprocess::allocator<T, segment_manager> type;
+ };
+
+ //!Returns an instance of the default allocator for type T
+ //!initialized that allocates memory from this segment manager.
+ template<class T>
+ typename allocator<T>::type
+ get_allocator()
+ { return typename allocator<T>::type(this); }
+
+ //!This is the default deleter to delete types T
+ //!from this managed segment.
+ template<class T>
+ struct deleter
+ {
+ typedef boost::interprocess::deleter<T, segment_manager> type;
+ };
+
+ //!Returns an instance of the default allocator for type T
+ //!initialized that allocates memory from this segment manager.
+ template<class T>
+ typename deleter<T>::type
+ get_deleter()
+ { return typename deleter<T>::type(this); }
/// @cond
//!Generic named/anonymous new function. Offers all the possibilities,
Modified: trunk/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- trunk/boost/interprocess/shared_memory_object.hpp (original)
+++ trunk/boost/interprocess/shared_memory_object.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -63,7 +63,7 @@
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
//!Otherwise throws an error.
shared_memory_object(open_or_create_t, const char *name, mode_t mode)
- { this->priv_open_or_create(detail::DoCreateOrOpen, name, mode); }
+ { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode); }
//!Tries to open a shared memory object with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
@@ -105,15 +105,20 @@
//!Swaps the shared_memory_objects. Does not throw
void swap(shared_memory_object &other);
- //!Erases a shared memory object from the system. Never throws
+ //!Erases a shared memory object from the system.
+ //!Returns false on error. Never throws
static bool remove(const char *name);
//!Sets the size of the shared memory mapping
void truncate(offset_t length);
- //!Closes the shared memory mapping. All mapped regions are still
- //!valid after destruction. The shared memory object still exists and
- //!can be newly opened.
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. All mapped regions are still
+ //!valid after destruction. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~shared_memory_object();
//!Returns the name of the file.
@@ -207,7 +212,7 @@
case detail::DoCreate:
m_handle = detail::create_new_file(shmfile.c_str(), mode, true);
break;
- case detail::DoCreateOrOpen:
+ case detail::DoOpenOrCreate:
m_handle = detail::create_or_open_file(shmfile.c_str(), mode, true);
break;
default:
@@ -275,7 +280,7 @@
mode_t mode)
{
bool slash_added = filename[0] != '/';
- //First add precedding "/"
+ //First add preceding "/"
m_filename.clear();
if(slash_added){
m_filename = '/';
@@ -302,7 +307,7 @@
case detail::DoCreate:
oflag |= (O_CREAT | O_EXCL);
break;
- case detail::DoCreateOrOpen:
+ case detail::DoOpenOrCreate:
oflag |= O_CREAT;
break;
default:
@@ -334,7 +339,7 @@
{
try{
std::string file_str;
- //First add precedding "/"
+ //First add preceding "/"
if(filename[0] != '/'){
file_str = '/';
}
Modified: trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -4,7 +4,7 @@
//
// (C) Copyright Peter Dimov and Multi Media Ltd. 2001, 2002, 2003
// (C) Copyright Peter Dimov 2004-2005
-// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2006-2007. 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)
//
@@ -24,7 +24,6 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/checked_delete.hpp>
-#include <boost/throw_exception.hpp>
#include <boost/interprocess/smart_ptr/detail/bad_weak_ptr.hpp>
#include <boost/interprocess/smart_ptr/detail/sp_counted_impl.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -35,36 +34,36 @@
namespace interprocess {
namespace detail{
-template<class T, class A, class D>
+template<class T, class VoidAllocator, class Deleter>
class weak_count;
-template<class T, class A, class D>
+template<class T, class VoidAllocator, class Deleter>
class shared_count
{
public:
typedef typename detail::pointer_to_other
- <typename A::pointer, T>::type pointer;
+ <typename VoidAllocator::pointer, T>::type pointer;
private:
- typedef sp_counted_impl_pd<A, D> counted_impl;
+ typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
typedef typename detail::pointer_to_other
- <typename A::pointer, counted_impl>::type counted_impl_ptr;
+ <typename VoidAllocator::pointer, counted_impl>::type counted_impl_ptr;
typedef typename detail::pointer_to_other
- <typename A::pointer, sp_counted_base>::type counted_base_ptr;
- typedef typename A::template rebind
+ <typename VoidAllocator::pointer, sp_counted_base>::type counted_base_ptr;
+ typedef typename VoidAllocator::template rebind
<counted_impl>::other counted_impl_allocator;
typedef typename detail::pointer_to_other
- <typename A::pointer, const D>::type const_deleter_pointer;
+ <typename VoidAllocator::pointer, const Deleter>::type const_deleter_pointer;
typedef typename detail::pointer_to_other
- <typename A::pointer, const A>::type const_allocator_pointer;
+ <typename VoidAllocator::pointer, const VoidAllocator>::type const_allocator_pointer;
pointer m_px;
counted_impl_ptr m_pi;
- template <class T2, class A2, class D2>
+ template <class T2, class VoidAllocator2, class Deleter2>
friend class weak_count;
- template <class T2, class A2, class D2>
+ template <class T2, class VoidAllocator2, class Deleter2>
friend class shared_count;
public:
@@ -74,7 +73,7 @@
{}
template <class Ptr>
- shared_count(const Ptr &p, const A &a, D d)
+ shared_count(const Ptr &p, const VoidAllocator &a, Deleter d)
: m_px(p), m_pi(0)
{
BOOST_TRY{
@@ -85,7 +84,7 @@
scoped_ptr<counted_impl,
scoped_ptr_dealloc_functor<counted_impl_allocator> >
deallocator(m_pi, alloc);
- //It's more correct to use A::construct but
+ //It's more correct to use VoidAllocator::construct but
//this needs copy constructor and we don't like it
new(detail::get_pointer(m_pi))counted_impl(p, a, d);
deallocator.release();
@@ -110,18 +109,18 @@
//this is a test
template<class Y>
- explicit shared_count(shared_count<Y, A, D> const & r)
+ explicit shared_count(shared_count<Y, VoidAllocator, Deleter> const & r)
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
{ if( m_pi != 0 ) m_pi->add_ref_copy(); }
//this is a test
template<class Y>
- explicit shared_count(const pointer & ptr, shared_count<Y, A, D> const & r)
+ explicit shared_count(const pointer & ptr, shared_count<Y, VoidAllocator, Deleter> const & r)
: m_px(ptr), m_pi(r.m_pi) // nothrow
{ if( m_pi != 0 ) m_pi->add_ref_copy(); }
/*
- explicit shared_count(weak_count<Y, A, D> const & r)
+ explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
// throws bad_weak_ptr when r.use_count() == 0
: m_pi( r.m_pi )
{
@@ -131,12 +130,12 @@
}
*/
template<class Y>
- explicit shared_count(weak_count<Y, A, D> const & r)
+ explicit shared_count(weak_count<Y, VoidAllocator, Deleter> const & r)
// throws bad_weak_ptr when r.use_count() == 0
: m_px(r.m_px), m_pi( r.m_pi )
{
if( m_pi == 0 || !m_pi->add_ref_lock() ){
- boost::throw_exception( boost::interprocess::bad_weak_ptr() );
+ throw( boost::interprocess::bad_weak_ptr() );
}
}
@@ -159,7 +158,7 @@
}
template<class Y>
- shared_count & operator= (shared_count<Y, A, D> const & r) // nothrow
+ shared_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
{
m_px = r.m_px;
counted_impl_ptr tmp = r.m_pi;
@@ -186,45 +185,45 @@
// const_allocator_pointer get_allocator() const
// { return m_pi ? m_pi->get_allocator() : 0; }
- template<class T2, class A2, class D2>
- bool internal_equal (shared_count<T2, A2, D2> const & other) const
+ template<class T2, class VoidAllocator2, class Deleter2>
+ bool internal_equal (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
{ return this->m_pi == other.m_pi; }
- template<class T2, class A2, class D2>
- bool internal_less (shared_count<T2, A2, D2> const & other) const
+ template<class T2, class VoidAllocator2, class Deleter2>
+ bool internal_less (shared_count<T2, VoidAllocator2, Deleter2> const & other) const
{ return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
};
-template<class T, class A, class D, class T2, class A2, class D2> inline
-bool operator==(shared_count<T, A, D> const & a, shared_count<T2, A2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
+bool operator==(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
{ return a.internal_equal(b); }
-template<class T, class A, class D, class T2, class A2, class D2> inline
-bool operator<(shared_count<T, A, D> const & a, shared_count<T2, A2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
+bool operator<(shared_count<T, VoidAllocator, Deleter> const & a, shared_count<T2, VoidAllocator2, Deleter2> const & b)
{ return a.internal_less(b); }
-template<class T, class A, class D>
+template<class T, class VoidAllocator, class Deleter>
class weak_count
{
public:
typedef typename detail::pointer_to_other
- <typename A::pointer, T>::type pointer;
+ <typename VoidAllocator::pointer, T>::type pointer;
private:
- typedef sp_counted_impl_pd<A, D> counted_impl;
+ typedef sp_counted_impl_pd<VoidAllocator, Deleter> counted_impl;
typedef typename detail::pointer_to_other
- <typename A::pointer, counted_impl>::type counted_impl_ptr;
+ <typename VoidAllocator::pointer, counted_impl>::type counted_impl_ptr;
typedef typename detail::pointer_to_other
- <typename A::pointer, sp_counted_base>::type counted_base_ptr;
+ <typename VoidAllocator::pointer, sp_counted_base>::type counted_base_ptr;
pointer m_px;
counted_impl_ptr m_pi;
- template <class T2, class A2, class D2>
+ template <class T2, class VoidAllocator2, class Deleter2>
friend class weak_count;
- template <class T2, class A2, class D2>
+ template <class T2, class VoidAllocator2, class Deleter2>
friend class shared_count;
public:
@@ -233,7 +232,7 @@
{}
template <class Y>
- explicit weak_count(shared_count<Y, A, D> const & r)
+ explicit weak_count(shared_count<Y, VoidAllocator, Deleter> const & r)
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
{ if(m_pi != 0) m_pi->weak_add_ref(); }
@@ -242,7 +241,7 @@
{ if(m_pi != 0) m_pi->weak_add_ref(); }
template<class Y>
- weak_count(weak_count<Y, A, D> const & r)
+ weak_count(weak_count<Y, VoidAllocator, Deleter> const & r)
: m_px(r.m_px), m_pi(r.m_pi) // nothrow
{ if(m_pi != 0) m_pi->weak_add_ref(); }
@@ -250,7 +249,7 @@
{ if(m_pi != 0) m_pi->weak_release(); }
template<class Y>
- weak_count & operator= (shared_count<Y, A, D> const & r) // nothrow
+ weak_count & operator= (shared_count<Y, VoidAllocator, Deleter> const & r) // nothrow
{
m_px = r.m_px;
counted_impl_ptr tmp = r.m_pi;
@@ -273,7 +272,7 @@
{ m_px = ptr; }
template<class Y>
- weak_count & operator= (weak_count<Y, A, D> const& r) // nothrow
+ weak_count & operator= (weak_count<Y, VoidAllocator, Deleter> const& r) // nothrow
{
counted_impl_ptr tmp = r.m_pi;
if(tmp != 0) tmp->weak_add_ref();
@@ -288,21 +287,21 @@
long use_count() const // nothrow
{ return m_pi != 0? m_pi->use_count() : 0; }
- template<class T2, class A2, class D2>
- bool internal_equal (weak_count<T2, A2, D2> const & other) const
+ template<class T2, class VoidAllocator2, class Deleter2>
+ bool internal_equal (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
{ return this->m_pi == other.m_pi; }
- template<class T2, class A2, class D2>
- bool internal_less (weak_count<T2, A2, D2> const & other) const
+ template<class T2, class VoidAllocator2, class Deleter2>
+ bool internal_less (weak_count<T2, VoidAllocator2, Deleter2> const & other) const
{ return std::less<counted_base_ptr>()(this->m_pi, other.m_pi); }
};
-template<class T, class A, class D, class T2, class A2, class D2> inline
-bool operator==(weak_count<T, A, D> const & a, weak_count<T2, A2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
+bool operator==(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
{ return a.internal_equal(b); }
-template<class T, class A, class D, class T2, class A2, class D2> inline
-bool operator<(weak_count<T, A, D> const & a, weak_count<T2, A2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class T2, class VoidAllocator2, class Deleter2> inline
+bool operator<(weak_count<T, VoidAllocator, Deleter> const & a, weak_count<T2, VoidAllocator2, Deleter2> const & b)
{ return a.internal_less(b); }
} // namespace detail
Modified: trunk/boost/interprocess/smart_ptr/enable_shared_from_this.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/enable_shared_from_this.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/enable_shared_from_this.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -21,6 +21,9 @@
#include <boost/interprocess/smart_ptr/weak_ptr.hpp>
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
+//!\file
+//!Describes an utility to form a shared pointer from this
+
namespace boost{
namespace interprocess{
Modified: trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/intrusive_ptr.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -14,9 +14,8 @@
#ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
#define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
-/*!\file
- Describes an intrusive ownership pointer.
-*/
+//!\file
+//!Describes an intrusive ownership pointer.
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
@@ -31,27 +30,27 @@
namespace boost {
namespace interprocess {
-/*!The intrusive_ptr class template stores a pointer to an object
- with an embedded reference count. intrusive_ptr is parameterized on
- T (the type of the object pointed to) and VoidPointer(a void pointer type
- that defines the type of pointer that intrusive_ptr will store).
- intrusive_ptr<T, void *> defines a class with a T* member whereas
- intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.
- Relies on unqualified calls to:
-
- void intrusive_ptr_add_ref(T * p);
- void intrusive_ptr_release(T * p);
-
- with (p != 0)
-
- The object is responsible for destroying itself.*/
+//!The intrusive_ptr class template stores a pointer to an object
+//!with an embedded reference count. intrusive_ptr is parameterized on
+//!T (the type of the object pointed to) and VoidPointer(a void pointer type
+//!that defines the type of pointer that intrusive_ptr will store).
+//!intrusive_ptr<T, void *> defines a class with a T* member whereas
+//!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.
+//!Relies on unqualified calls to:
+//!
+//! void intrusive_ptr_add_ref(T * p);
+//! void intrusive_ptr_release(T * p);
+//!
+//! with (p != 0)
+//!
+//!The object is responsible for destroying itself.
template<class T, class VoidPointer>
class intrusive_ptr
{
public:
- /*!Provides the type of the internal stored pointer.*/
+ //!Provides the type of the internal stored pointer.
typedef typename detail::pointer_to_other<VoidPointer, T>::type pointer;
- /*!Provides the type of the stored pointer.*/
+ //!Provides the type of the stored pointer.
typedef T element_type;
/// @cond
@@ -62,28 +61,29 @@
/// @endcond
public:
- /*!Constructor. Initializes internal pointer to 0. Does not throw*/
+ //!Constructor. Initializes internal pointer to 0.
+ //!Does not throw
intrusive_ptr(): m_ptr(0)
{}
- /*!Constructor. Copies pointer and if "p" is not zero and
- "add_ref" is true calls intrusive_ptr_add_ref(get_pointer(p)).
- Does not throw*/
+ //!Constructor. Copies pointer and if "p" is not zero and
+ //!"add_ref" is true calls intrusive_ptr_add_ref(get_pointer(p)).
+ //!Does not throw
intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p)
{
if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(detail::get_pointer(m_ptr));
}
- /*!Copy constructor. Copies the internal pointer and if "p" is not
- zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw*/
+ //!Copy constructor. Copies the internal pointer and if "p" is not
+ //!zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw
intrusive_ptr(intrusive_ptr const & rhs)
: m_ptr(rhs.m_ptr)
{
if(m_ptr != 0) intrusive_ptr_add_ref(detail::get_pointer(m_ptr));
}
- /*!Constructor from related. Copies the internal pointer and if "p" is not
- zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw*/
+ //!Constructor from related. Copies the internal pointer and if "p" is not
+ //!zero calls intrusive_ptr_add_ref(get_pointer(p)). Does not throw
template<class U> intrusive_ptr
(intrusive_ptr<U, VP> const & rhs)
: m_ptr(rhs.get())
@@ -91,23 +91,23 @@
if(m_ptr != 0) intrusive_ptr_add_ref(detail::get_pointer(m_ptr));
}
- /*!Destructor. If internal pointer is not 0, calls
- intrusive_ptr_release(get_pointer(m_ptr)). Does not throw*/
+ //!Destructor. If internal pointer is not 0, calls
+ //!intrusive_ptr_release(get_pointer(m_ptr)). Does not throw
~intrusive_ptr()
{
if(m_ptr != 0) intrusive_ptr_release(detail::get_pointer(m_ptr));
}
- /*!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
- Does not throw*/
+ //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
+ //!Does not throw
intrusive_ptr & operator=(intrusive_ptr const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
- /*!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
- Does not throw*/
+ //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
+ //!Does not throw
template<class U> intrusive_ptr & operator=
(intrusive_ptr<U, VP> const & rhs)
{
@@ -115,43 +115,51 @@
return *this;
}
- /*!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
- Does not throw*/
+ //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
+ //!Does not throw
intrusive_ptr & operator=(pointer rhs)
{
this_type(rhs).swap(*this);
return *this;
}
- /*!Returns a reference to the internal pointer. Does not throw*/
+ //!Returns a reference to the internal pointer.
+ //!Does not throw
pointer &get()
{ return m_ptr; }
- /*!Returns a reference to the internal pointer. Does not throw*/
+ //!Returns a reference to the internal pointer.
+ //!Does not throw
const pointer &get() const
{ return m_ptr; }
- /*!Returns *get(). Does not throw*/
+ //!Returns *get().
+ //!Does not throw
T & operator*() const
{ return *m_ptr; }
- /*!Returns *get(). Does not throw*/
+ //!Returns *get().
+ //!Does not throw
const pointer &operator->() const
{ return m_ptr; }
- /*!Returns get(). Does not throw*/
+ //!Returns get().
+ //!Does not throw
pointer &operator->()
{ return m_ptr; }
- /*!Conversion to boolean. Does not throw*/
+ //!Conversion to boolean.
+ //!Does not throw
operator unspecified_bool_type () const
{ return m_ptr == 0? 0: &this_type::m_ptr; }
- /*!Not operator. Does not throw*/
+ //!Not operator.
+ //!Does not throw
bool operator! () const
{ return m_ptr == 0; }
- /*!Exchanges the contents of the two smart pointers. Does not throw*/
+ //!Exchanges the contents of the two smart pointers.
+ //!Does not throw
void swap(intrusive_ptr & rhs)
{ detail::do_swap(m_ptr, rhs.m_ptr); }
@@ -161,43 +169,50 @@
/// @endcond
};
-/*Returns a.get() == b.get(). Does not throw*/
+//!Returns a.get() == b.get().
+//!Does not throw
template<class T, class U, class VP> inline
bool operator==(intrusive_ptr<T, VP> const & a,
intrusive_ptr<U, VP> const & b)
{ return a.get() == b.get(); }
-/*Returns a.get() != b.get(). Does not throw*/
+//!Returns a.get() != b.get().
+//!Does not throw
template<class T, class U, class VP> inline
bool operator!=(intrusive_ptr<T, VP> const & a,
intrusive_ptr<U, VP> const & b)
{ return a.get() != b.get(); }
-/*Returns a.get() == b. Does not throw*/
+//!Returns a.get() == b.
+//!Does not throw
template<class T, class VP> inline
bool operator==(intrusive_ptr<T, VP> const & a,
const typename intrusive_ptr<T, VP>::pointer &b)
{ return a.get() == b; }
-/*Returns a.get() != b. Does not throw*/
+//!Returns a.get() != b.
+//!Does not throw
template<class T, class VP> inline
bool operator!=(intrusive_ptr<T, VP> const & a,
const typename intrusive_ptr<T, VP>::pointer &b)
{ return a.get() != b; }
-/*Returns a == b.get(). Does not throw*/
+//!Returns a == b.get().
+//!Does not throw
template<class T, class VP> inline
bool operator==(const typename intrusive_ptr<T, VP>::pointer &a,
intrusive_ptr<T, VP> const & b)
{ return a == b.get(); }
-/*Returns a != b.get(). Does not throw*/
+//!Returns a != b.get().
+//!Does not throw
template<class T, class VP> inline
bool operator!=(const typename intrusive_ptr<T, VP>::pointer &a,
intrusive_ptr<T, VP> const & b)
{ return a != b.get(); }
-/*Returns a.get() < b.get(). Does not throw*/
+//!Returns a.get() < b.get().
+//!Does not throw
template<class T, class VP> inline
bool operator<(intrusive_ptr<T, VP> const & a,
intrusive_ptr<T, VP> const & b)
@@ -206,7 +221,8 @@
(a.get(), b.get());
}
-/*!Exchanges the contents of the two intrusive_ptrs. Does not throw*/
+//!Exchanges the contents of the two intrusive_ptrs.
+//!Does not throw
template<class T, class VP> inline
void swap(intrusive_ptr<T, VP> & lhs,
intrusive_ptr<T, VP> & rhs)
@@ -218,7 +234,8 @@
(std::basic_ostream<E, T> & os, intrusive_ptr<Y, VP> const & p)
{ os << p.get(); return os; }
-/*Returns p.get(). Does not throw*/
+//!Returns p.get().
+//!Does not throw
template<class T, class VP>
inline typename boost::interprocess::intrusive_ptr<T, VP>::pointer
get_pointer(intrusive_ptr<T, VP> p)
@@ -260,7 +277,8 @@
/// @cond
#if defined(_MSC_VER) && (_MSC_VER < 1400)
-/*Returns p.get(). Does not throw*/
+//!Returns p.get().
+//!Does not throw
template<class T, class VP>
inline T *get_pointer(boost::interprocess::intrusive_ptr<T, VP> p)
{ return p.get(); }
Modified: trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/scoped_ptr.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -20,6 +20,9 @@
#include <boost/interprocess/detail/pointer_type.hpp>
#include <boost/assert.hpp>
+//!\file
+//!Describes the smart pointer scoped_ptr
+
namespace boost {
namespace interprocess {
Modified: trunk/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/shared_ptr.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -4,9 +4,10 @@
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// (C) Copyright Peter Dimov 2001, 2002, 2003
-// (C) Copyright Ion Gaztanaga 2006. 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)
+// (C) Copyright Ion Gaztanaga 2006-2007.
+// 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.
//
@@ -18,14 +19,14 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-#include <boost/assert.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/cast_tags.hpp>
#include <boost/assert.hpp>
-#include <boost/throw_exception.hpp>
#include <boost/interprocess/smart_ptr/detail/shared_count.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <boost/static_assert.hpp>
#include <algorithm> // for std::swap
@@ -33,75 +34,87 @@
#include <typeinfo> // for std::bad_cast
#include <iosfwd> // for std::basic_ostream
+//!\file
+//!Describes the smart pointer shared_ptr
+
namespace boost{
namespace interprocess{
-template<class T, class VA, class D> class weak_ptr;
-template<class T, class VA, class D> class enable_shared_from_this;
+template<class T, class VoidAllocator, class Deleter> class weak_ptr;
+template<class T, class VoidAllocator, class Deleter> class enable_shared_from_this;
namespace detail{
-template<class T, class VA, class D>
+template<class T, class VoidAllocator, class Deleter>
inline void sp_enable_shared_from_this
- (shared_count<T, VA, D> const & pn,
- const typename pointer_to_other <typename shared_count<T, VA, D>::pointer,
- enable_shared_from_this<T, VA, D> >::type &pe,
- const typename shared_count<T, VA, D>::pointer &px)
+ (shared_count<T, VoidAllocator, Deleter> const & pn,
+ const typename pointer_to_other <typename shared_count<T, VoidAllocator, Deleter>::pointer,
+ enable_shared_from_this<T, VoidAllocator, Deleter> >::type &pe,
+ const typename shared_count<T, VoidAllocator, Deleter>::pointer &px)
{
if(pe != 0)
pe->_internal_weak_this._internal_assign(pn);
}
/*
-template<class T, class VA, class D>
-inline void sp_enable_shared_from_this(shared_count<T, VA, D> const &, ...)
+template<class T, class VoidAllocator, class Deleter>
+inline void sp_enable_shared_from_this(shared_count<T, VoidAllocator, Deleter> const &, ...)
{}
*/
} // namespace detail
-/*!shared_ptr stores a pointer to a dynamically allocated object.
- The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
- it is destroyed or reset. shared_ptr is parameterized on
- T (the type of the object pointed to), VA (the void allocator to be used
- to allocate the auxiliary data) and D (the deleter whose
- operator() will be used to delete the object.
- The internal pointer will be of the same pointer type as typename
- VA::pointer type (that is, if typename VA::pointer is
- offset_ptr<void>, the internal pointer will be offset_ptr<T>).*/
-template<class T, class VA, class D>
+//!shared_ptr stores a pointer to a dynamically allocated object.
+//!The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to
+//!it is destroyed or reset.
+//!
+//!shared_ptr is parameterized on
+//!T (the type of the object pointed to), VoidAllocator (the void allocator to be used
+//!to allocate the auxiliary data) and Deleter (the deleter whose
+//!operator() will be used to delete the object.
+//!
+//!The internal pointer will be of the same pointer type as typename
+//!VoidAllocator::pointer type (that is, if typename VoidAllocator::pointer is
+//!offset_ptr<void>, the internal pointer will be offset_ptr<T>).
+//!
+//!Because the implementation uses reference counting, cycles of shared_ptr
+//!instances will not be reclaimed. For example, if main() holds a
+//!shared_ptr to A, which directly or indirectly holds a shared_ptr back
+//!to A, A's use count will be 2. Destruction of the original shared_ptr
+//!will leave A dangling with a use count of 1.
+//!Use weak_ptr to "break cycles."
+template<class T, class VoidAllocator, class Deleter>
class shared_ptr
{
/// @cond
private:
- typedef shared_ptr<T, VA, D> this_type;
+ typedef shared_ptr<T, VoidAllocator, Deleter> this_type;
/// @endcond
public:
- /*!Provides the type of the stored pointer.*/
+
typedef T element_type;
- /*!Provides the type of the stored pointer.*/
typedef T value_type;
- /*!Provides the type of the internal stored pointer.*/
typedef typename detail::pointer_to_other
- <typename VA::pointer, T>::type pointer;
-
+ <typename VoidAllocator::pointer, T>::type pointer;
typedef typename detail::add_reference
<value_type>::type reference;
typedef typename detail::add_reference
<const value_type>::type const_reference;
typedef typename detail::pointer_to_other
- <typename VA::pointer, const D>::type const_deleter_pointer;
+ <typename VoidAllocator::pointer, const Deleter>::type const_deleter_pointer;
typedef typename detail::pointer_to_other
- <typename VA::pointer, const VA>::type const_allocator_pointer;
+ <typename VoidAllocator::pointer, const VoidAllocator>::type const_allocator_pointer;
- /*!Constructs an empty shared_ptr. Use_count() == 0 && get() == 0.*/
+ public:
+ //!Constructs an empty shared_ptr.
+ //!Use_count() == 0 && get()== 0.
shared_ptr()
: m_pn() // never throws
{}
- /*!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated
- with a copy of a and the object will be deleted with a copy of d.
- Requirements: D and A's copy constructor must not throw.*/
- explicit shared_ptr(const pointer&p, const VA &a = VA(), const D &d = D())
+ //!Constructs a shared_ptr that owns the pointer p. Auxiliary data will be allocated
+ //!with a copy of a and the object will be deleted with a copy of d.
+ //!Requirements: Deleter and A's copy constructor must not throw.
+ explicit shared_ptr(const pointer&p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
: m_pn(p, a, d)
{
//Check that the pointer passed is of the same type that
@@ -112,57 +125,64 @@
//detail::sp_enable_shared_from_this( m_pn, p, p );
}
- /*!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
- a shared_ptr that shares ownership with r. Never throws.*/
+ //!If r is empty, constructs an empty shared_ptr. Otherwise, constructs
+ //!a shared_ptr that shares ownership with r. Never throws.
template<class Y>
- shared_ptr(shared_ptr<Y, VA, D> const & r)
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r)
: m_pn(r.m_pn) // never throws
{}
- /*!Constructs a shared_ptr that shares ownership with r and stores
- a copy of the pointer stored in r.*/
+ //!Constructs a shared_ptr that shares ownership with r and stores
+ //!a copy of the pointer stored in r.
template<class Y>
- explicit shared_ptr(weak_ptr<Y, VA, D> const & r)
+ explicit shared_ptr(weak_ptr<Y, VoidAllocator, Deleter> const & r)
: m_pn(r.m_pn) // may throw
{}
+ /// @cond
template<class Y>
- shared_ptr(shared_ptr<Y, VA, D> const & r, detail::static_cast_tag)
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::static_cast_tag)
: m_pn( pointer(static_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
, r.m_pn)
{}
template<class Y>
- shared_ptr(shared_ptr<Y, VA, D> const & r, detail::const_cast_tag)
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::const_cast_tag)
: m_pn( pointer(const_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
, r.m_pn)
{}
template<class Y>
- shared_ptr(shared_ptr<Y, VA, D> const & r, detail::dynamic_cast_tag)
+ shared_ptr(shared_ptr<Y, VoidAllocator, Deleter> const & r, detail::dynamic_cast_tag)
: m_pn( pointer(dynamic_cast<T*>(detail::get_pointer(r.m_pn.get_pointer())))
, r.m_pn)
{
if(!m_pn.get_pointer()){ // need to allocate new counter -- the cast failed
- m_pn = detail::shared_count<T, VA, D>();
+ m_pn = detail::shared_count<T, VoidAllocator, Deleter>();
}
}
+ /// @endcond
- /*!Equivalent to shared_ptr(r).swap(*this). Never throws*/
+ //!Equivalent to shared_ptr(r).swap(*this).
+ //!Never throws
template<class Y>
- shared_ptr & operator=(shared_ptr<Y, VA, D> const & r)
+ shared_ptr & operator=(shared_ptr<Y, VoidAllocator, Deleter> const & r)
{
m_pn = r.m_pn; // shared_count::op= doesn't throw
return *this;
}
+ //!This is equivalent to:
+ //!this_type().swap(*this);
void reset()
{
this_type().swap(*this);
}
+ //!This is equivalent to:
+ //!this_type(p, a, d).swap(*this);
template<class Pointer>
- void reset(const Pointer &p, const VA &a = VA(), const D &d = D())
+ void reset(const Pointer &p, const VoidAllocator &a = VoidAllocator(), const Deleter &d = Deleter())
{
//Check that the pointer passed is of the same type that
//the pointer the allocator defines or it's a raw pointer
@@ -172,42 +192,57 @@
this_type(p, a, d).swap(*this);
}
+ //!Returns a reference to the
+ //!pointed type
reference operator* () const // never throws
{ BOOST_ASSERT(m_pn.get_pointer() != 0); return *m_pn.get_pointer(); }
+ //!Returns the pointer pointing
+ //!to the owned object
pointer operator-> () const // never throws
{ BOOST_ASSERT(m_pn.get_pointer() != 0); return m_pn.get_pointer(); }
- pointer &operator-> () // never throws
- { BOOST_ASSERT(m_pn.get_pointer() != 0); return m_pn.get_pointer(); }
-
- const pointer &get() const // never throws
- { return m_pn.get_pointer(); }
-
- pointer &get() // never throws
+ //!Returns the pointer pointing
+ //!to the owned object
+ pointer get() const // never throws
{ return m_pn.get_pointer(); }
+ /// @cond
// implicit conversion to "bool"
void unspecified_bool_type_func() const {}
typedef void (this_type::*unspecified_bool_type)() const;
operator unspecified_bool_type() const // never throws
{ return !m_pn.get_pointer() ? 0 : &this_type::unspecified_bool_type_func; }
+ /// @endcond
+ //!Not operator.
+ //!Returns true if this->get() != 0, false otherwise
bool operator! () const // never throws
{ return !m_pn.get_pointer(); }
+ //!Returns use_count() == 1.
+ //!unique() might be faster than use_count()
bool unique() const // never throws
{ return m_pn.unique(); }
+ //!Returns the number of shared_ptr objects, *this included,
+ //!that share ownership with *this, or an unspecified nonnegative
+ //!value when *this is empty.
+ //!use_count() is not necessarily efficient. Use only for
+ //!debugging and testing purposes, not for production code.
long use_count() const // never throws
{ return m_pn.use_count(); }
- void swap(shared_ptr<T, VA, D> & other) // never throws
+ //!Exchanges the contents of the two
+ //!smart pointers.
+ void swap(shared_ptr<T, VoidAllocator, Deleter> & other) // never throws
{ m_pn.swap(other.m_pn); }
- template<class T2, class A2, class D2>
- bool _internal_less(shared_ptr<T2, A2, D2> const & rhs) const
+ /// @cond
+
+ template<class T2, class A2, class Deleter2>
+ bool _internal_less(shared_ptr<T2, A2, Deleter2> const & rhs) const
{ return m_pn < rhs.m_pn; }
const_deleter_pointer get_deleter() const
@@ -216,60 +251,87 @@
// const_allocator_pointer get_allocator() const
// { return m_pn.get_allocator(); }
- /// @cond
private:
- template<class T2, class A2, class D2> friend class shared_ptr;
- template<class T2, class A2, class D2> friend class weak_ptr;
+ template<class T2, class A2, class Deleter2> friend class shared_ptr;
+ template<class T2, class A2, class Deleter2> friend class weak_ptr;
- detail::shared_count<T, VA, D> m_pn; // reference counter
+ detail::shared_count<T, VoidAllocator, Deleter> m_pn; // reference counter
/// @endcond
}; // shared_ptr
-template<class T, class VA, class D, class U, class VA2, class D2> inline
-bool operator==(shared_ptr<T, VA, D> const & a, shared_ptr<U, VA2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
+bool operator==(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{ return a.get() == b.get(); }
-template<class T, class VA, class D, class U, class VA2, class D2> inline
-bool operator!=(shared_ptr<T, VA, D> const & a, shared_ptr<U, VA2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
+bool operator!=(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{ return a.get() != b.get(); }
-template<class T, class VA, class D, class U, class VA2, class D2> inline
-bool operator<(shared_ptr<T, VA, D> const & a, shared_ptr<U, VA2, D2> const & b)
+template<class T, class VoidAllocator, class Deleter, class U, class VoidAllocator2, class Deleter2> inline
+bool operator<(shared_ptr<T, VoidAllocator, Deleter> const & a, shared_ptr<U, VoidAllocator2, Deleter2> const & b)
{ return a._internal_less(b); }
-template<class T, class VA, class D> inline
-void swap(shared_ptr<T, VA, D> & a, shared_ptr<T, VA, D> & b)
+template<class T, class VoidAllocator, class Deleter> inline
+void swap(shared_ptr<T, VoidAllocator, Deleter> & a, shared_ptr<T, VoidAllocator, Deleter> & b)
{ a.swap(b); }
-template<class T, class VA, class D, class U> inline
-shared_ptr<T, VA, D> static_pointer_cast(shared_ptr<U, VA, D> const & r)
-{ return shared_ptr<T, VA, D>(r, detail::static_cast_tag()); }
-
-template<class T, class VA, class D, class U> inline
-shared_ptr<T, VA, D> const_pointer_cast(shared_ptr<U, VA, D> const & r)
-{ return shared_ptr<T, VA, D>(r, detail::const_cast_tag()); }
-
-template<class T, class VA, class D, class U> inline
-shared_ptr<T, VA, D> dynamic_pointer_cast(shared_ptr<U, VA, D> const & r)
-{ return shared_ptr<T, VA, D>(r, detail::dynamic_cast_tag()); }
+template<class T, class VoidAllocator, class Deleter, class U> inline
+shared_ptr<T, VoidAllocator, Deleter> static_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
+{ return shared_ptr<T, VoidAllocator, Deleter>(r, detail::static_cast_tag()); }
+
+template<class T, class VoidAllocator, class Deleter, class U> inline
+shared_ptr<T, VoidAllocator, Deleter> const_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
+{ return shared_ptr<T, VoidAllocator, Deleter>(r, detail::const_cast_tag()); }
+
+template<class T, class VoidAllocator, class Deleter, class U> inline
+shared_ptr<T, VoidAllocator, Deleter> dynamic_pointer_cast(shared_ptr<U, VoidAllocator, Deleter> const & r)
+{ return shared_ptr<T, VoidAllocator, Deleter>(r, detail::dynamic_cast_tag()); }
// get_pointer() enables boost::mem_fn to recognize shared_ptr
-template<class T, class VA, class D> inline
-T * get_pointer(shared_ptr<T, VA, D> const & p)
+template<class T, class VoidAllocator, class Deleter> inline
+T * get_pointer(shared_ptr<T, VoidAllocator, Deleter> const & p)
{ return p.get(); }
// operator<<
-template<class E, class T, class Y, class VA, class D> inline
+template<class E, class T, class Y, class VoidAllocator, class Deleter> inline
std::basic_ostream<E, T> & operator<<
- (std::basic_ostream<E, T> & os, shared_ptr<Y, VA, D> const & p)
+ (std::basic_ostream<E, T> & os, shared_ptr<Y, VoidAllocator, Deleter> const & p)
{ os << p.get(); return os; }
+
+//!Returns the type of a shared pointer
+//!of type T with the allocator boost::interprocess::allocator allocator
+//!and boost::interprocess::deleter deleter
+//!that can be constructed in the given managed segment type.
+template<class T, class ManagedMemory>
+struct managed_shared_ptr
+{
+ typedef typename ManagedMemory::template allocator<void>::type void_allocator;
+ typedef typename ManagedMemory::template deleter<T>::type deleter;
+ typedef shared_ptr< T, void_allocator, deleter> type;
+};
+
+//!Returns an instance of a shared pointer constructed
+//!with the default allocator and deleter from a pointer
+//!of type T that has been allocated in the passed managed segment
+template<class T, class ManagedMemory>
+inline typename managed_shared_ptr<T, ManagedMemory>::type
+ make_managed_shared_ptr(T *constructed_object, ManagedMemory &managed_memory)
+{
+ return typename managed_shared_ptr<T, ManagedMemory>::type
+ ( constructed_object
+ , managed_memory.template get_allocator<void>()
+ , managed_memory.template get_deleter<T>()
+ );
+}
+
+
/*
// get_deleter (experimental)
-template<class T, class VA, class D>
-typename detail::pointer_to_other<shared_ptr<T, VA, D>, D>::type
- get_deleter(shared_ptr<T, VA, D> const & p)
-{ return static_cast<D *>(p._internal_get_deleter(typeid(D))); }
+template<class T, class VoidAllocator, class Deleter>
+typename detail::pointer_to_other<shared_ptr<T, VoidAllocator, Deleter>, Deleter>::type
+ get_deleter(shared_ptr<T, VoidAllocator, Deleter> const & p)
+{ return static_cast<Deleter *>(p._internal_get_deleter(typeid(Deleter))); }
*/
} // namespace interprocess
@@ -277,8 +339,8 @@
#if defined(_MSC_VER) && (_MSC_VER < 1400)
// get_pointer() enables boost::mem_fn to recognize shared_ptr
-template<class T, class VA, class D> inline
-T * get_pointer(boost::interprocess::shared_ptr<T, VA, D> const & p)
+template<class T, class VoidAllocator, class Deleter> inline
+T * get_pointer(boost::interprocess::shared_ptr<T, VoidAllocator, Deleter> const & p)
{ return p.get(); }
#endif
Modified: trunk/boost/interprocess/smart_ptr/unique_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/unique_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/unique_ptr.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -3,7 +3,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// This file is the adaptation for Interprocess of
-// Howard Hinnant's unique_ptr emulation
+// Howard Hinnant's unique_ptr emulation code.
//
// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -26,45 +26,15 @@
#include <boost/static_assert.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
-//#include <boost/type_traits.hpp>
-//#include <boost/utility/enable_if.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
#include <cstddef>
+//!\file
+//!Describes the smart pointer unique_ptr
+
namespace boost{
namespace interprocess{
-template <class T>
-struct default_delete
-{
- default_delete() {}
- template <class U> default_delete(const default_delete<U>&) {}
- void operator() (T* ptr) const
- {
- BOOST_STATIC_ASSERT(sizeof(T) > 0);
- delete ptr;
- }
-};
-
-template <class T>
-struct default_delete<T[]>
-{
- void operator() (T* ptr) const
- {
- BOOST_STATIC_ASSERT(sizeof(T) > 0);
- delete [] ptr;
- }
-};
-
-template <class T, std::size_t N>
-struct default_delete<T[N]>
-{
- void operator() (T* ptr, std::size_t) const
- {
- BOOST_STATIC_ASSERT(sizeof(T) > 0);
- delete [] ptr;
- }
-};
-
/// @cond
template <class T, class D> class unique_ptr;
@@ -81,7 +51,34 @@
} //namespace detail {
/// @endcond
-template <class T, class D = default_delete<T> >
+//!Template unique_ptr stores a pointer to an object and deletes that object
+//!using the associated deleter when it is itself destroyed (such as when
+//!leaving block scope.
+//!
+//!The unique_ptr provides a semantics of strict ownership. A unique_ptr owns the
+//!object it holds a pointer to.
+//!
+//!A unique_ptr is not CopyConstructible, nor CopyAssignable, however it is
+//!MoveConstructible and Move-Assignable.
+//!
+//!The uses of unique_ptr include providing exception safety for dynamically
+//!allocated memory, passing ownership of dynamically allocated memory to a
+//!function, and returning dynamically allocated memory from a function
+//!
+//!A client-supplied template argument D must be a
+//!function pointer or functor for which, given a value d of type D and a pointer
+//!ptr to a type T*, the expression d(ptr) is
+//!valid and has the effect of deallocating the pointer as appropriate for that
+//!deleter. D may also be an lvalue-reference to a deleter.
+//!
+//!If the deleter D maintains state, it is intended that this state stay with
+//!the associated pointer as ownership is transferred
+//!from unique_ptr to unique_ptr. The deleter state need never be copied,
+//!only moved or swapped as pointer ownership
+//!is moved around. That is, the deleter need only be MoveConstructible,
+//!MoveAssignable, and Swappable, and need not be CopyConstructible
+//!(unless copied into the unique_ptr) nor CopyAssignable.
+template <class T, class D>
class unique_ptr
{
/// @cond
@@ -95,51 +92,93 @@
typedef D deleter_type;
typedef typename detail::pointer_type<T, D>::type pointer;
- // constructors
+ //!Requires: D must be default constructible, and that construction must not
+ //!throw an exception. D must not be a reference type.
+ //!
+ //!Effects: Constructs a unique_ptr which owns nothing.
+ //!
+ //!Postconditions: get() == 0. get_deleter() returns a reference to a
+ //!default constructed deleter D.
+ //!
+ //!Throws: nothing.
unique_ptr()
- : ptr_(pointer())
+ : ptr_(pointer(0))
{}
+ //!Requires: The expression D()(p) must be well formed. The default constructor
+ //!of D must not throw an exception.
+ //!
+ //!D must not be a reference type.
+ //!
+ //!Effects: Constructs a unique_ptr which owns p.
+ //!
+ //!Postconditions: get() == p. get_deleter() returns a reference to a default constructed deleter D.
+ //!
+ //!Throws: nothing.
explicit unique_ptr(pointer p)
: ptr_(p)
{}
+ //!Requires: The expression d(p) must be well formed.
+ //!
+ //!Postconditions: get() == p. get_deleter() returns a reference to the
+ //!internally stored deleter. If D is a
+ //!reference type then get_deleter() returns a reference to the lvalue d.
+ //!
+ //!Throws: nothing.
unique_ptr(pointer p
,typename detail::if_<detail::is_reference<D>
,D
,typename detail::add_reference<const D>::type>::type d)
: ptr_(p, d)
{}
-/*
- unique_ptr(const unique_ptr& u)
- : ptr_(const_cast<unique_ptr&>(u).release(), u.get_deleter())
- {}
-*/
+
+ //!Requires: If the deleter is not a reference type, construction of the
+ //!deleter D from an lvalue D must not throw an exception.
+ //!
+ //!Effects: Constructs a unique_ptr which owns the pointer which u owns
+ //!(if any). If the deleter is not a reference type, it is move constructed
+ //!from us deleter, otherwise the reference is copy constructed from us deleter.
+ //!
+ //!After the construction, u no longer owns a pointer.
+ //![ Note: The deleter constructor can be implemented with
+ //!std::forward<D>. end note ]
+ //!
+ //!Postconditions: get() == value u.get() had before the construction.
+ //!get_deleter() returns a reference to the internally stored deleter which
+ //!was constructed from u.get_deleter(). If D is a reference type then get_-
+ //!deleter() and u.get_deleter() both reference the same lvalue deleter.
+ //!
+ //!Throws: nothing.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
unique_ptr(detail::moved_object<unique_ptr> u)
- : ptr_(u.get().release(), u.get().get_deleter())
+ : ptr_(u.get().release(), move(u.get().get_deleter()))
{}
#else
unique_ptr(unique_ptr &&u)
- : ptr_(u.release(), u.get_deleter())
+ : ptr_(u.release(), forward<D>(u.get_deleter()))
{}
#endif
-/*
- template <class U, class E>
- unique_ptr(const unique_ptr<U, E>& u,
- typename boost::enable_if_c<
- detail::is_convertible<typename unique_ptr<U, E>::pointer, pointer>::value &&
- detail::is_convertible<E, D>::value &&
- (
- !detail::is_reference<D>::value ||
- detail::is_same<D, E>::value
- )
- ,
- nat
- >::type = nat())
- : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), u.get_deleter())
- {}
-*/
+
+ //!Requires: If D is not a reference type, construction of the deleter
+ //!D from an rvalue of type E must be well formed
+ //!and not throw an exception. If D is a reference type, then E must be
+ //!the same type as D (diagnostic required). unique_ptr<U, E>::pointer
+ //!must be implicitly convertible to pointer.
+ //!
+ //!Effects: Constructs a unique_ptr which owns the pointer which u owns
+ //!(if any). If the deleter is not a reference
+ //!type, it is move constructed from us deleter, otherwise the reference
+ //!is copy constructed from us deleter.
+ //!
+ //!After the construction, u no longer owns a pointer.
+ //!
+ //!postconditions get() == value u.get() had before the construction,
+ //!modulo any required offset adjustments
+ //!resulting from the cast from U* to T*. get_deleter() returns a reference to the internally stored deleter which
+ //!was constructed from u.get_deleter().
+ //!
+ //!Throws: nothing.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
template <class U, class E>
unique_ptr(const detail::moved_object<unique_ptr<U, E> >& u,
@@ -153,7 +192,7 @@
,
nat
>::type = nat())
- : ptr_(const_cast<unique_ptr<U,E>&>(u.get()).release(), u.get().get_deleter())
+ : ptr_(const_cast<unique_ptr<U,E>&>(u.get()).release(), move(u.get().get_deleter()))
{}
#else
template <class U, class E>
@@ -168,66 +207,145 @@
,
nat
>::type = nat())
- : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), u.get_deleter())
+ : ptr_(const_cast<unique_ptr<U,E>&>(u).release(), forward<D>(u.get_deleter()))
{}
#endif
- // destructor
+ //!Effects: If get() == 0 there are no effects. Otherwise get_deleter()(get()).
+ //!
+ //!Throws: nothing.
~unique_ptr()
{ reset(); }
// assignment
- unique_ptr& operator=(const unique_ptr& cu)
+
+ //!Requires: Assignment of the deleter D from an rvalue D must not throw an exception.
+ //!
+ //!Effects: reset(u.release()) followed by a move assignment from us deleter to
+ //!this deleter.
+ //!
+ //!Postconditions: This unique_ptr now owns the pointer which u owned, and u no
+ //!longer owns it.
+ //!
+ //!Returns: *this.
+ //!
+ //!Throws: nothing.
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ unique_ptr& operator=(const detail::moved_object<unique_ptr>& u)
+ {
+ reset(u.get().release());
+ ptr_.second() = move(u.get().get_deleter());
+ return *this;
+ }
+ #else
+ unique_ptr(unique_ptr && u)
{
- unique_ptr& u = const_cast<unique_ptr&>(cu);
reset(u.release());
- ptr_.second() = u.get_deleter();
+ ptr_.second() = move(u.get_deleter());
return *this;
}
+ #endif
+ //!Requires: Assignment of the deleter D from an rvalue D must not
+ //!throw an exception. U* must be implicitly convertible to T*.
+ //!
+ //!Effects: reset(u.release()) followed by a move assignment from
+ //!us deleter to this deleter. If either D or E is
+ //!a reference type, then the referenced lvalue deleter participates
+ //!in the move assignment.
+ //!
+ //!Postconditions: This unique_ptr now owns the pointer which u owned,
+ //!and u no longer owns it.
+ //!
+ //!Returns: *this.
+ //!
+ //!Throws: nothing.
template <class U, class E>
- unique_ptr& operator=(const unique_ptr<U, E>& cu)
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ unique_ptr& operator=(const detail::moved_object<unique_ptr<U, E> >& mu)
+ {
+ reset(mu.get().release());
+ ptr_.second() = move(mu.get().get_deleter());
+ return *this;
+ }
+ #else
+ unique_ptr(unique_ptr<U, E> && u)
{
- unique_ptr<U, E>& u = const_cast<unique_ptr<U, E>&>(cu);
reset(u.release());
- ptr_.second() = u.get_deleter();
+ ptr_.second() = move(u.get_deleter());
return *this;
}
+ #endif
+ //!Assigns from the literal 0 or NULL.
+ //!
+ //!Effects: reset().
+ //!
+ //!Postcondition: get() == 0
+ //!
+ //!Returns: *this.
+ //!
+ //!Throws: nothing.
unique_ptr& operator=(int nat::*)
{
reset();
return *this;
}
- // observers
+ //!Requires: get() != 0.
+ //!Returns: *get().
+ //!Throws: nothing.
typename detail::add_reference<T>::type operator*() const
{ return *ptr_.first(); }
+ //!Requires: get() != 0.
+ //!Returns: get().
+ //!Throws: nothing.
pointer operator->() const
{ return ptr_.first(); }
+ //!Returns: The stored pointer.
+ //!Throws: nothing.
pointer get() const
{ return ptr_.first(); }
+ //!Returns: A reference to the stored deleter.
+ //!
+ //!Throws: nothing.
deleter_reference get_deleter()
{ return ptr_.second(); }
+ //!Returns: A const reference to the stored deleter.
+ //!
+ //!Throws: nothing.
deleter_const_reference get_deleter() const
{ return ptr_.second(); }
+ //!Returns: An unspecified value that, when used in boolean
+ //!contexts, is equivalent to get() != 0.
+ //!
+ //!Throws: nothing.
operator int nat::*() const
{ return ptr_.first() ? &nat::for_bool_ : 0; }
- // modifiers
+ //!Postcondition: get() == 0.
+ //!
+ //!Returns: The value get() had at the start of the call to release.
+ //!
+ //!Throws: nothing.
pointer release()
{
pointer tmp = ptr_.first();
- ptr_.first() = pointer();
+ ptr_.first() = 0;
return tmp;
}
- void reset(pointer p = pointer())
+ //!Effects: If p == get() there are no effects. Otherwise get_deleter()(get()).
+ //!
+ //!Postconditions: get() == p.
+ //!
+ //!Throws: nothing.
+ void reset(pointer p = 0)
{
if (ptr_.first() != p){
if (ptr_.first())
@@ -236,6 +354,11 @@
}
}
+ //!Requires: The deleter D is Swappable and will not throw an exception under swap.
+ //!
+ //!Effects: The stored pointers of this and u are exchanged. The stored deleters are swapd (unqualified).
+ //!
+ //!Throws: nothing.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void swap(unique_ptr& u)
{ ptr_.swap(u.ptr_); }
@@ -255,7 +378,6 @@
unique_ptr(const unique_ptr&);
template <class U, class E> unique_ptr(unique_ptr<U, E>&);
template <class U> unique_ptr(U&, typename detail::unique_ptr_error<U>::type = 0);
-
unique_ptr& operator=(unique_ptr&);
template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&);
@@ -313,10 +435,10 @@
pointer release()
{
pointer tmp = ptr_.first();
- ptr_.first() = pointer();
+ ptr_.first() = 0;
return tmp;
}
- void reset(pointer p = pointer())
+ void reset(pointer p = 0)
{
if (ptr_.first() != p)
{
@@ -354,7 +476,7 @@
static const std::size_t size = N;
// constructors
- unique_ptr() : ptr_(pointer()) {}
+ unique_ptr() : ptr_(0) {}
explicit unique_ptr(pointer p) : ptr_(p) {}
unique_ptr(pointer p, typename if_<
boost::is_reference<D>,
@@ -392,10 +514,10 @@
pointer release()
{
pointer tmp = ptr_.first();
- ptr_.first() = pointer();
+ ptr_.first() = 0;
return tmp;
}
- void reset(pointer p = pointer())
+ void reset(pointer p = 0)
{
if (ptr_.first() != p)
{
@@ -449,7 +571,8 @@
{ return x.get() >= y.get(); }
/// @cond
-/*!This class has move constructor*/
+
+//!This class has move constructor
template <class T, class D>
struct is_movable<unique_ptr<T, D> >
{
@@ -457,6 +580,35 @@
};
/// @endcond
+
+//!Returns the type of a unique pointer
+//!of type T with boost::interprocess::deleter deleter
+//!that can be constructed in the given managed segment type.
+template<class T, class ManagedMemory>
+struct managed_unique_ptr
+{
+ typedef unique_ptr
+ < T
+ , typename ManagedMemory::template deleter<T>::type
+ > type;
+};
+
+//!Returns an instance of the a unique pointer constructed
+//!with boost::interproces::deleter from a pointer
+//!of type T that has been allocated in the passed managed segment
+template<class T, class ManagedMemory>
+inline typename detail::return_type
+ <typename managed_unique_ptr<T, ManagedMemory>::type
+ >::type
+ make_managed_unique_ptr(T *constructed_object, ManagedMemory &managed_memory)
+{
+ typename managed_unique_ptr<T, ManagedMemory>::type to_return
+ ( constructed_object
+ , managed_memory.template get_deleter<T>()
+ );
+ return to_return;
+}
+
} //namespace interprocess{
} //namespace boost{
Modified: trunk/boost/interprocess/smart_ptr/weak_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/weak_ptr.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/weak_ptr.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -3,9 +3,10 @@
// This file is the adaptation for Interprocess of boost/weak_ptr.hpp
//
// (C) Copyright Peter Dimov 2001, 2002, 2003
-// (C) Copyright Ion Gaztanaga 2006. 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)
+// (C) Copyright Ion Gaztanaga 2006-2007.
+// 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.
//
@@ -19,10 +20,32 @@
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/smart_ptr/deleter.hpp>
+
+//!\file
+//!Describes the smart pointer weak_ptr.
namespace boost{
namespace interprocess{
+//!The weak_ptr class template stores a "weak reference" to an object
+//!that's already managed by a shared_ptr. To access the object, a weak_ptr
+//!can be converted to a shared_ptr using the shared_ptr constructor or the
+//!member function lock. When the last shared_ptr to the object goes away
+//!and the object is deleted, the attempt to obtain a shared_ptr from the
+//!weak_ptr instances that refer to the deleted object will fail: the constructor
+//!will throw an exception of type bad_weak_ptr, and weak_ptr::lock will
+//!return an empty shared_ptr.
+//!
+//!Every weak_ptr meets the CopyConstructible and Assignable requirements
+//!of the C++ Standard Library, and so can be used in standard library containers.
+//!Comparison operators are supplied so that weak_ptr works with the standard
+//!library's associative containers.
+//!
+//!weak_ptr operations never throw exceptions.
+//!
+//!The class template is parameterized on T, the type of the object pointed to.
template<class T, class A, class D>
class weak_ptr
{
@@ -42,6 +65,8 @@
typedef T element_type;
typedef T value_type;
+ //!Effects: Constructs an empty weak_ptr.
+ //!Postconditions: use_count() == 0.
weak_ptr()
: m_pn() // never throws
{}
@@ -61,6 +86,14 @@
//
// It is not possible to avoid spurious access violations since
// in multithreaded programs r.m_px may be invalidated at any point.
+
+ //!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
+ //!constructs a weak_ptr that shares ownership with r as if by storing a
+ //!copy of the pointer stored in r.
+ //!
+ //!Postconditions: use_count() == r.use_count().
+ //!
+ //!Throws: nothing.
template<class Y>
weak_ptr(weak_ptr<Y, A, D> const & r)
: m_pn(r.m_pn) // never throws
@@ -71,11 +104,24 @@
m_pn.set_pointer(ref.get());
}
+ //!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
+ //!constructs a weak_ptr that shares ownership with r as if by storing a
+ //!copy of the pointer stored in r.
+ //!
+ //!Postconditions: use_count() == r.use_count().
+ //!
+ //!Throws: nothing.
template<class Y>
weak_ptr(shared_ptr<Y, A, D> const & r)
: m_pn(r.m_pn) // never throws
{}
+ //!Effects: Equivalent to weak_ptr(r).swap(*this).
+ //!
+ //!Throws: nothing.
+ //!
+ //!Notes: The implementation is free to meet the effects (and the
+ //!implied guarantees) via different means, without creating a temporary.
template<class Y>
weak_ptr & operator=(weak_ptr<Y, A, D> const & r) // never throws
{
@@ -87,10 +133,19 @@
return *this;
}
+ //!Effects: Equivalent to weak_ptr(r).swap(*this).
+ //!
+ //!Throws: nothing.
+ //!
+ //!Notes: The implementation is free to meet the effects (and the
+ //!implied guarantees) via different means, without creating a temporary.
template<class Y>
weak_ptr & operator=(shared_ptr<Y, A, D> const & r) // never throws
{ m_pn = r.m_pn; return *this; }
+ //!Returns: expired()? shared_ptr<T>(): shared_ptr<T>(*this).
+ //!
+ //!Throws: nothing.
shared_ptr<T, A, D> lock() const // never throws
{
// optimization: avoid throw overhead
@@ -108,18 +163,37 @@
BOOST_CATCH_END
}
+ //!Returns: 0 if *this is empty; otherwise, the number of shared_ptr objects
+ //!that share ownership with *this.
+ //!
+ //!Throws: nothing.
+ //!
+ //!Notes: use_count() is not necessarily efficient. Use only for debugging and
+ //!testing purposes, not for production code.
long use_count() const // never throws
{ return m_pn.use_count(); }
-
+
+ //!Returns: Returns: use_count() == 0.
+ //!
+ //!Throws: nothing.
+ //!
+ //!Notes: expired() may be faster than use_count().
bool expired() const // never throws
{ return m_pn.use_count() == 0; }
+ //!Effects: Equivalent to:
+ //!weak_ptr().swap(*this).
void reset() // never throws in 1.30+
{ this_type().swap(*this); }
+ //!Effects: Exchanges the contents of the two
+ //!smart pointers.
+ //!
+ //!Throws: nothing.
void swap(this_type & other) // never throws
{ detail::do_swap(m_pn, other.m_pn); }
+ /// @cond
template<class T2, class A2, class D2>
bool _internal_less(weak_ptr<T2, A2, D2> const & rhs) const
{ return m_pn < rhs.m_pn; }
@@ -128,7 +202,6 @@
void _internal_assign(const detail::shared_count<Y, A, D> & pn2)
{ m_pn = pn2; }
- /// @cond
private:
template<class T2, class A2, class D2> friend class shared_ptr;
@@ -146,6 +219,34 @@
void swap(weak_ptr<T, A, D> & a, weak_ptr<T, A, D> & b)
{ a.swap(b); }
+//!Returns the type of a weak pointer
+//!of type T with the allocator boost::interprocess::allocator allocator
+//!and boost::interprocess::deleter deleter
+//!that can be constructed in the given managed segment type.
+template<class T, class ManagedMemory>
+struct managed_weak_ptr
+{
+ typedef weak_ptr
+ < T
+ , typename ManagedMemory::template allocator<void>::type
+ , typename ManagedMemory::template deleter<T>::type
+ > type;
+};
+
+//!Returns an instance of the a weak pointer constructed
+//!with the default allocator and deleter from a pointer
+//!of type T that has been allocated in the passed managed segment
+template<class T, class ManagedMemory>
+inline typename managed_weak_ptr<T, ManagedMemory>::type
+ make_managed_weak_ptr(T *constructed_object, ManagedMemory &managed_memory)
+{
+ return typename managed_weak_ptr<T, ManagedMemory>::type
+ ( constructed_object
+ , managed_memory.template get_allocator<void>()
+ , managed_memory.template get_deleter<T>()
+ );
+}
+
} // namespace interprocess
} // namespace boost
Added: trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -0,0 +1,69 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007. 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_SYNC_NAMED_CREATION_FUNCTOR_HPP
+#define BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP
+
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace detail {
+
+struct named_creation_functor_no_arg{};
+
+template <class T, class Arg = named_creation_functor_no_arg>
+class named_creation_functor
+{
+ typedef named_creation_functor_no_arg no_arg_t;
+ public:
+ named_creation_functor(detail::create_enum_t type, Arg arg = Arg())
+ : m_creation_type(type), m_arg(arg){}
+
+ template<class ArgType>
+ void construct(void *address, typename enable_if_c<is_same<ArgType, no_arg_t>::value>::type * = 0) const
+ { new(address)T; }
+
+ template<class ArgType>
+ void construct(void *address, typename enable_if_c<!is_same<ArgType, no_arg_t>::value>::type * = 0) const
+ { new(address)T(m_arg); }
+
+ bool operator()(void *address, std::size_t, bool created) const
+ {
+ switch(m_creation_type){
+ case detail::DoOpen:
+ return true;
+ break;
+ case detail::DoCreate:
+ case detail::DoOpenOrCreate:
+ if(created){
+ construct<Arg>(address);
+ }
+ return true;
+ break;
+
+ default:
+ return false;
+ break;
+ }
+ return true;
+ }
+ private:
+ detail::create_enum_t m_creation_type;
+ Arg m_arg;
+};
+
+} //namespace detail {
+} //namespace interprocess {
+} //namespace boost {
+
+#endif //BOOST_INTERPROCESS_SYNC_NAMED_CREATION_FUNCTOR_HPP
Modified: trunk/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/file_lock.hpp (original)
+++ trunk/boost/interprocess/sync/file_lock.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -22,16 +22,15 @@
#include <boost/interprocess/detail/os_file_functions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-/*!\file
- Describes a class that wraps file locking capabilities.
-*/
+//!\file
+//!Describes a class that wraps file locking capabilities.
namespace boost {
namespace interprocess {
-/*!A file lock, is a mutual exclusion utility similar to a mutex using a
- file. A file lock has sharable and exclusive locking capabilities and
- can be used with scoped_lock and sharable_lock classes.*/
+//!A file lock, is a mutual exclusion utility similar to a mutex using a
+//!file. A file lock has sharable and exclusive locking capabilities and
+//!can be used with scoped_lock and sharable_lock classes.
class file_lock
{
/// @cond
@@ -41,67 +40,67 @@
file_lock &operator=(const file_lock &);
/// @endcond
public:
- /*!Opens a file lock. Throws interprocess_exception if the file does not
- exist or there are no operating system resources.*/
+ //!Opens a file lock. Throws interprocess_exception if the file does not
+ //!exist or there are no operating system resources.
file_lock(const char *name);
- /*!Closes a file lock. Does not throw.*/
+ //!Closes a file lock. Does not throw.
~file_lock();
//Exclusive locking
- /*!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
- and if another thread has exclusive, or sharable ownership of
- the mutex, it waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
+ //! and if another thread has exclusive, or sharable ownership of
+ //! the mutex, it waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock();
- /*!Effects: The calling thread tries to acquire exclusive ownership of the mutex
- without waiting. If no other thread has exclusive, or sharable
- ownership of the mutex this succeeds.
- Returns: If it can acquire exclusive ownership immediately returns true.
- If it has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! without waiting. If no other thread has exclusive, or sharable
+ //! ownership of the mutex this succeeds.
+ //!Returns: If it can acquire exclusive ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock();
- /*!Effects: The calling thread tries to acquire exclusive ownership of the mutex
- waiting if necessary until no other thread has has exclusive, or sharable
- ownership of the mutex or abs_time is reached.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive, or sharable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The calling thread releases the exclusive ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock();
//Sharable locking
- /*!Effects: The calling thread tries to obtain sharable ownership of the mutex,
- and if another thread has exclusive ownership of the mutex, waits until
- it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
+ //! and if another thread has exclusive ownership of the mutex, waits until
+ //! it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock_sharable();
- /*!Effects: The calling thread tries to acquire sharable ownership of the mutex
- without waiting. If no other thread has has exclusive ownership of the
- mutex this succeeds.
- Returns: If it can acquire sharable ownership immediately returns true. If it
- has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! without waiting. If no other thread has has exclusive ownership of the
+ //! mutex this succeeds.
+ //!Returns: If it can acquire sharable ownership immediately returns true. If it
+ //! has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock_sharable();
- /*!Effects: The calling thread tries to acquire sharable ownership of the mutex
- waiting if necessary until no other thread has has exclusive ownership of
- the mutex or abs_time is reached.
- Returns: If acquires sharable ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive ownership of
+ //! the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have sharable ownership of the mutex.
- Effects: The calling thread releases the sharable ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
/// @cond
private:
Modified: trunk/boost/interprocess/sync/interprocess_barrier.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_barrier.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_barrier.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -52,31 +52,31 @@
namespace boost {
namespace interprocess {
-/*!An object of class barrier is a synchronization primitive that
- can be placed in shared memory used to cause a set of threads from
- different processes to wait until they each perform a certain
- function or each reach a particular point in their execution.*/
+//!An object of class barrier is a synchronization primitive that
+//!can be placed in shared memory used to cause a set of threads from
+//!different processes to wait until they each perform a certain
+//!function or each reach a particular point in their execution.
class barrier
{
public:
- /*!Constructs a barrier object that will cause count threads
- to block on a call to wait(). */
+ //!Constructs a barrier object that will cause count threads
+ //!to block on a call to wait().
barrier(unsigned int count);
- /*!Destroys *this. If threads are still executing their wait()
- operations, the behavior for these threads is undefined.*/
+ //!Destroys *this. If threads are still executing their wait()
+ //!operations, the behavior for these threads is undefined.
~barrier();
- /*!Effects: Wait until N threads call wait(), where N equals the count
- provided to the constructor for the barrier object.
- Note that if the barrier is destroyed before wait() can return,
- the behavior is undefined.
- Returns: Exactly one of the N threads will receive a return value
- of true, the others will receive a value of false. Precisely which
- thread receives the return value of true will be implementation-defined.
- Applications can use this value to designate one thread as a leader that
- will take a certain action, and the other threads emerging from the barrier
- can wait for that action to take place.*/
+ //!Effects: Wait until N threads call wait(), where N equals the count
+ //!provided to the constructor for the barrier object.
+ //!Note that if the barrier is destroyed before wait() can return,
+ //!the behavior is undefined.
+ //!Returns: Exactly one of the N threads will receive a return value
+ //!of true, the others will receive a value of false. Precisely which
+ //!thread receives the return value of true will be implementation-defined.
+ //!Applications can use this value to designate one thread as a leader that
+ //!will take a certain action, and the other threads emerging from the barrier
+ //!can wait for that action to take place.
bool wait();
/// @cond
Modified: trunk/boost/interprocess/sync/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_condition.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -38,9 +38,8 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
-/*!\file
- Describes process-shared variables interprocess_condition class
-*/
+//!\file
+//!Describes process-shared variables interprocess_condition class
namespace boost {
@@ -60,23 +59,24 @@
friend class named_condition;
/// @endcond
public:
- /*!Constructs a interprocess_condition*/
+ //!Constructs a interprocess_condition. On error throws interprocess_exception.
interprocess_condition();
- /*!Destroys *this*/
+ //!Destroys *this
+ //!liberating system resources.
~interprocess_condition();
- /*!If there is a thread waiting on *this, change that
- thread's state to ready. Otherwise there is no effect.*/
+ //!If there is a thread waiting on *this, change that
+ //!thread's state to ready. Otherwise there is no effect.
void notify_one();
- /*!Change the state of all threads waiting on *this to ready.
- If there are no waiting threads, notify_all() has no effect.*/
+ //!Change the state of all threads waiting on *this to ready.
+ //!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- /*!Releases the lock on the interprocess_mutex object associated with lock, blocks
- the current thread of execution until readied by a call to
- this->notify_one() or this->notify_all(), and then reacquires the lock.*/
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock)
{
@@ -85,7 +85,8 @@
do_wait(*lock.mutex());
}
- /*!The same as: while (!pred()) wait(lock)*/
+ //!The same as:
+ //!while (!pred()) wait(lock)
template <typename L, typename Pr>
void wait(L& lock, Pr pred)
{
@@ -96,11 +97,11 @@
do_wait(*lock.mutex());
}
- /*!Releases the lock on the interprocess_mutex object associated with lock, blocks
- the current thread of execution until readied by a call to
- this->notify_one() or this->notify_all(), or until time abs_time is reached,
- and then reacquires the lock.
- Returns: false if time abs_time is reached, otherwise true.*/
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!and then reacquires the lock.
+ //!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
{
@@ -110,9 +111,9 @@
return do_timed_wait(abs_time, *lock.mutex());
}
- /*!The same as: while (!pred()) {
- if (!timed_wait(lock, abs_time)) return pred();
- } return true;*/
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
+ //! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
Modified: trunk/boost/interprocess/sync/interprocess_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -48,18 +48,17 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
-/*!\file
- Describes a mutex class that can be placed in memory shared by
- several processes.
-*/
+//!\file
+//!Describes a mutex class that can be placed in memory shared by
+//!several processes.
namespace boost {
namespace interprocess {
class interprocess_condition;
-/*!Wraps a interprocess_mutex that can be placed in shared memory and can be
- shared between processes. Allows timed lock tries*/
+//!Wraps a interprocess_mutex that can be placed in shared memory and can be
+//!shared between processes. Allows timed lock tries
class interprocess_mutex
{
/// @cond
@@ -70,38 +69,39 @@
/// @endcond
public:
- /*!Constructor. Throws interprocess_exception on error.*/
+ //!Constructor.
+ //!Throws interprocess_exception on error.
interprocess_mutex();
- /*!Destructor. If any process uses the mutex after the destructor is called
- the result is undefined. Does not throw.*/
+ //!Destructor. If any process uses the mutex after the destructor is called
+ //!the result is undefined. Does not throw.
~interprocess_mutex();
- /*!Effects: The calling thread tries to obtain ownership of the mutex, and
- if another thread has ownership of the mutex, it waits until it can
- obtain the ownership. If a thread takes ownership of the mutex the
- mutex must be unlocked by the same mutex.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain ownership of the mutex, and
+ //! if another thread has ownership of the mutex, it waits until it can
+ //! obtain the ownership. If a thread takes ownership of the mutex the
+ //! mutex must be unlocked by the same mutex.
+ //!Throws: interprocess_exception on error.
void lock();
- /*!Effects: The calling thread tries to obtain ownership of the mutex, and
- if another thread has ownership of the mutex returns immediately.
- Returns: If the thread acquires ownership of the mutex, returns true, if
- the another thread has ownership of the mutex, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain ownership of the mutex, and
+ //! if another thread has ownership of the mutex returns immediately.
+ //!Returns: If the thread acquires ownership of the mutex, returns true, if
+ //! the another thread has ownership of the mutex, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock();
- /*!Effects: The calling thread will try to obtain exclusive ownership of the
- mutex if it can do so in until the specified time is reached. If the
- mutex supports recursive locking, the mutex must be unlocked the same
- number of times it is locked.
- Returns: If the thread acquires ownership of the mutex, returns true, if
- the timeout expires returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread will try to obtain exclusive ownership of the
+ //! mutex if it can do so in until the specified time is reached. If the
+ //! mutex supports recursive locking, the mutex must be unlocked the same
+ //! number of times it is locked.
+ //!Returns: If the thread acquires ownership of the mutex, returns true, if
+ //! the timeout expires returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*!Effects: The calling thread releases the exclusive ownership of the mutex.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Throws: interprocess_exception on error.
void unlock();
/// @cond
private:
Modified: trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -49,17 +49,16 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
-/*!\file
- Describes interprocess_recursive_mutex and shared_recursive_try_mutex classes
-*/
+//!\file
+//!Describes interprocess_recursive_mutex and shared_recursive_try_mutex classes
namespace boost {
namespace interprocess {
-/*!Wraps a interprocess_mutex that can be placed in shared memory and can be
- shared between processes. Allows several locking calls by the same
- process. Allows timed lock tries*/
+//!Wraps a interprocess_mutex that can be placed in shared memory and can be
+//!shared between processes. Allows several locking calls by the same
+//!process. Allows timed lock tries
class interprocess_recursive_mutex
{
/// @cond
@@ -68,37 +67,38 @@
interprocess_recursive_mutex &operator=(const interprocess_recursive_mutex &);
/// @endcond
public:
- /*!Constructor. Throws interprocess_exception on error.*/
+ //!Constructor.
+ //!Throws interprocess_exception on error.
interprocess_recursive_mutex();
- /*!Destructor. If any process uses the mutex after the destructor is called
- the result is undefined. Does not throw.*/
+ //!Destructor. If any process uses the mutex after the destructor is called
+ //!the result is undefined. Does not throw.
~interprocess_recursive_mutex();
- /*!Effects: The calling thread tries to obtain ownership of the mutex, and
- if another thread has ownership of the mutex, it waits until it can
- obtain the ownership. If a thread takes ownership of the mutex the
- mutex must be unlocked by the same mutex. The mutex must be unlocked
- the same number of times it is locked.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain ownership of the mutex, and
+ //! if another thread has ownership of the mutex, it waits until it can
+ //! obtain the ownership. If a thread takes ownership of the mutex the
+ //! mutex must be unlocked by the same mutex. The mutex must be unlocked
+ //! the same number of times it is locked.
+ //!Throws: interprocess_exception on error.
void lock(void);
- /*! Tries to lock the interprocess_mutex, returns false when interprocess_mutex
- is already locked, returns true when success. The mutex must be unlocked
- the same number of times it is locked.
- Throws: interprocess_exception if a severe error is found*/
+ //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!is already locked, returns true when success. The mutex must be unlocked
+ //!the same number of times it is locked.
+ //!Throws: interprocess_exception if a severe error is found
bool try_lock(void);
- /*! Tries to lock the interprocess_mutex, if interprocess_mutex can't be locked before
- abs_time time, returns false. The mutex must be unlocked
- the same number of times it is locked.
- Throws: interprocess_exception if a severe error is found*/
+ //!Tries to lock the interprocess_mutex, if interprocess_mutex can't be locked before
+ //!abs_time time, returns false. The mutex must be unlocked
+ //! the same number of times it is locked.
+ //!Throws: interprocess_exception if a severe error is found
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*!Effects: The calling thread releases the exclusive ownership of the mutex.
- If the mutex supports recursive locking, the mutex must be unlocked the
- same number of times it is locked.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //! If the mutex supports recursive locking, the mutex must be unlocked the
+ //! same number of times it is locked.
+ //!Throws: interprocess_exception on error.
void unlock(void);
/// @cond
private:
Modified: trunk/boost/interprocess/sync/interprocess_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_semaphore.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -39,16 +39,15 @@
#define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
#endif
-/*!\file
- Describes a interprocess_semaphore class for inter-process synchronization
-*/
+//!\file
+//!Describes a interprocess_semaphore class for inter-process synchronization
namespace boost {
namespace interprocess {
-/*!Wraps a interprocess_semaphore that can be placed in shared memory and can be
- shared between processes. Allows timed lock tries*/
+//!Wraps a interprocess_semaphore that can be placed in shared memory and can be
+//!shared between processes. Allows timed lock tries
class interprocess_semaphore
{
/// @cond
@@ -57,36 +56,37 @@
interprocess_semaphore &operator=(const interprocess_semaphore &);
/// @endcond
public:
- /*!Creates a interprocess_semaphore with the given initial count.
- interprocess_exception if there is an error.*/
+ //!Creates a interprocess_semaphore with the given initial count.
+ //!interprocess_exception if there is an error.*/
interprocess_semaphore(int initialCount);
- /*!Destroys the interprocess_semaphore. Does not throw*/
+ //!Destroys the interprocess_semaphore.
+ //!Does not throw
~interprocess_semaphore();
- /*!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
- for the interprocess_semaphore, then one of these processes will return successfully from
- its wait function. If there is an error an interprocess_exception exception is thrown.*/
+ //!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
+ //!for the interprocess_semaphore, then one of these processes will return successfully from
+ //!its wait function. If there is an error an interprocess_exception exception is thrown.
void post();
- /*!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
- then the calling process/thread blocks until it can decrement the counter.
- If there is an error an interprocess_exception exception is thrown.*/
+ //!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
+ //!then the calling process/thread blocks until it can decrement the counter.
+ //!If there is an error an interprocess_exception exception is thrown.
void wait();
- /*!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
- and returns true. If the value is not greater than zero returns false.
- If there is an error an interprocess_exception exception is thrown.*/
+ //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
+ //!and returns true. If the value is not greater than zero returns false.
+ //!If there is an error an interprocess_exception exception is thrown.
bool try_wait();
- /*!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
- than zero and returns true. Otherwise, waits for the interprocess_semaphore
- to the posted or the timeout expires. If the timeout expires, the
- function returns false. If the interprocess_semaphore is posted the function
- returns true. If there is an error throws sem_exception*/
+ //!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
+ //!than zero and returns true. Otherwise, waits for the interprocess_semaphore
+ //!to the posted or the timeout expires. If the timeout expires, the
+ //!function returns false. If the interprocess_semaphore is posted the function
+ //!returns true. If there is an error throws sem_exception
bool timed_wait(const boost::posix_time::ptime &abs_time);
- /*!Returns the interprocess_semaphore count*/
+ //!Returns the interprocess_semaphore count
// int get_count() const;
/// @cond
private:
Modified: trunk/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_upgradable_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_upgradable_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,16 +23,14 @@
#include <limits.h>
-/*!\file
- Describes interprocess_upgradable_mutex class
-*/
+//!\file
+//!Describes interprocess_upgradable_mutex class
namespace boost {
-
namespace interprocess {
-/*!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be
- shared between processes. Allows timed lock tries*/
+//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be
+//!shared between processes. Allows timed lock tries
class interprocess_upgradable_mutex
{
//Non-copyable
@@ -42,156 +40,158 @@
friend class interprocess_condition;
public:
- /*!Constructs the upgradable lock. Throws interprocess_exception on error.*/
+ //!Constructs the upgradable lock.
+ //!Throws interprocess_exception on error.
interprocess_upgradable_mutex();
- /*!Destroys the upgradable lock. Does not throw.*/
+ //!Destroys the upgradable lock.
+ //!Does not throw.
~interprocess_upgradable_mutex();
//Exclusive locking
- /*!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
- and if another thread has exclusive, sharable or upgradable ownership of
- the mutex, it waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
+ //! and if another thread has exclusive, sharable or upgradable ownership of
+ //! the mutex, it waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock();
- /*!Effects: The calling thread tries to acquire exclusive ownership of the mutex
- without waiting. If no other thread has exclusive, sharable or upgradable
- ownership of the mutex this succeeds.
- Returns: If it can acquire exclusive ownership immediately returns true.
- If it has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! without waiting. If no other thread has exclusive, sharable or upgradable
+ //! ownership of the mutex this succeeds.
+ //!Returns: If it can acquire exclusive ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock();
- /*!Effects: The calling thread tries to acquire exclusive ownership of the mutex
- waiting if necessary until no other thread has has exclusive, sharable or
- upgradable ownership of the mutex or abs_time is reached.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive, sharable or
+ //! upgradable ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The calling thread releases the exclusive ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock();
//Sharable locking
- /*!Effects: The calling thread tries to obtain sharable ownership of the mutex,
- and if another thread has exclusive or upgradable ownership of the mutex,
- waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
+ //! and if another thread has exclusive or upgradable ownership of the mutex,
+ //! waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock_sharable();
- /*!Effects: The calling thread tries to acquire sharable ownership of the mutex
- without waiting. If no other thread has has exclusive or upgradable ownership
- of the mutex this succeeds.
- Returns: If it can acquire sharable ownership immediately returns true. If it
- has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! without waiting. If no other thread has has exclusive or upgradable ownership
+ //! of the mutex this succeeds.
+ //!Returns: If it can acquire sharable ownership immediately returns true. If it
+ //! has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock_sharable();
- /*!Effects: The calling thread tries to acquire sharable ownership of the mutex
- waiting if necessary until no other thread has has exclusive or upgradable
- ownership of the mutex or abs_time is reached.
- Returns: If acquires sharable ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive or upgradable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have sharable ownership of the mutex.
- Effects: The calling thread releases the sharable ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
//Upgradable locking
- /*!Effects: The calling thread tries to obtain upgradable ownership of the mutex,
- and if another thread has exclusive or upgradable ownership of the mutex,
- waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain upgradable ownership of the mutex,
+ //! and if another thread has exclusive or upgradable ownership of the mutex,
+ //! waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock_upgradable();
- /*!Effects: The calling thread tries to acquire upgradable ownership of the mutex
- without waiting. If no other thread has has exclusive or upgradable ownership
- of the mutex this succeeds.
- Returns: If it can acquire upgradable ownership immediately returns true.
- If it has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire upgradable ownership of the mutex
+ //! without waiting. If no other thread has has exclusive or upgradable ownership
+ //! of the mutex this succeeds.
+ //!Returns: If it can acquire upgradable ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock_upgradable();
- /*!Effects: The calling thread tries to acquire upgradable ownership of the mutex
- waiting if necessary until no other thread has has exclusive or upgradable
- ownership of the mutex or abs_time is reached.
- Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire upgradable ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive or upgradable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The calling thread releases the upgradable ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The thread atomically releases exclusive ownership and acquires
- upgradable ownership. This operation is non-blocking.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The thread atomically releases exclusive ownership and acquires
+ //! upgradable ownership. This operation is non-blocking.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The thread atomically releases exclusive ownership and acquires
- sharable ownership. This operation is non-blocking.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The thread atomically releases exclusive ownership and acquires
+ //! sharable ownership. This operation is non-blocking.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and acquires
- sharable ownership. This operation is non-blocking.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and acquires
+ //! sharable ownership. This operation is non-blocking.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and acquires
- exclusive ownership. This operation will block until all threads with
- sharable ownership releas it.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and acquires
+ //! exclusive ownership. This operation will block until all threads with
+ //! sharable ownership release their sharable lock.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and tries to
- acquire exclusive ownership. This operation will fail if there are threads
- with sharable ownership, but it will maintain upgradable ownership.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and tries to
+ //! acquire exclusive ownership. This operation will fail if there are threads
+ //! with sharable ownership, but it will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and tries to acquire
- exclusive ownership, waiting if necessary until abs_time. This operation will
- fail if there are threads with sharable ownership or timeout reaches, but it
- will maintain upgradable ownership.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error. */
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and tries to acquire
+ //! exclusive ownership, waiting if necessary until abs_time. This operation will
+ //! fail if there are threads with sharable ownership or timeout reaches, but it
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error. */
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have sharable ownership of the mutex.
- Effects: The thread atomically releases sharable ownership and tries to acquire
- exclusive ownership. This operation will fail if there are threads with sharable
- or upgradable ownership, but it will maintain sharable ownership.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The thread atomically releases sharable ownership and tries to acquire
+ //! exclusive ownership. This operation will fail if there are threads with sharable
+ //! or upgradable ownership, but it will maintain sharable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
- /*!Precondition: The thread must have sharable ownership of the mutex.
- Effects: The thread atomically releases sharable ownership and tries to acquire
- upgradable ownership. This operation will fail if there are threads with sharable
- or upgradable ownership, but it will maintain sharable ownership.
- Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The thread atomically releases sharable ownership and tries to acquire
+ //! upgradable ownership. This operation will fail if there are threads with sharable
+ //! or upgradable ownership, but it will maintain sharable ownership.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock_upgradable();
/// @cond
Modified: trunk/boost/interprocess/sync/lock_options.hpp
==============================================================================
--- trunk/boost/interprocess/sync/lock_options.hpp (original)
+++ trunk/boost/interprocess/sync/lock_options.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -18,9 +18,8 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
-/*!\file
- Describes the lock options with associated with interprocess_mutex lock constructors.
-*/
+//!\file
+//!Describes the lock options with associated with interprocess_mutex lock constructors.
namespace boost {
@@ -30,11 +29,11 @@
namespace interprocess {
namespace detail{
- /*!Type to indicate to a mutex lock constructor that must not lock the mutex.*/
+ //!Type to indicate to a mutex lock constructor that must not lock the mutex.
struct defer_lock_type{};
- /*!Type to indicate to a mutex lock constructor that must try to lock the mutex.*/
+ //!Type to indicate to a mutex lock constructor that must try to lock the mutex.
struct try_to_lock_type {};
- /*!Type to indicate to a mutex lock constructor that the mutex is already locked.*/
+ //!Type to indicate to a mutex lock constructor that the mutex is already locked.
struct accept_ownership_type{};
} //namespace detail{
Modified: trunk/boost/interprocess/sync/mutex_family.hpp
==============================================================================
--- trunk/boost/interprocess/sync/mutex_family.hpp (original)
+++ trunk/boost/interprocess/sync/mutex_family.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -22,24 +22,23 @@
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/interprocess/sync/null_mutex.hpp>
-/*!\file
- Describes a shared interprocess_mutex family fit algorithm used to allocate objects in shared memory.
-*/
+//!\file
+//!Describes a shared interprocess_mutex family fit algorithm used to allocate objects in shared memory.
namespace boost {
namespace interprocess {
-/*!Describes interprocess_mutex family to use with Interprocess framework
- based on boost::interprocess synchronization objects.*/
+//!Describes interprocess_mutex family to use with Interprocess framework
+//!based on boost::interprocess synchronization objects.
struct mutex_family
{
typedef boost::interprocess::interprocess_mutex mutex_type;
typedef boost::interprocess::interprocess_recursive_mutex recursive_mutex_type;
};
-/*!Describes interprocess_mutex family to use with Interprocess frameworks
- based on null operation synchronization objects.*/
+//!Describes interprocess_mutex family to use with Interprocess frameworks
+//!based on null operation synchronization objects.
struct null_mutex_family
{
typedef boost::interprocess::null_mutex mutex_type;
Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp (original)
+++ trunk/boost/interprocess/sync/named_condition.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_NAMED_CONDITION_HPP
-#define BOOST_NAMED_CONDITION_HPP
+#ifndef BOOST_INTERPROCESS_NAMED_CONDITION_HPP
+#define BOOST_INTERPROCESS_NAMED_CONDITION_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -23,10 +23,15 @@
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
+#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#include <boost/interprocess/sync/interprocess_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#endif
+
-/*!\file
- Describes process-shared variables interprocess_condition class
-*/
+//!\file
+//!Describes process-shared variables interprocess_condition class
namespace boost {
@@ -41,102 +46,114 @@
named_condition &operator=(const named_condition &);
/// @endcond
public:
- /*!Creates a global condition with a name.*/
+ //!Creates a global condition with a name.
+ //!If the condition can't be created throws interprocess_exception
named_condition(create_only_t create_only, const char *name);
- /*!Opens or creates a global condition with a name.
- If the condition is created, this call is equivalent to create().
- If the condition is already created, this call is equivalent to open().
- Does not throw*/
+ //!Opens or creates a global condition with a name.
+ //!If the condition is created, this call is equivalent to
+ //!named_condition(create_only_t, ... )
+ //!If the condition is already created, this call is equivalent
+ //!named_condition(open_only_t, ... )
+ //!Does not throw
named_condition(open_or_create_t open_or_create, const char *name);
- /*!Opens a global condition with a name if that condition is previously.
- created. If it is not previously created this function return false.
- Does not throw*/
+ //!Opens a global condition with a name if that condition is previously
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
named_condition(open_only_t open_only, const char *name);
- /*!Destroys *this*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~named_condition();
- /*!If there is a thread waiting on *this, change that
- thread's state to ready. Otherwise there is no effect.*/
+ //!If there is a thread waiting on *this, change that
+ //!thread's state to ready. Otherwise there is no effect.*/
void notify_one();
- /*!Change the state of all threads waiting on *this to ready.
- If there are no waiting threads, notify_all() has no effect.*/
+ //!Change the state of all threads waiting on *this to ready.
+ //!If there are no waiting threads, notify_all() has no effect.
void notify_all();
- /*!Releases the lock on the interprocess_mutex object associated with lock, blocks
- the current thread of execution until readied by a call to
- this->notify_one() or this->notify_all(), and then reacquires the lock.*/
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), and then reacquires the lock.
template <typename L>
void wait(L& lock);
- /*!The same as: while (!pred()) wait(lock)*/
+ //!The same as:
+ //!while (!pred()) wait(lock)
template <typename L, typename Pr>
void wait(L& lock, Pr pred);
- /*!Releases the lock on the interprocess_mutex object associated with lock, blocks
- the current thread of execution until readied by a call to
- this->notify_one() or this->notify_all(), or until time abs_time is reached,
- and then reacquires the lock.
- Returns: false if time abs_time is reached, otherwise true.*/
+ //!Releases the lock on the interprocess_mutex object associated with lock, blocks
+ //!the current thread of execution until readied by a call to
+ //!this->notify_one() or this->notify_all(), or until time abs_time is reached,
+ //!and then reacquires the lock.
+ //!Returns: false if time abs_time is reached, otherwise true.
template <typename L>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time);
- /*!The same as: while (!pred()) {
- if (!timed_wait(lock, abs_time)) return pred();
- } return true;*/
+ //!The same as: while (!pred()) {
+ //! if (!timed_wait(lock, abs_time)) return pred();
+ //! } return true;
template <typename L, typename Pr>
bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred);
+ //!Erases a named condition from the system.
+ //!Returns false on error. Never throws.
static bool remove(const char *name);
/// @cond
private:
- interprocess_condition *condition() const
- { return static_cast<interprocess_condition*>(m_shmem.get_address()); }
+ struct condition_holder
+ {
+ interprocess_condition cond_;
+ //If named_mutex is implemented using semaphores
+ //we need to store an additional mutex
+ #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ interprocess_mutex mutex_;
+ #endif
+ };
- detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
+ interprocess_condition *condition() const
+ { return &static_cast<condition_holder*>(m_shmem.get_address())->cond_; }
- class construct_func_t;
- /// @endcond
-};
+ #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ interprocess_mutex *mutex() const
+ { return &static_cast<condition_holder*>(m_shmem.get_address())->mutex_; }
+
+ template <class Lock>
+ void do_wait(Lock& lock)
+ {
+ scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
+ lock.unlock();
+ this->condition()->wait(internal_lock);
+ lock.lock();
+ }
-/// @cond
-class named_condition::construct_func_t
-{
- public:
- enum CreationType { open_only, open_or_create, create_only };
+ template <class Lock>
+ bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time)
+ {
+ scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
+ lock.unlock();
+ bool r = this->condition()->timed_wait(internal_lock, abs_time);
+ lock.lock();
+ return r;
+ }
+ #endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
- construct_func_t(CreationType type)
- : m_creation_type(type){}
+ detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- bool operator()(void *address, std::size_t, bool created) const
- {
- switch(m_creation_type){
- case open_only:
- return true;
- break;
- case create_only:
- case open_or_create:
- if(created){
- new(address)interprocess_condition;
- }
- return true;
- break;
-
- default:
- return false;
- break;
- }
- return true;
- }
- private:
- CreationType m_creation_type;
+ template <class T, class Arg> friend class boost::interprocess::detail::named_creation_functor;
+ typedef detail::named_creation_functor<condition_holder> construct_func_t;
+ /// @endcond
};
-/// @endcond
inline named_condition::~named_condition()
{}
@@ -144,23 +161,23 @@
inline named_condition::named_condition(create_only_t, const char *name)
: m_shmem (create_only
,name
- ,sizeof(interprocess_condition) +
+ ,sizeof(condition_holder) +
detail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::create_only))
+ ,construct_func_t(detail::DoCreate))
{}
inline named_condition::named_condition(open_or_create_t, const char *name)
: m_shmem (open_or_create
,name
- ,sizeof(interprocess_condition) +
+ ,sizeof(condition_holder) +
detail::managed_open_or_create_impl<shared_memory_object>::
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::open_or_create))
+ ,construct_func_t(detail::DoOpenOrCreate))
{}
inline named_condition::named_condition(open_only_t, const char *name)
@@ -168,9 +185,65 @@
,name
,read_write
,0
- ,construct_func_t(construct_func_t::open_only))
+ ,construct_func_t(detail::DoOpen))
{}
+#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+
+inline void named_condition::notify_one()
+{
+ scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
+ this->condition()->notify_one();
+}
+
+inline void named_condition::notify_all()
+{
+ scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
+ this->condition()->notify_all();
+}
+
+template <typename L>
+inline void named_condition::wait(L& lock)
+{
+ if (!lock)
+ throw lock_exception();
+ this->do_wait(lock);
+}
+
+template <typename L, typename Pr>
+inline void named_condition::wait(L& lock, Pr pred)
+{
+ if (!lock)
+ throw lock_exception();
+ while (!pred())
+ this->do_wait(lock);
+}
+
+template <typename L>
+inline bool named_condition::timed_wait
+ (L& lock, const boost::posix_time::ptime &abs_time)
+{
+ if (!lock)
+ throw lock_exception();
+ return this->do_timed_wait(lock, abs_time);
+}
+
+template <typename L, typename Pr>
+inline bool named_condition::timed_wait
+ (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
+{
+ if (!lock)
+ throw lock_exception();
+
+ while (!pred()){
+ if(!this->do_timed_wait(lock, abs_time)){
+ return pred();
+ }
+ }
+ return true;
+}
+
+#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
inline void named_condition::notify_one()
{ this->condition()->notify_one(); }
@@ -187,8 +260,7 @@
}
template <typename L, typename Pr>
-inline void named_condition::wait
- (L& lock, Pr pred)
+inline void named_condition::wait(L& lock, Pr pred)
{
if (!lock)
throw lock_exception();
@@ -202,8 +274,7 @@
(L& lock, const boost::posix_time::ptime &abs_time)
{
if (!lock)
- throw lock_exception();
-
+ throw lock_exception();
return this->condition()->do_timed_wait(abs_time, *lock.mutex()->mutex());
}
@@ -212,22 +283,24 @@
(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
{
if (!lock)
- throw lock_exception();
+ throw lock_exception();
while (!pred()){
- if (!this->condition()->do_timed_wait(abs_time, *lock.mutex()->mutex()))
- return pred();
+ if (!this->condition()->do_timed_wait(abs_time, *lock.mutex()->mutex()))
+ return pred();
}
return true;
}
+#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+
inline bool named_condition::remove(const char *name)
{ return shared_memory_object::remove(name); }
} //namespace interprocess
-} // namespace boost
+} //namespace boost
#include <boost/interprocess/detail/config_end.hpp>
-#endif // BOOST_NAMED_CONDITION_HPP
+#endif // BOOST_INTERPROCESS_NAMED_CONDITION_HPP
Modified: trunk/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -19,14 +19,19 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/shared_memory_object.hpp>
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
-#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
-#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-
-/*!\file
- Describes a named mutex class for inter-process synchronization
-*/
+#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
+
+#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ #include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
+#else
+ #include <boost/interprocess/shared_memory_object.hpp>
+ #include <boost/interprocess/sync/interprocess_mutex.hpp>
+ #include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
+ #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#endif
+
+//!\file
+//!Describes a named mutex class for inter-process synchronization
namespace boost {
@@ -34,100 +39,117 @@
class named_condition;
-/*!A mutex with a global name, so it can be found from different
- processes. This mutex can't be placed in shared memory, and
- each process should have it's own named_mutex.*/
+//!A mutex with a global name, so it can be found from different
+//!processes. This mutex can't be placed in shared memory, and
+//!each process should have it's own named_mutex.
class named_mutex
{
/// @cond
+
//Non-copyable
named_mutex();
named_mutex(const named_mutex &);
named_mutex &operator=(const named_mutex &);
friend class named_condition;
/// @endcond
+
public:
- /*!Creates a global interprocess_mutex with a name.*/
+ //!Creates a global interprocess_mutex with a name.
+ //!Throws interprocess_exception on error.
named_mutex(create_only_t create_only, const char *name);
- /*!Opens or creates a global mutex with a name.
- If the mutex is created, this call is equivalent to create().
- If the mutex is already created, this call is equivalent to open().
- Does not throw*/
+ //!Opens or creates a global mutex with a name.
+ //!If the mutex is created, this call is equivalent to
+ //!named_mutex(create_only_t, ... )
+ //!If the mutex is already created, this call is equivalent
+ //!named_mutex(open_only_t, ... )
+ //!Does not throw
named_mutex(open_or_create_t open_or_create, const char *name);
- /*!Opens a global mutex with a name if that mutex is previously.
- created. If it is not previously created this function return false.
- Does not throw*/
+ //!Opens a global mutex with a name if that mutex is previously
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
named_mutex(open_only_t open_only, const char *name);
- /*!Closes the named mutex. Does not throw*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~named_mutex();
- /*!Unlocks a previously locked interprocess_mutex.*/
+ //!Unlocks a previously locked
+ //!interprocess_mutex.
void unlock();
- /*!Locks interprocess_mutex, sleeps when interprocess_mutex is already locked.
- Throws interprocess_exception if a severe error is found*/
+ //!Locks interprocess_mutex, sleeps when interprocess_mutex is already locked.
+ //!Throws interprocess_exception if a severe error is found
void lock();
- /*! Tries to lock the interprocess_mutex, returns false when interprocess_mutex
- is already locked, returns true when success.
- Throws interprocess_exception if a severe error is found*/
+ //!Tries to lock the interprocess_mutex, returns false when interprocess_mutex
+ //!is already locked, returns true when success.
+ //!Throws interprocess_exception if a severe error is found
bool try_lock();
- /*! Tries to lock the interprocess_mutex until time abs_time,
- Returns false when timeout expires, returns true when locks.
- Throws interprocess_exception if a severe error is found*/
+ //!Tries to lock the interprocess_mutex until time abs_time,
+ //!Returns false when timeout expires, returns true when locks.
+ //!Throws interprocess_exception if a severe error is found
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*! Erases a named mutex from the system*/
+ //!Erases a named mutex from the system.
+ //!Returns false on error. Never throws.
static bool remove(const char *name);
/// @cond
private:
+ #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ detail::named_semaphore_wrapper m_sem;
+ #else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
interprocess_mutex *mutex() const
{ return static_cast<interprocess_mutex*>(m_shmem.get_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
-
- class construct_func_t;
+ typedef detail::named_creation_functor<interprocess_mutex> construct_func_t;
+ #endif
/// @endcond
};
/// @cond
-class named_mutex::construct_func_t
-{
- public:
- enum CreationType { open_only, open_or_create, create_only };
- construct_func_t(CreationType type)
- : m_creation_type(type){}
+#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
- bool operator()(void *address, std::size_t, bool created) const
- {
- switch(m_creation_type){
- case open_only:
- return true;
- break;
- case create_only:
- case open_or_create:
- if(created){
- new(address)interprocess_mutex;
- }
- return true;
- break;
-
- default:
- return false;
- break;
- }
- return true;
- }
- private:
- CreationType m_creation_type;
-};
-/// @endcond
+inline named_mutex::named_mutex(create_only_t, const char *name)
+ : m_sem(detail::DoCreate, name, read_write, 1)
+{}
+
+inline named_mutex::named_mutex(open_or_create_t, const char *name)
+ : m_sem(detail::DoOpenOrCreate, name, read_write, 1)
+{}
+
+inline named_mutex::named_mutex(open_only_t, const char *name)
+ : m_sem(detail::DoOpen, name, read_write, 1)
+{}
+
+inline named_mutex::~named_mutex()
+{}
+
+inline void named_mutex::lock()
+{ m_sem.wait(); }
+
+inline void named_mutex::unlock()
+{ m_sem.post(); }
+
+inline bool named_mutex::try_lock()
+{ return m_sem.try_wait(); }
+
+inline bool named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
+{ return m_sem.timed_wait(abs_time); }
+
+inline bool named_mutex::remove(const char *name)
+{ return detail::named_semaphore_wrapper::remove(name); }
+
+#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
inline named_mutex::~named_mutex()
{}
@@ -140,7 +162,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::create_only))
+ ,construct_func_t(detail::DoCreate))
{}
inline named_mutex::named_mutex(open_or_create_t, const char *name)
@@ -151,7 +173,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::open_or_create))
+ ,construct_func_t(detail::DoOpenOrCreate))
{}
inline named_mutex::named_mutex(open_only_t, const char *name)
@@ -159,7 +181,7 @@
,name
,read_write
,0
- ,construct_func_t(construct_func_t::open_only))
+ ,construct_func_t(detail::DoOpen))
{}
inline void named_mutex::lock()
@@ -177,6 +199,10 @@
inline bool named_mutex::remove(const char *name)
{ return shared_memory_object::remove(name); }
+#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+
+/// @endcond
+
} //namespace interprocess {
} //namespace boost {
Modified: trunk/boost/interprocess/sync/named_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_recursive_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,17 +23,17 @@
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
+#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
-/*!\file
- Describes a named interprocess_mutex class for inter-process synchronization
-*/
+//!\file
+//!Describes a named named_recursive_mutex class for inter-process synchronization
namespace boost {
namespace interprocess {
-/*!A recursive mutex with a global name, so it can be found from different
- processes. This mutex can't be placed in shared memory, and
- each process should have it's own named_recursive_mutex.*/
+//!A recursive mutex with a global name, so it can be found from different
+//!processes. This mutex can't be placed in shared memory, and
+//!each process should have it's own named_recursive_mutex.
class named_recursive_mutex
{
/// @cond
@@ -43,41 +43,52 @@
named_recursive_mutex &operator=(const named_recursive_mutex &);
/// @endcond
public:
- /*!Creates a global interprocess_mutex with a name.*/
+
+ //!Creates a global recursive_mutex with a name.
+ //!If the recursive_mutex can't be created throws interprocess_exception
named_recursive_mutex(create_only_t create_only, const char *name);
- /*!Opens or creates a global interprocess_mutex with a name.
- If the interprocess_mutex is created, this call is equivalent to create().
- If the interprocess_mutex is already created, this call is equivalent to open().
- Does not throw*/
+ //!Opens or creates a global recursive_mutex with a name.
+ //!If the recursive_mutex is created, this call is equivalent to
+ //!named_recursive_mutex(create_only_t, ... )
+ //!If the recursive_mutex is already created, this call is equivalent
+ //!named_recursive_mutex(open_only_t, ... )
+ //!Does not throw
named_recursive_mutex(open_or_create_t open_or_create, const char *name);
- /*!Opens a global interprocess_mutex with a name if that interprocess_mutex is previously.
- created. If it is not previously created this function return false.
- Does not throw*/
+ //!Opens a global recursive_mutex with a name if that recursive_mutex is previously
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
named_recursive_mutex(open_only_t open_only, const char *name);
- /*!Destroys named interprocess_mutex. Does not throw*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~named_recursive_mutex();
- /*!Unlocks a previously locked interprocess_mutex.*/
+ //!Unlocks a previously locked
+ //!named_recursive_mutex.
void unlock();
- /*!Locks interprocess_mutex, sleeps when interprocess_mutex is already locked.
- Throws interprocess_exception if a severe error is found*/
+ //!Locks named_recursive_mutex, sleeps when named_recursive_mutex is already locked.
+ //!Throws interprocess_exception if a severe error is found.
void lock();
- /*! Tries to lock the interprocess_mutex, returns false when interprocess_mutex
- is already locked, returns true when success.
- Throws interprocess_exception if a severe error is found*/
+ //!Tries to lock the named_recursive_mutex, returns false when named_recursive_mutex
+ //!is already locked, returns true when success.
+ //!Throws interprocess_exception if a severe error is found.
bool try_lock();
- /*! Tries to lock the interprocess_mutex until time abs_time,
- Returns false when timeout expires, returns true when locks.
- Throws interprocess_exception if a severe error is found*/
+ //!Tries to lock the named_recursive_mutex until time abs_time,
+ //!Returns false when timeout expires, returns true when locks.
+ //!Throws interprocess_exception if a severe error is found
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*! Erases a named recursive mutex from the system*/
+ //!Erases a named recursive mutex
+ //!from the system
static bool remove(const char *name);
/// @cond
@@ -86,45 +97,10 @@
{ return static_cast<interprocess_recursive_mutex*>(m_shmem.get_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
-
- class construct_func_t;
+ typedef detail::named_creation_functor<interprocess_recursive_mutex> construct_func_t;
/// @endcond
};
-/// @cond
-class named_recursive_mutex::construct_func_t
-{
- public:
- enum CreationType { open_only, open_or_create, create_only };
-
- construct_func_t(CreationType type)
- : m_creation_type(type){}
-
- bool operator()(void *address, std::size_t, bool created) const
- {
- switch(m_creation_type){
- case open_only:
- return true;
- break;
- case create_only:
- case open_or_create:
- if(created){
- new(address)interprocess_recursive_mutex;
- }
- return true;
- break;
-
- default:
- return false;
- break;
- }
- return true;
- }
- private:
- CreationType m_creation_type;
-};
-/// @endcond
-
inline named_recursive_mutex::~named_recursive_mutex()
{}
@@ -136,7 +112,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::create_only))
+ ,construct_func_t(detail::DoCreate))
{}
inline named_recursive_mutex::named_recursive_mutex(open_or_create_t, const char *name)
@@ -147,7 +123,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::open_or_create))
+ ,construct_func_t(detail::DoOpenOrCreate))
{}
inline named_recursive_mutex::named_recursive_mutex(open_only_t, const char *name)
@@ -155,7 +131,7 @@
,name
,read_write
,0
- ,construct_func_t(construct_func_t::open_only))
+ ,construct_func_t(detail::DoOpen))
{}
inline void named_recursive_mutex::lock()
Modified: trunk/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/named_semaphore.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -20,113 +20,139 @@
#include <boost/interprocess/creation_tags.hpp>
#include <boost/interprocess/exceptions.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+
+#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#include <boost/interprocess/sync/posix/semaphore_wrapper.hpp>
+#else
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
+#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
+#endif
-/*!\file
- Describes a named semaphore class for inter-process synchronization
-*/
+//!\file
+//!Describes a named semaphore class for inter-process synchronization
namespace boost {
-
namespace interprocess {
-/*!A interprocess_semaphore with a global name, so it can be found from different
- processes. Allows several resource sharing patterns and efficient
- acknowledgment mechanisms.*/
+//!A semaphore with a global name, so it can be found from different
+//!processes. Allows several resource sharing patterns and efficient
+//!acknowledgment mechanisms.
class named_semaphore
{
/// @cond
+
//Non-copyable
named_semaphore();
named_semaphore(const named_semaphore &);
named_semaphore &operator=(const named_semaphore &);
/// @endcond
+
public:
- /*!Creates a global interprocess_semaphore with a name, and an initial count.
- It will return an false if the interprocess_semaphore is already created.*/
+ //!Creates a global semaphore with a name, and an initial count.
+ //!If the semaphore can't be created throws interprocess_exception
named_semaphore(create_only_t, const char *name, int initialCount);
- /*!Opens or creates a global interprocess_semaphore with a name, and an initial count.
- If the interprocess_semaphore is created, this call is equivalent to create().
- If the interprocess_semaphore is already created, this call is equivalent to open()
- and initialCount is ignored.*/
+ //!Opens or creates a global semaphore with a name, and an initial count.
+ //!If the semaphore is created, this call is equivalent to
+ //!named_semaphore(create_only_t, ...)
+ //!If the semaphore is already created, this call is equivalent to
+ //!named_semaphore(open_only_t, ... )
+ //!and initialCount is ignored.
named_semaphore(open_or_create_t, const char *name, int initialCount);
- /*!Opens a global interprocess_semaphore with a name if that interprocess_semaphore is previously.
- created. If it is not previously created this function return false.*/
+ //!Opens a global semaphore with a name if that semaphore is previously.
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
named_semaphore(open_only_t, const char *name);
- /*!Destroys the named semaphore. Does not throw*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~named_semaphore();
- /*!Increments the interprocess_semaphore count. If there are processes/threads blocked waiting
- for the interprocess_semaphore, then one of these processes will return successfully from
- its wait function. If there is an error an interprocess_exception exception is thrown.*/
+ //!Increments the semaphore count. If there are processes/threads blocked waiting
+ //!for the semaphore, then one of these processes will return successfully from
+ //!its wait function. If there is an error an interprocess_exception exception is thrown.
void post();
- /*!Decrements the interprocess_semaphore. If the interprocess_semaphore value is not greater than zero,
- then the calling process/thread blocks until it can decrement the counter.
- If there is an error an interprocess_exception exception is thrown.*/
+ //!Decrements the semaphore. If the semaphore value is not greater than zero,
+ //!then the calling process/thread blocks until it can decrement the counter.
+ //!If there is an error an interprocess_exception exception is thrown.
void wait();
- /*!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater than zero
- and returns true. If the value is not greater than zero returns false.
- If there is an error an interprocess_exception exception is thrown.*/
+ //!Decrements the semaphore if the semaphore's value is greater than zero
+ //!and returns true. If the value is not greater than zero returns false.
+ //!If there is an error an interprocess_exception exception is thrown.
bool try_wait();
- /*!Decrements the interprocess_semaphore if the interprocess_semaphore's value is greater
- than zero and returns true. Otherwise, waits for the interprocess_semaphore
- to the posted or the timeout expires. If the timeout expires, the
- function returns false. If the interprocess_semaphore is posted the function
- returns true. If there is an error throws sem_exception*/
+ //!Decrements the semaphore if the semaphore's value is greater
+ //!than zero and returns true. Otherwise, waits for the semaphore
+ //!to the posted or the timeout expires. If the timeout expires, the
+ //!function returns false. If the semaphore is posted the function
+ //!returns true. If there is an error throws sem_exception
bool timed_wait(const boost::posix_time::ptime &abs_time);
- /*!Erases a named semaphore from the system*/
+ //!Erases a named semaphore from the system.
+ //!Returns false on error. Never throws.
static bool remove(const char *name);
/// @cond
private:
+ #ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ detail::named_semaphore_wrapper m_sem;
+ #else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+ interprocess_semaphore *semaphore() const
+ { return static_cast<interprocess_semaphore*>(m_shmem.get_address()); }
+
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
- class construct_func_t;
+ typedef detail::named_creation_functor<interprocess_semaphore, int> construct_func_t;
+ #endif
/// @endcond
};
/// @cond
-class named_semaphore::construct_func_t
-{
- public:
- enum CreationType { open_only, open_or_create, create_only };
- construct_func_t(CreationType type, int init_count)
- : m_creation_type(type), m_init_count(init_count){}
+#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
- bool operator()(void *address, std::size_t, bool created) const
- {
- switch(m_creation_type){
- case open_only:
- return true;
- break;
- case create_only:
- case open_or_create:
- if(created){
- new(address)interprocess_semaphore(m_init_count);
- }
- return true;
- break;
-
- default:
- return false;
- break;
- }
- return true;
- }
- private:
- CreationType m_creation_type;
- int m_init_count;
-};
-/// @endcond
+inline named_semaphore::named_semaphore
+ (create_only_t, const char *name, int initialCount)
+ : m_sem(detail::DoCreate, name, read_write, initialCount)
+{}
+
+inline named_semaphore::named_semaphore
+ (open_or_create_t, const char *name, int initialCount)
+ : m_sem(detail::DoOpenOrCreate, name, read_write, initialCount)
+{}
+
+inline named_semaphore::named_semaphore
+ (open_only_t, const char *name)
+ : m_sem(detail::DoOpen, name, read_write, 1)
+{}
+
+inline named_semaphore::~named_semaphore()
+{}
+
+inline void named_semaphore::wait()
+{ m_sem.wait(); }
+
+inline void named_semaphore::post()
+{ m_sem.post(); }
+
+inline bool named_semaphore::try_wait()
+{ return m_sem.try_wait(); }
+
+inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
+{ return m_sem.timed_wait(abs_time); }
+
+inline bool named_semaphore::remove(const char *name)
+{ return detail::named_semaphore_wrapper::remove(name); }
+
+#else //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
inline named_semaphore::~named_semaphore()
{}
@@ -140,7 +166,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::create_only, initialCount))
+ ,construct_func_t(detail::DoCreate, initialCount))
{}
inline named_semaphore::named_semaphore
@@ -152,7 +178,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::open_or_create, initialCount))
+ ,construct_func_t(detail::DoOpenOrCreate, initialCount))
{}
inline named_semaphore::named_semaphore
@@ -161,26 +187,29 @@
,name
,read_write
,0
- ,construct_func_t(construct_func_t::open_only, 0))
+ ,construct_func_t(detail::DoOpen, 0))
{}
inline void named_semaphore::post()
-{ static_cast<interprocess_semaphore*>(m_shmem.get_address())->post(); }
+{ semaphore()->post(); }
inline void named_semaphore::wait()
-{ static_cast<interprocess_semaphore*>(m_shmem.get_address())->wait(); }
+{ semaphore()->wait(); }
inline bool named_semaphore::try_wait()
-{ return static_cast<interprocess_semaphore*>(m_shmem.get_address())->try_wait(); }
+{ return semaphore()->try_wait(); }
inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
-{ return static_cast<interprocess_semaphore*>(m_shmem.get_address())->timed_wait(abs_time); }
+{ return semaphore()->timed_wait(abs_time); }
inline bool named_semaphore::remove(const char *name)
{ return shared_memory_object::remove(name); }
-} //namespace interprocess {
+#endif //#ifdef BOOST_INTERPROCESS_POSIX_SEMAPHORES
+
+/// @endcond
+} //namespace interprocess {
} //namespace boost {
Modified: trunk/boost/interprocess/sync/named_upgradable_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_upgradable_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_upgradable_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -23,19 +23,19 @@
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/sync/emulation/named_creation_functor.hpp>
-/*!\file
- Describes a named upgradable mutex class for inter-process synchronization
-*/
+//!\file
+//!Describes a named upgradable mutex class for inter-process synchronization
namespace boost {
namespace interprocess {
class named_condition;
-/*!A upgradable mutex with a global name, so it can be found from different
- processes. This mutex can't be placed in shared memory, and
- each process should have it's own named upgradable mutex.*/
+//!A upgradable mutex with a global name, so it can be found from different
+//!processes. This mutex can't be placed in shared memory, and
+//!each process should have it's own named upgradable mutex.
class named_upgradable_mutex
{
/// @cond
@@ -46,164 +46,174 @@
friend class named_condition;
/// @endcond
public:
- /*!Creates a global interprocess_mutex with a name.*/
+
+ //!Creates a global upgradable mutex with a name.
+ //!If the upgradable mutex can't be created throws interprocess_exception
named_upgradable_mutex(create_only_t create_only, const char *name);
- /*!Opens or creates a global upgradable mutex with a name.
- If the upgradable mutex is created, this call is equivalent to create().
- If the upgradable mutex is already created, this call is equivalent to open().
- Throws interprocess_exception on error.*/
+ //!Opens or creates a global upgradable mutex with a name, and an initial count.
+ //!If the upgradable mutex is created, this call is equivalent to
+ //!named_upgradable_mutex(create_only_t, ...)
+ //!If the upgradable mutex is already created, this call is equivalent to
+ //!named_upgradable_mutex(open_only_t, ... ).
named_upgradable_mutex(open_or_create_t open_or_create, const char *name);
- /*!Opens a global upgradable mutex with a name if that mutex is previously.
- created. If it is not previously created this function return false.
- Throws interprocess_exception on error.*/
+ //!Opens a global upgradable mutex with a name if that upgradable mutex
+ //!is previously.
+ //!created. If it is not previously created this function throws
+ //!interprocess_exception.
named_upgradable_mutex(open_only_t open_only, const char *name);
- /*!Closes the named upgradable mutex. Does not throw*/
+ //!Destroys *this and indicates that the calling process is finished using
+ //!the resource. The destructor function will deallocate
+ //!any system resources allocated by the system for use by this process for
+ //!this resource. The resource can still be opened again calling
+ //!the open constructor overload. To erase the resource from the system
+ //!use remove().
~named_upgradable_mutex();
//Exclusive locking
- /*!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
- and if another thread has exclusive, sharable or upgradable ownership of
- the mutex, it waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
+ //! and if another thread has exclusive, sharable or upgradable ownership of
+ //! the mutex, it waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock();
- /*!Effects: The calling thread tries to acquire exclusive ownership of the mutex
- without waiting. If no other thread has exclusive, sharable or upgradable
- ownership of the mutex this succeeds.
- Returns: If it can acquire exclusive ownership immediately returns true.
- If it has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! without waiting. If no other thread has exclusive, sharable or upgradable
+ //! ownership of the mutex this succeeds.
+ //!Returns: If it can acquire exclusive ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock();
- /*!Effects: The calling thread tries to acquire exclusive ownership of the mutex
- waiting if necessary until no other thread has has exclusive, sharable or
- upgradable ownership of the mutex or abs_time is reached.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive, sharable or
+ //! upgradable ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The calling thread releases the exclusive ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The calling thread releases the exclusive ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock();
//Sharable locking
- /*!Effects: The calling thread tries to obtain sharable ownership of the mutex,
- and if another thread has exclusive or upgradable ownership of the mutex,
- waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
+ //! and if another thread has exclusive or upgradable ownership of the mutex,
+ //! waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock_sharable();
- /*!Effects: The calling thread tries to acquire sharable ownership of the mutex
- without waiting. If no other thread has has exclusive or upgradable ownership
- of the mutex this succeeds.
- Returns: If it can acquire sharable ownership immediately returns true. If it
- has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! without waiting. If no other thread has has exclusive or upgradable ownership
+ //! of the mutex this succeeds.
+ //!Returns: If it can acquire sharable ownership immediately returns true. If it
+ //! has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock_sharable();
- /*!Effects: The calling thread tries to acquire sharable ownership of the mutex
- waiting if necessary until no other thread has has exclusive or upgradable
- ownership of the mutex or abs_time is reached.
- Returns: If acquires sharable ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire sharable ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive or upgradable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have sharable ownership of the mutex.
- Effects: The calling thread releases the sharable ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The calling thread releases the sharable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_sharable();
//Upgradable locking
- /*!Effects: The calling thread tries to obtain upgradable ownership of the mutex,
- and if another thread has exclusive or upgradable ownership of the mutex,
- waits until it can obtain the ownership.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to obtain upgradable ownership of the mutex,
+ //! and if another thread has exclusive or upgradable ownership of the mutex,
+ //! waits until it can obtain the ownership.
+ //!Throws: interprocess_exception on error.
void lock_upgradable();
- /*!Effects: The calling thread tries to acquire upgradable ownership of the mutex
- without waiting. If no other thread has has exclusive or upgradable ownership
- of the mutex this succeeds.
- Returns: If it can acquire upgradable ownership immediately returns true.
- If it has to wait, returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire upgradable ownership of the mutex
+ //! without waiting. If no other thread has has exclusive or upgradable ownership
+ //! of the mutex this succeeds.
+ //!Returns: If it can acquire upgradable ownership immediately returns true.
+ //! If it has to wait, returns false.
+ //!Throws: interprocess_exception on error.
bool try_lock_upgradable();
- /*!Effects: The calling thread tries to acquire upgradable ownership of the mutex
- waiting if necessary until no other thread has has exclusive or upgradable
- ownership of the mutex or abs_time is reached.
- Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
- Throws: interprocess_exception on error.*/
+ //!Effects: The calling thread tries to acquire upgradable ownership of the mutex
+ //! waiting if necessary until no other thread has has exclusive or upgradable
+ //! ownership of the mutex or abs_time is reached.
+ //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.
+ //!Throws: interprocess_exception on error.
bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The calling thread releases the upgradable ownership of the mutex.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The calling thread releases the upgradable ownership of the mutex.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable();
//Demotions
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The thread atomically releases exclusive ownership and acquires
- upgradable ownership. This operation is non-blocking.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The thread atomically releases exclusive ownership and acquires
+ //! upgradable ownership. This operation is non-blocking.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_upgradable();
- /*!Precondition: The thread must have exclusive ownership of the mutex.
- Effects: The thread atomically releases exclusive ownership and acquires
- sharable ownership. This operation is non-blocking.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have exclusive ownership of the mutex.
+ //!Effects: The thread atomically releases exclusive ownership and acquires
+ //! sharable ownership. This operation is non-blocking.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_and_lock_sharable();
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and acquires
- sharable ownership. This operation is non-blocking.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and acquires
+ //! sharable ownership. This operation is non-blocking.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock_sharable();
//Promotions
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and acquires
- exclusive ownership. This operation will block until all threads with
- sharable ownership releas it.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and acquires
+ //! exclusive ownership. This operation will block until all threads with
+ //! sharable ownership releas it.
+ //!Throws: An exception derived from interprocess_exception on error.
void unlock_upgradable_and_lock();
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and tries to
- acquire exclusive ownership. This operation will fail if there are threads
- with sharable ownership, but it will maintain upgradable ownership.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and tries to
+ //! acquire exclusive ownership. This operation will fail if there are threads
+ //! with sharable ownership, but it will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_upgradable_and_lock();
- /*!Precondition: The thread must have upgradable ownership of the mutex.
- Effects: The thread atomically releases upgradable ownership and tries to acquire
- exclusive ownership, waiting if necessary until abs_time. This operation will
- fail if there are threads with sharable ownership or timeout reaches, but it
- will maintain upgradable ownership.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error. */
+ //!Precondition: The thread must have upgradable ownership of the mutex.
+ //!Effects: The thread atomically releases upgradable ownership and tries to acquire
+ //! exclusive ownership, waiting if necessary until abs_time. This operation will
+ //! fail if there are threads with sharable ownership or timeout reaches, but it
+ //! will maintain upgradable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);
- /*!Precondition: The thread must have sharable ownership of the mutex.
- Effects: The thread atomically releases sharable ownership and tries to acquire
- exclusive ownership. This operation will fail if there are threads with sharable
- or upgradable ownership, but it will maintain sharable ownership.
- Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
- Throws: An exception derived from interprocess_exception on error.*/
+ //!Precondition: The thread must have sharable ownership of the mutex.
+ //!Effects: The thread atomically releases sharable ownership and tries to acquire
+ //! exclusive ownership. This operation will fail if there are threads with sharable
+ //! or upgradable ownership, but it will maintain sharable ownership.
+ //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
+ //!Throws: An exception derived from interprocess_exception on error.
bool try_unlock_sharable_and_lock();
bool try_unlock_sharable_and_lock_upgradable();
- /*! Erases a named upgradable mutex from the system*/
+ //!Erases a named upgradable mutex from the system.
+ //!Returns false on error. Never throws.
static bool remove(const char *name);
/// @cond
@@ -212,43 +222,10 @@
{ return static_cast<interprocess_upgradable_mutex*>(m_shmem.get_address()); }
detail::managed_open_or_create_impl<shared_memory_object> m_shmem;
-
- class construct_func_t;
+ typedef detail::named_creation_functor<interprocess_upgradable_mutex> construct_func_t;
/// @endcond
};
-/// @cond
-class named_upgradable_mutex::construct_func_t
-{
- public:
- enum CreationType { open_only, open_or_create, create_only };
- construct_func_t(CreationType type)
- : m_creation_type(type){}
-
- bool operator()(void *address, std::size_t, bool created) const
- {
- switch(m_creation_type){
- case open_only:
- return true;
- break;
- case create_only:
- case open_or_create:
- if(created){
- new(address)interprocess_upgradable_mutex;
- }
- return true;
- break;
-
- default:
- return false;
- break;
- }
- return true;
- }
- private:
- CreationType m_creation_type;
-};
-/// @endcond
inline named_upgradable_mutex::~named_upgradable_mutex()
{}
@@ -261,7 +238,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::create_only))
+ ,construct_func_t(detail::DoCreate))
{}
inline named_upgradable_mutex::named_upgradable_mutex
@@ -273,7 +250,7 @@
ManagedOpenOrCreateUserOffset
,read_write
,0
- ,construct_func_t(construct_func_t::open_or_create))
+ ,construct_func_t(detail::DoOpenOrCreate))
{}
inline named_upgradable_mutex::named_upgradable_mutex
@@ -282,7 +259,7 @@
,name
,read_write
,0
- ,construct_func_t(construct_func_t::open_only))
+ ,construct_func_t(detail::DoOpen))
{}
inline void named_upgradable_mutex::lock()
Modified: trunk/boost/interprocess/sync/null_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/null_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/null_mutex.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -19,9 +19,8 @@
#include <boost/interprocess/detail/workaround.hpp>
-/*!\file
- Describes null_mutex classes
-*/
+//!\file
+//!Describes null_mutex classes
namespace boost {
@@ -30,8 +29,8 @@
namespace interprocess {
-/*!Implements a mutex that simulates a mutex without doing any operation and
- simulates a successful operation.*/
+//!Implements a mutex that simulates a mutex without doing any operation and
+//!simulates a successful operation.
class null_mutex
{
/// @cond
@@ -40,97 +39,102 @@
/// @endcond
public:
- /*!Constructor. Empty.*/
+ //!Constructor.
+ //!Empty.
null_mutex(){}
- /*!Destructor. Empty.*/
+ //!Destructor.
+ //!Empty.
~null_mutex(){}
- /*!Simulates a mutex lock() operation. Empty function. Does not throw.*/
+ //!Simulates a mutex lock() operation. Empty function.
void lock(){}
- /*!Simulates a mutex try_lock() operation. Returns always true. Does not throw.*/
+ //!Simulates a mutex try_lock() operation.
+ //!Equivalent to "return true;"
bool try_lock()
{ return true; }
- /*!Simulates a mutex timed_lock() operation. Returns always true. Does not throw.*/
+ //!Simulates a mutex timed_lock() operation.
+ //!Equivalent to "return true;"
bool timed_lock(const boost::posix_time::ptime &)
{ return true; }
- /*!Simulates a mutex unlock() operation. Empty function. Does not throw.*/
+ //!Simulates a mutex unlock() operation.
+ //!Empty function.
void unlock(){}
- /*!Simulates a mutex lock_sharable() operation. Empty function.
- Does not throw.*/
+ //!Simulates a mutex lock_sharable() operation.
+ //!Empty function.
void lock_sharable(){}
- /*!Simulates a mutex try_lock_sharable() operation. Returns always true.
- Does not throw.*/
+ //!Simulates a mutex try_lock_sharable() operation.
+ //!Equivalent to "return true;"
bool try_lock_sharable()
{ return true; }
- /*!Simulates a mutex timed_lock_sharable() operation. Returns always true.
- Does not throw.*/
+ //!Simulates a mutex timed_lock_sharable() operation.
+ //!Equivalent to "return true;"
bool timed_lock_sharable(const boost::posix_time::ptime &)
{ return true; }
- /*!Simulates a mutex unlock_sharable() operation. Empty function.
- Does not throw.*/
+ //!Simulates a mutex unlock_sharable() operation.
+ //!Empty function.
void unlock_sharable(){}
- /*!Simulates a mutex lock_upgradable() operation. Empty function.
- Does not throw.*/
+ //!Simulates a mutex lock_upgradable() operation.
+ //!Empty function.
void lock_upgradable(){}
- /*!Simulates a mutex try_lock_upgradable() operation. Returns always true.
- Does not throw.*/
+ //!Simulates a mutex try_lock_upgradable() operation.
+ //!Equivalent to "return true;"
bool try_lock_upgradable()
{ return true; }
- /*!Simulates a mutex timed_lock_upgradable() operation. Returns always true.
- Does not throw.*/
+ //!Simulates a mutex timed_lock_upgradable() operation.
+ //!Equivalent to "return true;"
bool timed_lock_upgradable(const boost::posix_time::ptime &)
{ return true; }
- /*!Simulates a mutex unlock_upgradable() operation. Empty function.
- Does not throw.*/
+ //!Simulates a mutex unlock_upgradable() operation.
+ //!Empty function.
void unlock_upgradable(){}
- /*!Simulates unlock_and_lock_upgradable(). Empty function.
- Does not throw.*/
+ //!Simulates unlock_and_lock_upgradable().
+ //!Empty function.
void unlock_and_lock_upgradable(){}
- /*!Simulates unlock_and_lock_sharable(). Empty function.
- Does not throw.*/
+ //!Simulates unlock_and_lock_sharable().
+ //!Empty function.
void unlock_and_lock_sharable(){}
- /*!Simulates unlock_upgradable_and_lock_sharable(). Empty function.
- Does not throw.*/
+ //!Simulates unlock_upgradable_and_lock_sharable().
+ //!Empty function.
void unlock_upgradable_and_lock_sharable(){}
//Promotions
- /*!Simulates unlock_upgradable_and_lock(). Empty function.
- Does not throw.*/
+ //!Simulates unlock_upgradable_and_lock().
+ //!Empty function.
void unlock_upgradable_and_lock(){}
- /*!Simulates try_unlock_upgradable_and_lock(). Returns always true.
- Does not throw.*/
+ //!Simulates try_unlock_upgradable_and_lock().
+ //!Equivalent to "return true;"
bool try_unlock_upgradable_and_lock()
{ return true; }
- /*!Simulates timed_unlock_upgradable_and_lock(). Returns always true.
- Does not throw.*/
+ //!Simulates timed_unlock_upgradable_and_lock().
+ //!Equivalent to "return true;"
bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &)
{ return true; }
- /*!Simulates try_unlock_sharable_and_lock(). Returns always true.
- Does not throw.*/
+ //!Simulates try_unlock_sharable_and_lock().
+ //!Equivalent to "return true;"
bool try_unlock_sharable_and_lock()
{ return true; }
- /*!Simulates try_unlock_sharable_and_lock_upgradable(). Returns always true.
- Does not throw.*/
+ //!Simulates try_unlock_sharable_and_lock_upgradable().
+ //!Equivalent to "return true;"
bool try_unlock_sharable_and_lock_upgradable()
{ return true; }
};
Modified: trunk/boost/interprocess/sync/posix/pthread_helpers.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/pthread_helpers.hpp (original)
+++ trunk/boost/interprocess/sync/posix/pthread_helpers.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -28,10 +28,10 @@
#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
- /*!Makes pthread_mutexattr_t cleanup easy when using exceptions*/
+ //!Makes pthread_mutexattr_t cleanup easy when using exceptions
struct mutexattr_wrapper
{
- /*!Constructor*/
+ //!Constructor
mutexattr_wrapper(bool recursive = false)
{
if(pthread_mutexattr_init(&m_attr)!=0 ||
@@ -41,19 +41,19 @@
throw boost::interprocess::interprocess_exception();
}
- /*!Destructor*/
+ //!Destructor
~mutexattr_wrapper() { pthread_mutexattr_destroy(&m_attr); }
- /*!This allows using mutexattr_wrapper as pthread_mutexattr_t*/
+ //!This allows using mutexattr_wrapper as pthread_mutexattr_t
operator pthread_mutexattr_t&() { return m_attr; }
pthread_mutexattr_t m_attr;
};
- /*!Makes pthread_condattr_t cleanup easy when using exceptions*/
+ //!Makes pthread_condattr_t cleanup easy when using exceptions
struct condattr_wrapper
{
- /*!Constructor*/
+ //!Constructor
condattr_wrapper()
{
if(pthread_condattr_init(&m_attr)!=0 ||
@@ -61,20 +61,20 @@
throw boost::interprocess::interprocess_exception();
}
- /*!Destructor*/
+ //!Destructor
~condattr_wrapper() { pthread_condattr_destroy(&m_attr); }
- /*!This allows using condattr_wrapper as pthread_condattr_t*/
+ //!This allows using condattr_wrapper as pthread_condattr_t
operator pthread_condattr_t&(){ return m_attr; }
pthread_condattr_t m_attr;
};
- /*!Makes initialized pthread_mutex_t cleanup easy when using exceptions*/
+ //!Makes initialized pthread_mutex_t cleanup easy when using exceptions
class mutex_initializer
{
public:
- /*!Constructor. Takes interprocess_mutex attributes to initialize the interprocess_mutex*/
+ //!Constructor. Takes interprocess_mutex attributes to initialize the interprocess_mutex
mutex_initializer(pthread_mutex_t &mut, pthread_mutexattr_t &mut_attr)
: mp_mut(&mut)
{
@@ -90,7 +90,7 @@
pthread_mutex_t *mp_mut;
};
- /*!Makes initialized pthread_cond_t cleanup easy when using exceptions*/
+ //!Makes initialized pthread_cond_t cleanup easy when using exceptions
class condition_initializer
{
public:
@@ -113,10 +113,10 @@
#if defined BOOST_INTERPROCESS_POSIX_BARRIERS
- /*!Makes pthread_barrierattr_t cleanup easy when using exceptions*/
+ //!Makes pthread_barrierattr_t cleanup easy when using exceptions
struct barrierattr_wrapper
{
- /*!Constructor*/
+ //!Constructor
barrierattr_wrapper()
{
if(pthread_barrierattr_init(&m_attr)!=0 ||
@@ -124,20 +124,20 @@
throw boost::interprocess::interprocess_exception();
}
- /*!Destructor*/
+ //!Destructor
~barrierattr_wrapper() { pthread_barrierattr_destroy(&m_attr); }
- /*!This allows using mutexattr_wrapper as pthread_barrierattr_t*/
+ //!This allows using mutexattr_wrapper as pthread_barrierattr_t
operator pthread_barrierattr_t&() { return m_attr; }
pthread_barrierattr_t m_attr;
};
- /*!Makes initialized pthread_barrier_t cleanup easy when using exceptions*/
+ //!Makes initialized pthread_barrier_t cleanup easy when using exceptions
class barrier_initializer
{
public:
- /*!Constructor. Takes barrier attributes to initialize the barrier*/
+ //!Constructor. Takes barrier attributes to initialize the barrier
barrier_initializer(pthread_barrier_t &mut,
pthread_barrierattr_t &mut_attr,
int count)
Modified: trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp (original)
+++ trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -11,90 +11,247 @@
#ifndef BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
#define BOOST_INTERPROCESS_POSIX_SEMAPHORE_WRAPPER_HPP
-#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <string>
+#include <semaphore.h>
+
+#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+#include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
+#else
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+#endif
namespace boost {
namespace interprocess {
namespace detail {
-class semaphore_wrapper
+inline bool semaphore_open
+ (sem_t *&handle, detail::create_enum_t type, const char *origname, mode_t mode,
+ unsigned int count)
{
- semaphore_wrapper();
- semaphore_wrapper(const semaphore_wrapper&);
- semaphore_wrapper &operator= (const semaphore_wrapper &);
- public:
- semaphore_wrapper(int initialCount)
- {
- int ret = sem_init(&m_sem, 1, initialCount);
- if(ret != 0){
- throw interprocess_exception(system_error_code());
- }
+ bool slash_added = origname[0] != '/';
+ //First add preceding "/"
+ std::string name;
+
+ if(slash_added){
+ name = '/';
+ }
+ name += origname;
+
+ //Create new mapping
+ int oflag = 0;
+ if(mode == read_only){
+ oflag |= O_RDONLY;
+ }
+ else if(mode == read_write){
+ oflag |= O_RDWR;
+ }
+ else{
+ error_info err(mode_error);
+ throw interprocess_exception(err);
+ }
+
+ switch(type){
+ case detail::DoOpen:
+ //No addition
+ break;
+ case detail::DoCreate:
+ oflag |= (O_CREAT | O_EXCL);
+ break;
+ case detail::DoOpenOrCreate:
+ oflag |= O_CREAT;
+ break;
+ default:
+ {
+ error_info err = other_error;
+ throw interprocess_exception(err);
+ }
}
- ~semaphore_wrapper()
- {
- int ret = sem_destroy(&m_sem);
- if(ret != 0){
- assert(0);
- }
+ //Open file using POSIX API
+ if(oflag & O_CREAT)
+ handle = sem_open(name.c_str(), oflag, S_IRWXO | S_IRWXG | S_IRWXU, count);
+ else
+ handle = sem_open(name.c_str(), oflag);
+
+ //Check for error
+ if(handle == SEM_FAILED){
+ throw interprocess_exception(error_info(errno));
}
- void post()
- {
- int ret = sem_post(&m_sem);
- if(ret != 0){
- throw interprocess_exception(system_error_code());
- }
+ if(slash_added){
+ name.erase(name.begin());
}
- void wait()
- {
- int ret = sem_wait(&m_sem);
- if(ret != 0){
- throw interprocess_exception(system_error_code());
+ return true;
+}
+
+inline void semaphore_close(sem_t *handle)
+{
+ int ret = sem_close(handle);
+ if(ret != 0){
+ assert(0);
+ }
+}
+
+inline bool semaphore_unlink(const char *name)
+{
+ try{
+ std::string str;
+ //First add preceding "/"
+ if(name[0] != '/'){
+ str = '/';
}
+ str += name;
+ return 0 != sem_unlink(str.c_str());
+ }
+ catch(...){
+ return false;
}
+}
- bool try_wait()
- {
- int res = sem_trywait(&m_sem);
+inline void semaphore_init(sem_t *handle, int initialCount)
+{
+ int ret = sem_init(handle, 1, initialCount);
+ if(ret != 0){
+ throw interprocess_exception(system_error_code());
+ }
+}
+
+inline void semaphore_destroy(sem_t *handle)
+{
+ int ret = sem_destroy(handle);
+ if(ret != 0){
+ assert(0);
+ }
+}
+
+inline void semaphore_post(sem_t *handle)
+{
+ int ret = sem_post(handle);
+ if(ret != 0){
+ throw interprocess_exception(system_error_code());
+ }
+}
+
+inline void semaphore_wait(sem_t *handle)
+{
+ int ret = sem_wait(handle);
+ if(ret != 0){
+ throw interprocess_exception(system_error_code());
+ }
+}
+
+inline bool semaphore_try_wait(sem_t *handle)
+{
+ int res = sem_trywait(handle);
+ if(res == 0)
+ return true;
+ if(system_error_code() == EAGAIN){
+ return false;
+ }
+ throw interprocess_exception(system_error_code());
+ return false;
+}
+
+inline bool semaphore_timed_wait(sem_t *handle, const boost::posix_time::ptime &abs_time)
+{
+ #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ timespec tspec = detail::ptime_to_timespec(abs_time);
+ for (;;){
+ int res = sem_timedwait(handle, &tspec);
if(res == 0)
return true;
- if(system_error_code() == EAGAIN){
+ if (res > 0){
+ //buggy glibc, copy the returned error code to errno
+ errno = res;
+ }
+ if(system_error_code() == ETIMEDOUT){
return false;
}
throw interprocess_exception(system_error_code());
- return false;
}
-
- bool timed_wait(const boost::posix_time::ptime &abs_time)
- {
- timespec tspec = detail::ptime_to_timespec(abs_time);
- for (;;){
- int res = sem_timedwait(&m_sem, &tspec);
- if(res == 0)
- return true;
- if (res > 0){
- //buggy glibc, copy the returned error code to errno
- errno = res;
- }
- if(system_error_code() == ETIMEDOUT){
- return false;
- }
- throw interprocess_exception(system_error_code());
- }
- return false;
+ return false;
+ #else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ boost::posix_time::ptime now;
+ while((now = microsec_clock::universal_time()) < abs_time){
+ if(semaphore_try_wait(handle))
+ return true;
+ thread_yield();
}
+ return false;
+ #endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+}
/*
- int get_count()const
- {
- int count;
- sem_getvalue(&m_sem, &ret);
- return count;
- }
+inline int semaphore_get_count(sem_t *handle)
+{
+ int count;
+ sem_getvalue(handle, &ret);
+ return count;
+}
*/
+
+class named_semaphore_wrapper
+{
+ named_semaphore_wrapper();
+ named_semaphore_wrapper(const named_semaphore_wrapper&);
+ named_semaphore_wrapper &operator= (const named_semaphore_wrapper &);
+
+ public:
+ named_semaphore_wrapper
+ (detail::create_enum_t type, const char *name, mode_t mode, unsigned int count)
+ { semaphore_open(mp_sem, type, name, mode, count); }
+
+ ~named_semaphore_wrapper()
+ { semaphore_close(mp_sem); }
+
+ void post()
+ { semaphore_post(mp_sem); }
+
+ void wait()
+ { semaphore_wait(mp_sem); }
+
+ bool try_wait()
+ { return semaphore_try_wait(mp_sem); }
+
+ bool timed_wait(const boost::posix_time::ptime &abs_time)
+ { return semaphore_timed_wait(mp_sem, abs_time); }
+
+ static bool remove(const char *name)
+ { return semaphore_unlink(name); }
+
+ private:
+ sem_t *mp_sem;
+};
+
+class semaphore_wrapper
+{
+ semaphore_wrapper();
+ semaphore_wrapper(const semaphore_wrapper&);
+ semaphore_wrapper &operator= (const semaphore_wrapper &);
+
+ public:
+ semaphore_wrapper(int initialCount)
+ { semaphore_init(&m_sem, initialCount); }
+
+ ~semaphore_wrapper()
+ { semaphore_destroy(&m_sem); }
+
+ void post()
+ { semaphore_post(&m_sem); }
+
+ void wait()
+ { semaphore_wait(&m_sem); }
+
+ bool try_wait()
+ { return semaphore_try_wait(&m_sem); }
+
+ bool timed_wait(const boost::posix_time::ptime &abs_time)
+ { return semaphore_timed_wait(&m_sem, abs_time); }
+
private:
sem_t m_sem;
};
Modified: trunk/boost/interprocess/sync/scoped_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/scoped_lock.hpp (original)
+++ trunk/boost/interprocess/sync/scoped_lock.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -27,9 +27,8 @@
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-/*!\file
- Describes the scoped_lock class.
-*/
+//!\file
+//!Describes the scoped_lock class.
namespace boost {
namespace interprocess {
@@ -40,16 +39,16 @@
template<class M>
class upgradable_lock;
-/*!scoped_lock is meant to carry out the tasks for locking, unlocking, try-locking
- and timed-locking (recursive or not) for the Mutex. The Mutex need not supply all
- of this functionality. If the client of scoped_lock<Mutex> does not use
- functionality which the Mutex does not supply, no harm is done. Mutex ownership
- transfer is supported through the syntax of move semantics. Ownership transfer
- is allowed both by construction and assignment. The scoped_lock does not support
- copy semantics. A compile time error results if copy construction or copy
- assignment is attempted. Mutex ownership can also be moved from an
- upgradable_lock and sharable_lock via constructor. In this role, scoped_lock
- shares the same functionality as a write_lock.*/
+//!scoped_lock is meant to carry out the tasks for locking, unlocking, try-locking
+//!and timed-locking (recursive or not) for the Mutex. The Mutex need not supply all
+//!of this functionality. If the client of scoped_lock<Mutex> does not use
+//!functionality which the Mutex does not supply, no harm is done. Mutex ownership
+//!transfer is supported through the syntax of move semantics. Ownership transfer
+//!is allowed both by construction and assignment. The scoped_lock does not support
+//!copy semantics. A compile time error results if copy construction or copy
+//!assignment is attempted. Mutex ownership can also be moved from an
+//!upgradable_lock and sharable_lock via constructor. In this role, scoped_lock
+//!shares the same functionality as a write_lock.
template <class Mutex>
class scoped_lock
{
@@ -63,69 +62,69 @@
public:
typedef Mutex mutex_type;
- /*!Effects: Default constructs a scoped_lock.
- Postconditions: owns() == false and mutex() == 0.*/
+ //!Effects: Default constructs a scoped_lock.
+ //!Postconditions: owns() == false and mutex() == 0.
scoped_lock()
: mp_mutex(0), m_locked(false)
{}
- /*!Effects: m.lock().
- Postconditions: owns() == true and mutex() == &m.
- Notes: The constructor will take ownership of the mutex. If another thread
- already owns the mutex, this thread will block until the mutex is released.
- Whether or not this constructor handles recursive locking depends upon the mutex.*/
+ //!Effects: m.lock().
+ //!Postconditions: owns() == true and mutex() == &m.
+ //!Notes: The constructor will take ownership of the mutex. If another thread
+ //! already owns the mutex, this thread will block until the mutex is released.
+ //! Whether or not this constructor handles recursive locking depends upon the mutex.
explicit scoped_lock(mutex_type& m)
: mp_mutex(&m), m_locked(false)
{ mp_mutex->lock(); m_locked = true; }
- /*!Postconditions: owns() == false, and mutex() == &m.
- Notes: The constructor will not take ownership of the mutex. There is no effect
- required on the referenced mutex.*/
+ //!Postconditions: owns() == false, and mutex() == &m.
+ //!Notes: The constructor will not take ownership of the mutex. There is no effect
+ //! required on the referenced mutex.
scoped_lock(mutex_type& m, detail::defer_lock_type)
: mp_mutex(&m), m_locked(false)
{}
- /*!Postconditions: owns() == true, and mutex() == &m.
- Notes: The constructor will suppose that the mutex is already locked. There
- is no effect required on the referenced mutex.*/
+ //!Postconditions: owns() == true, and mutex() == &m.
+ //!Notes: The constructor will suppose that the mutex is already locked. There
+ //! is no effect required on the referenced mutex.
scoped_lock(mutex_type& m, detail::accept_ownership_type)
: mp_mutex(&m), m_locked(true)
{}
- /*!Effects: m.try_lock().
- Postconditions: mutex() == &m. owns() == the return value of the
- m.try_lock() executed within the constructor.
- Notes: The constructor will take ownership of the mutex if it can do
- so without waiting. Whether or not this constructor handles recursive
- locking depends upon the mutex. If the mutex_type does not support try_lock,
- this constructor will fail at compile time if instantiated, but otherwise
- have no effect.*/
+ //!Effects: m.try_lock().
+ //!Postconditions: mutex() == &m. owns() == the return value of the
+ //! m.try_lock() executed within the constructor.
+ //!Notes: The constructor will take ownership of the mutex if it can do
+ //! so without waiting. Whether or not this constructor handles recursive
+ //! locking depends upon the mutex. If the mutex_type does not support try_lock,
+ //! this constructor will fail at compile time if instantiated, but otherwise
+ //! have no effect.
scoped_lock(mutex_type& m, detail::try_to_lock_type)
: mp_mutex(&m), m_locked(mp_mutex->try_lock())
{}
- /*!Effects: m.timed_lock(abs_time).
- Postconditions: mutex() == &m. owns() == the return value of the
- m.timed_lock(abs_time) executed within the constructor.
- Notes: The constructor will take ownership of the mutex if it can do
- it until abs_time is reached. Whether or not this constructor
- handles recursive locking depends upon the mutex. If the mutex_type
- does not support try_lock, this constructor will fail at compile
- time if instantiated, but otherwise have no effect.*/
+ //!Effects: m.timed_lock(abs_time).
+ //!Postconditions: mutex() == &m. owns() == the return value of the
+ //! m.timed_lock(abs_time) executed within the constructor.
+ //!Notes: The constructor will take ownership of the mutex if it can do
+ //! it until abs_time is reached. Whether or not this constructor
+ //! handles recursive locking depends upon the mutex. If the mutex_type
+ //! does not support try_lock, this constructor will fail at compile
+ //! time if instantiated, but otherwise have no effect.
scoped_lock(mutex_type& m, const boost::posix_time::ptime& abs_time)
: mp_mutex(&m), m_locked(mp_mutex->timed_lock(abs_time))
{}
- /*!Postconditions: mutex() == the value scop.mutex() had before the
- constructor executes. s1.mutex() == 0. owns() == the value of
- scop.owns() before the constructor executes. scop.owns().
- Notes: If the scop scoped_lock owns the mutex, ownership is moved
- to thisscoped_lock with no blocking. If the scop scoped_lock does not
- own the mutex, then neither will this scoped_lock. Only a moved
- scoped_lock's will match this signature. An non-moved scoped_lock
- can be moved with the expression: "move(lock);". This
- constructor does not alter the state of the mutex, only potentially
- who owns it.*/
+ //!Postconditions: mutex() == the value scop.mutex() had before the
+ //! constructor executes. s1.mutex() == 0. owns() == the value of
+ //! scop.owns() before the constructor executes. scop.owns().
+ //!Notes: If the scop scoped_lock owns the mutex, ownership is moved
+ //! to thisscoped_lock with no blocking. If the scop scoped_lock does not
+ //! own the mutex, then neither will this scoped_lock. Only a moved
+ //! scoped_lock's will match this signature. An non-moved scoped_lock
+ //! can be moved with the expression: "move(lock);". This
+ //! constructor does not alter the state of the mutex, only potentially
+ //! who owns it.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit scoped_lock(detail::moved_object<scoped_lock<Mutex> > scop)
: mp_mutex(0), m_locked(scop.get().owns())
@@ -136,18 +135,18 @@
{ mp_mutex = scop.release(); }
#endif
- /*!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the
- referenced mutex. upgr.release() is called.
- Postconditions: mutex() == the value upgr.mutex() had before the construction.
- upgr.mutex() == 0. owns() == upgr.owns() before the construction.
- upgr.owns() == false after the construction.
- Notes: If upgr is locked, this constructor will lock this scoped_lock while
- unlocking upgr. If upgr is unlocked, then this scoped_lock will be
- unlocked as well. Only a moved upgradable_lock's will match this
- signature. An non-moved upgradable_lock can be moved with
- the expression: "move(lock);" This constructor may block if
- other threads hold a sharable_lock on this mutex (sharable_lock's can
- share ownership with an upgradable_lock).*/
+ //!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the
+ //! referenced mutex. upgr.release() is called.
+ //!Postconditions: mutex() == the value upgr.mutex() had before the construction.
+ //! upgr.mutex() == 0. owns() == upgr.owns() before the construction.
+ //! upgr.owns() == false after the construction.
+ //!Notes: If upgr is locked, this constructor will lock this scoped_lock while
+ //! unlocking upgr. If upgr is unlocked, then this scoped_lock will be
+ //! unlocked as well. Only a moved upgradable_lock's will match this
+ //! signature. An non-moved upgradable_lock can be moved with
+ //! the expression: "move(lock);" This constructor may block if
+ //! other threads hold a sharable_lock on this mutex (sharable_lock's can
+ //! share ownership with an upgradable_lock).
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr)
: mp_mutex(0), m_locked(false)
@@ -172,21 +171,21 @@
}
#endif
- /*!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the
- referenced mutex:
- a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains
- the value from upgr.release() and owns() is set to true.
- b)if try_unlock_upgradable_and_lock() returns false then upgr is
- unaffected and this scoped_lock construction as the same effects as
- a default construction.
- c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
- and owns() is set to false
- Notes: This construction will not block. It will try to obtain mutex
- ownership from upgr immediately, while changing the lock type from a
- "read lock" to a "write lock". If the "read lock" isn't held in the
- first place, the mutex merely changes type to an unlocked "write lock".
- If the "read lock" is held, then mutex transfer occurs only if it can
- do so in a non-blocking manner.*/
+ //!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the
+ //!referenced mutex:
+ //! a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains
+ //! the value from upgr.release() and owns() is set to true.
+ //! b)if try_unlock_upgradable_and_lock() returns false then upgr is
+ //! unaffected and this scoped_lock construction as the same effects as
+ //! a default construction.
+ //! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
+ //! and owns() is set to false
+ //!Notes: This construction will not block. It will try to obtain mutex
+ //! ownership from upgr immediately, while changing the lock type from a
+ //! "read lock" to a "write lock". If the "read lock" isn't held in the
+ //! first place, the mutex merely changes type to an unlocked "write lock".
+ //! If the "read lock" is held, then mutex transfer occurs only if it can
+ //! do so in a non-blocking manner.*/
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
,detail::try_to_lock_type)
@@ -219,20 +218,20 @@
}
#endif
- /*!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)
- on the referenced mutex:
- a)if timed_unlock_upgradable_and_lock(abs_time) returns true then mutex()
- obtains the value from upgr.release() and owns() is set to true.
- b)if timed_unlock_upgradable_and_lock(abs_time) returns false then upgr
- is unaffected and this scoped_lock construction as the same effects
- as a default construction.
- c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
- and owns() is set to false
- Notes: This construction will not block. It will try to obtain mutex ownership
- from upgr immediately, while changing the lock type from a "read lock" to a
- "write lock". If the "read lock" isn't held in the first place, the mutex
- merely changes type to an unlocked "write lock". If the "read lock" is held,
- then mutex transfer occurs only if it can do so in a non-blocking manner.*/
+ //!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)
+ //! on the referenced mutex:
+ //! a)if timed_unlock_upgradable_and_lock(abs_time) returns true then mutex()
+ //! obtains the value from upgr.release() and owns() is set to true.
+ //! b)if timed_unlock_upgradable_and_lock(abs_time) returns false then upgr
+ //! is unaffected and this scoped_lock construction as the same effects
+ //! as a default construction.
+ //! c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()
+ //! and owns() is set to false
+ //!Notes: This construction will not block. It will try to obtain mutex ownership
+ //! from upgr immediately, while changing the lock type from a "read lock" to a
+ //! "write lock". If the "read lock" isn't held in the first place, the mutex
+ //! merely changes type to an unlocked "write lock". If the "read lock" is held,
+ //! then mutex transfer occurs only if it can do so in a non-blocking manner.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
,boost::posix_time::ptime &abs_time)
@@ -265,21 +264,21 @@
}
#endif
- /*!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the
- referenced mutex.
- a)if try_unlock_sharable_and_lock() returns true then mutex() obtains
- the value from shar.release() and owns() is set to true.
- b)if try_unlock_sharable_and_lock() returns false then shar is
- unaffected and this scoped_lock construction has the same
- effects as a default construction.
- c)Else shar.owns() is false. mutex() obtains the value from
- shar.release() and owns() is set to false
- Notes: This construction will not block. It will try to obtain mutex
- ownership from shar immediately, while changing the lock type from a
- "read lock" to a "write lock". If the "read lock" isn't held in the
- first place, the mutex merely changes type to an unlocked "write lock".
- If the "read lock" is held, then mutex transfer occurs only if it can
- do so in a non-blocking manner.*/
+ //!Effects: If shar.owns() then calls try_unlock_sharable_and_lock() on the
+ //!referenced mutex.
+ //! a)if try_unlock_sharable_and_lock() returns true then mutex() obtains
+ //! the value from shar.release() and owns() is set to true.
+ //! b)if try_unlock_sharable_and_lock() returns false then shar is
+ //! unaffected and this scoped_lock construction has the same
+ //! effects as a default construction.
+ //! c)Else shar.owns() is false. mutex() obtains the value from
+ //! shar.release() and owns() is set to false
+ //!Notes: This construction will not block. It will try to obtain mutex
+ //! ownership from shar immediately, while changing the lock type from a
+ //! "read lock" to a "write lock". If the "read lock" isn't held in the
+ //! first place, the mutex merely changes type to an unlocked "write lock".
+ //! If the "read lock" is held, then mutex transfer occurs only if it can
+ //! do so in a non-blocking manner.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
scoped_lock(detail::moved_object<sharable_lock<Mutex> > shar
,detail::try_to_lock_type)
@@ -312,20 +311,20 @@
}
#endif
- /*!Effects: if (owns()) mp_mutex->unlock().
- Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
+ //!Effects: if (owns()) mp_mutex->unlock().
+ //!Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
~scoped_lock()
{
try{ if(m_locked && mp_mutex) mp_mutex->unlock(); }
catch(...){}
}
- /*!Effects: If owns() before the call, then unlock() is called on mutex().
- *this gets the state of scop and scop gets set to a default constructed state.
- Notes: With a recursive mutex it is possible that both this and scop own
- the same mutex before the assignment. In this case, this will own the
- mutex after the assignment (and scop will not), but the mutex's lock
- count will be decremented by one.*/
+ //!Effects: If owns() before the call, then unlock() is called on mutex().
+ //! *this gets the state of scop and scop gets set to a default constructed state.
+ //!Notes: With a recursive mutex it is possible that both this and scop own
+ //! the same mutex before the assignment. In this case, this will own the
+ //! mutex after the assignment (and scop will not), but the mutex's lock
+ //! count will be decremented by one.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
scoped_lock &operator=(detail::moved_object<scoped_lock<Mutex> > scop)
{
@@ -346,11 +345,11 @@
}
#endif
- /*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- exception. Calls lock() on the referenced mutex.
- Postconditions: owns() == true.
- Notes: The scoped_lock changes from a state of not owning the mutex, to
- owning the mutex, blocking if necessary.*/
+ //!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
+ //! exception. Calls lock() on the referenced mutex.
+ //!Postconditions: owns() == true.
+ //!Notes: The scoped_lock changes from a state of not owning the mutex, to
+ //! owning the mutex, blocking if necessary.
void lock()
{
if(!mp_mutex || m_locked)
@@ -359,13 +358,13 @@
m_locked = true;
}
- /*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- exception. Calls try_lock() on the referenced mutex.
- Postconditions: owns() == the value returned from mutex()->try_lock().
- Notes: The scoped_lock changes from a state of not owning the mutex, to
- owning the mutex, but only if blocking was not required. If the
- mutex_type does not support try_lock(), this function will fail at
- compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
+ //! exception. Calls try_lock() on the referenced mutex.
+ //!Postconditions: owns() == the value returned from mutex()->try_lock().
+ //!Notes: The scoped_lock changes from a state of not owning the mutex, to
+ //! owning the mutex, but only if blocking was not required. If the
+ //! mutex_type does not support try_lock(), this function will fail at
+ //! compile time if instantiated, but otherwise have no effect.*/
bool try_lock()
{
if(!mp_mutex || m_locked)
@@ -374,13 +373,13 @@
return m_locked;
}
- /*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- exception. Calls timed_lock(abs_time) on the referenced mutex.
- Postconditions: owns() == the value returned from mutex()-> timed_lock(abs_time).
- Notes: The scoped_lock changes from a state of not owning the mutex, to
- owning the mutex, but only if it can obtain ownership by the specified
- time. If the mutex_type does not support timed_lock (), this function
- will fail at compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
+ //! exception. Calls timed_lock(abs_time) on the referenced mutex.
+ //!Postconditions: owns() == the value returned from mutex()-> timed_lock(abs_time).
+ //!Notes: The scoped_lock changes from a state of not owning the mutex, to
+ //! owning the mutex, but only if it can obtain ownership by the specified
+ //! time. If the mutex_type does not support timed_lock (), this function
+ //! will fail at compile time if instantiated, but otherwise have no effect.*/
bool timed_lock(const boost::posix_time::ptime& abs_time)
{
if(!mp_mutex || m_locked)
@@ -389,11 +388,11 @@
return m_locked;
}
- /*!Effects: If mutex() == 0 or if not locked, throws a lock_exception()
- exception. Calls unlock() on the referenced mutex.
- Postconditions: owns() == false.
- Notes: The scoped_lock changes from a state of owning the mutex, to not
- owning the mutex.*/
+ //!Effects: If mutex() == 0 or if not locked, throws a lock_exception()
+ //! exception. Calls unlock() on the referenced mutex.
+ //!Postconditions: owns() == false.
+ //!Notes: The scoped_lock changes from a state of owning the mutex, to not
+ //! owning the mutex.*/
void unlock()
{
if(!mp_mutex || !m_locked)
@@ -402,22 +401,24 @@
m_locked = false;
}
- /*!Effects: Returns true if this scoped_lock has acquired the referenced mutex.*/
+ //!Effects: Returns true if this scoped_lock has acquired
+ //!the referenced mutex.
bool owns() const
{ return m_locked && mp_mutex; }
- /*!Conversion to bool. Returns owns().*/
+ //!Conversion to bool.
+ //!Returns owns().
operator unspecified_bool_type() const
{ return m_locked? &this_type::m_locked : 0; }
- /*!Effects: Returns a pointer to the referenced mutex, or 0 if
- there is no mutex to reference.*/
+ //!Effects: Returns a pointer to the referenced mutex, or 0 if
+ //!there is no mutex to reference.
mutex_type* mutex() const
{ return mp_mutex; }
- /*!Effects: Returns a pointer to the referenced mutex, or 0 if there is no
- mutex to reference.
- Postconditions: mutex() == 0 and owns() == false.*/
+ //!Effects: Returns a pointer to the referenced mutex, or 0 if there is no
+ //! mutex to reference.
+ //!Postconditions: mutex() == 0 and owns() == false.
mutex_type* release()
{
mutex_type *mut = mp_mutex;
@@ -426,8 +427,8 @@
return mut;
}
- /*!Effects: Swaps state with moved lock.
- Throws: Nothing.*/
+ //!Effects: Swaps state with moved lock.
+ //!Throws: Nothing.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void swap(detail::moved_object<scoped_lock<mutex_type> > other)
{
@@ -450,7 +451,8 @@
};
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class M>
struct is_movable<scoped_lock<M> >
{
Modified: trunk/boost/interprocess/sync/sharable_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/sharable_lock.hpp (original)
+++ trunk/boost/interprocess/sync/sharable_lock.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -28,10 +28,9 @@
//Ig#include <boost/utility.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-/*!\file
- Describes the upgradable_lock class that serves to acquire the upgradable
- lock of a mutex.
-*/
+//!\file
+//!Describes the upgradable_lock class that serves to acquire the upgradable
+//!lock of a mutex.
namespace boost {
namespace interprocess {
@@ -42,14 +41,14 @@
template<class M>
class upgradable_lock;
-/*!sharable_lock is meant to carry out the tasks for sharable-locking
- (such as read-locking), unlocking, try-sharable-locking and timed-sharable-locking
- (recursive or not) for the Mutex. The Mutex need not supply all of this
- functionality. If the client of sharable_lock<Mutex> does not use functionality which
- the Mutex does not supply, no harm is done. Mutex ownership can be shared among
- sharable_locks, and a single upgradable_lock. sharable_lock does not support
- copy semantics. But sharable_lock supports ownership transfer from an sharable_lock,
- upgradable_lock and scoped_lock via trasfer_lock syntax.*/
+//!sharable_lock is meant to carry out the tasks for sharable-locking
+//!(such as read-locking), unlocking, try-sharable-locking and timed-sharable-locking
+//!(recursive or not) for the Mutex. The Mutex need not supply all of this
+//!functionality. If the client of sharable_lock<Mutex> does not use functionality which
+//!the Mutex does not supply, no harm is done. Mutex ownership can be shared among
+//!sharable_locks, and a single upgradable_lock. sharable_lock does not support
+//!copy semantics. But sharable_lock supports ownership transfer from an sharable_lock,
+//!upgradable_lock and scoped_lock via trasfer_lock syntax.*/
template <class SharableMutex>
class sharable_lock
{
@@ -66,70 +65,70 @@
/// @endcond
public:
- /*!Effects: Default constructs a sharable_lock.
- Postconditions: owns() == false and mutex() == 0.*/
+ //!Effects: Default constructs a sharable_lock.
+ //!Postconditions: owns() == false and mutex() == 0.
sharable_lock()
: mp_mutex(0), m_locked(false)
{}
- /*!Effects: m.lock_sharable().
- Postconditions: owns() == true and mutex() == &m.
- Notes: The constructor will take sharable-ownership of the mutex. If
- another thread already owns the mutex with exclusive ownership
- (scoped_lock), this thread will block until the mutex is released.
- If another thread owns the mutex with sharable or upgradable ownership,
- then no blocking will occur. Whether or not this constructor handles
- recursive locking depends upon the mutex.*/
+ //!Effects: m.lock_sharable().
+ //!Postconditions: owns() == true and mutex() == &m.
+ //!Notes: The constructor will take sharable-ownership of the mutex. If
+ //! another thread already owns the mutex with exclusive ownership
+ //! (scoped_lock), this thread will block until the mutex is released.
+ //! If another thread owns the mutex with sharable or upgradable ownership,
+ //! then no blocking will occur. Whether or not this constructor handles
+ //! recursive locking depends upon the mutex.
explicit sharable_lock(mutex_type& m)
: mp_mutex(&m), m_locked(false)
{ mp_mutex->lock_sharable(); m_locked = true; }
- /*!Postconditions: owns() == false, and mutex() == &m.
- Notes: The constructor will not take ownership of the mutex. There is no effect
- required on the referenced mutex.*/
+ //!Postconditions: owns() == false, and mutex() == &m.
+ //!Notes: The constructor will not take ownership of the mutex. There is no effect
+ //! required on the referenced mutex.
sharable_lock(mutex_type& m, detail::defer_lock_type)
: mp_mutex(&m), m_locked(false)
{}
- /*!Postconditions: owns() == true, and mutex() == &m.
- Notes: The constructor will suppose that the mutex is already sharable
- locked. There is no effect required on the referenced mutex.*/
+ //!Postconditions: owns() == true, and mutex() == &m.
+ //!Notes: The constructor will suppose that the mutex is already sharable
+ //! locked. There is no effect required on the referenced mutex.
sharable_lock(mutex_type& m, detail::accept_ownership_type)
: mp_mutex(&m), m_locked(true)
{}
- /*!Effects: m.try_lock_sharable()
- Postconditions: mutex() == &m. owns() == the return value of the
- m.try_lock_sharable() executed within the constructor.
- Notes: The constructor will take sharable-ownership of the mutex if it
- can do so without waiting. Whether or not this constructor handles
- recursive locking depends upon the mutex. If the mutex_type does not
- support try_lock_sharable, this constructor will fail at compile
- time if instantiated, but otherwise have no effect.*/
+ //!Effects: m.try_lock_sharable()
+ //!Postconditions: mutex() == &m. owns() == the return value of the
+ //! m.try_lock_sharable() executed within the constructor.
+ //!Notes: The constructor will take sharable-ownership of the mutex if it
+ //! can do so without waiting. Whether or not this constructor handles
+ //! recursive locking depends upon the mutex. If the mutex_type does not
+ //! support try_lock_sharable, this constructor will fail at compile
+ //! time if instantiated, but otherwise have no effect.
sharable_lock(mutex_type& m, detail::try_to_lock_type)
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->try_lock_sharable(); }
- /*!Effects: m.timed_lock_sharable(abs_time)
- Postconditions: mutex() == &m. owns() == the return value of the
- m.timed_lock_sharable() executed within the constructor.
- Notes: The constructor will take sharable-ownership of the mutex if it
- can do so within the time specified. Whether or not this constructor
- handles recursive locking depends upon the mutex. If the mutex_type
- does not support timed_lock_sharable, this constructor will fail at
- compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: m.timed_lock_sharable(abs_time)
+ //!Postconditions: mutex() == &m. owns() == the return value of the
+ //! m.timed_lock_sharable() executed within the constructor.
+ //!Notes: The constructor will take sharable-ownership of the mutex if it
+ //! can do so within the time specified. Whether or not this constructor
+ //! handles recursive locking depends upon the mutex. If the mutex_type
+ //! does not support timed_lock_sharable, this constructor will fail at
+ //! compile time if instantiated, but otherwise have no effect.
sharable_lock(mutex_type& m, const boost::posix_time::ptime& abs_time)
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->timed_lock_sharable(abs_time); }
- /*!Postconditions: mutex() == upgr.mutex(). owns() == the value of upgr.owns()
- before the construction. upgr.owns() == false after the construction.
- Notes: If the upgr sharable_lock owns the mutex, ownership is moved to this
- sharable_lock with no blocking. If the upgr sharable_lock does not own the mutex, then
- neither will this sharable_lock. Only a moved sharable_lock's will match this
- signature. An non-moved sharable_lock can be moved with the expression:
- "move(lock);". This constructor does not alter the state of the mutex,
- only potentially who owns it.*/
+ //!Postconditions: mutex() == upgr.mutex(). owns() == the value of upgr.owns()
+ //! before the construction. upgr.owns() == false after the construction.
+ //!Notes: If the upgr sharable_lock owns the mutex, ownership is moved to this
+ //! sharable_lock with no blocking. If the upgr sharable_lock does not own the mutex, then
+ //! neither will this sharable_lock. Only a moved sharable_lock's will match this
+ //! signature. An non-moved sharable_lock can be moved with the expression:
+ //! "move(lock);". This constructor does not alter the state of the mutex,
+ //! only potentially who owns it.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit sharable_lock(detail::moved_object<sharable_lock<mutex_type> > upgr)
: mp_mutex(0), m_locked(upgr.get().owns())
@@ -140,15 +139,15 @@
{ mp_mutex = upgr.release(); }
#endif
- /*!Effects: If upgr.owns() then calls unlock_upgradable_and_lock_sharable() on the
- referenced mutex.
- Postconditions: mutex() == the value upgr.mutex() had before the construction.
- upgr.mutex() == 0 owns() == the value of upgr.owns() before construction.
- upgr.owns() == false after the construction.
- Notes: If upgr is locked, this constructor will lock this sharable_lock while
- unlocking upgr. Only a moved sharable_lock's will match this
- signature. An non-moved upgradable_lock can be moved with the expression:
- "move(lock);".*/
+ //!Effects: If upgr.owns() then calls unlock_upgradable_and_lock_sharable() on the
+ //! referenced mutex.
+ //!Postconditions: mutex() == the value upgr.mutex() had before the construction.
+ //! upgr.mutex() == 0 owns() == the value of upgr.owns() before construction.
+ //! upgr.owns() == false after the construction.
+ //!Notes: If upgr is locked, this constructor will lock this sharable_lock while
+ //! unlocking upgr. Only a moved sharable_lock's will match this
+ //! signature. An non-moved upgradable_lock can be moved with the expression:
+ //! "move(lock);".*/
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit sharable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
: mp_mutex(0), m_locked(false)
@@ -173,16 +172,16 @@
}
#endif
- /*!Effects: If scop.owns() then calls unlock_and_lock_sharable() on the
- referenced mutex.
- Postconditions: mutex() == the value scop.mutex() had before the construction.
- scop.mutex() == 0 owns() == scop.owns() before the constructor. After the
- construction, scop.owns() == false.
- Notes: If scop is locked, this constructor will transfer the exclusive ownership
- to a sharable-ownership of this sharable_lock.
- Only a moved scoped_lock's will match this
- signature. An non-moved scoped_lock can be moved with the expression:
- "move(lock);".*/
+ //!Effects: If scop.owns() then calls unlock_and_lock_sharable() on the
+ //! referenced mutex.
+ //!Postconditions: mutex() == the value scop.mutex() had before the construction.
+ //! scop.mutex() == 0 owns() == scop.owns() before the constructor. After the
+ //! construction, scop.owns() == false.
+ //!Notes: If scop is locked, this constructor will transfer the exclusive ownership
+ //! to a sharable-ownership of this sharable_lock.
+ //! Only a moved scoped_lock's will match this
+ //! signature. An non-moved scoped_lock can be moved with the expression:
+ //! "move(lock);".*/
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit sharable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
: mp_mutex(0), m_locked(false)
@@ -207,8 +206,8 @@
}
#endif
- /*!Effects: if (owns()) mp_mutex->unlock_sharable().
- Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
+ //!Effects: if (owns()) mp_mutex->unlock_sharable().
+ //!Notes: The destructor behavior ensures that the mutex lock is not leaked.
~sharable_lock()
{
try{
@@ -217,11 +216,11 @@
catch(...){}
}
- /*!Effects: If owns() before the call, then unlock_sharable() is called on mutex().
- *this gets the state of upgr and upgr gets set to a default constructed state.
- Notes: With a recursive mutex it is possible that both this and upgr own the mutex
- before the assignment. In this case, this will own the mutex after the assignment
- (and upgr will not), but the mutex's lock count will be decremented by one.*/
+ //!Effects: If owns() before the call, then unlock_sharable() is called on mutex().
+ //! *this gets the state of upgr and upgr gets set to a default constructed state.
+ //!Notes: With a recursive mutex it is possible that both this and upgr own the mutex
+ //! before the assignment. In this case, this will own the mutex after the assignment
+ //! (and upgr will not), but the mutex's lock count will be decremented by one.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
sharable_lock &operator=(detail::moved_object<sharable_lock<mutex_type> > upgr)
{
@@ -242,11 +241,11 @@
}
#endif
- /*!Effects: If mutex() == 0 or already locked, throws a lock_exception()
- exception. Calls lock_sharable() on the referenced mutex.
- Postconditions: owns() == true.
- Notes: The sharable_lock changes from a state of not owning the
- mutex, to owning the mutex, blocking if necessary.*/
+ //!Effects: If mutex() == 0 or already locked, throws a lock_exception()
+ //! exception. Calls lock_sharable() on the referenced mutex.
+ //!Postconditions: owns() == true.
+ //!Notes: The sharable_lock changes from a state of not owning the
+ //! mutex, to owning the mutex, blocking if necessary.
void lock()
{
if(!mp_mutex || m_locked)
@@ -255,14 +254,14 @@
m_locked = true;
}
- /*!Effects: If mutex() == 0 or already locked, throws a lock_exception()
- exception. Calls try_lock_sharable() on the referenced mutex.
- Postconditions: owns() == the value returned from
- mutex()->try_lock_sharable().
- Notes: The sharable_lock changes from a state of not owning the mutex,
- to owning the mutex, but only if blocking was not required. If the
- mutex_type does not support try_lock_sharable(), this function will
- fail at compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: If mutex() == 0 or already locked, throws a lock_exception()
+ //! exception. Calls try_lock_sharable() on the referenced mutex.
+ //!Postconditions: owns() == the value returned from
+ //! mutex()->try_lock_sharable().
+ //!Notes: The sharable_lock changes from a state of not owning the mutex,
+ //! to owning the mutex, but only if blocking was not required. If the
+ //! mutex_type does not support try_lock_sharable(), this function will
+ //! fail at compile time if instantiated, but otherwise have no effect.
bool try_lock()
{
if(!mp_mutex || m_locked)
@@ -271,15 +270,15 @@
return m_locked;
}
- /*!Effects: If mutex() == 0 or already locked, throws a lock_exception()
- exception. Calls timed_lock_sharable(abs_time) on the referenced mutex.
- Postconditions: owns() == the value returned from
- mutex()->timed_lock_sharable(elps_time).
- Notes: The sharable_lock changes from a state of not owning the mutex,
- to owning the mutex, but only if it can obtain ownership within the
- specified time interval. If the mutex_type does not support
- timed_lock_sharable(), this function will fail at compile time if
- instantiated, but otherwise have no effect.*/
+ //!Effects: If mutex() == 0 or already locked, throws a lock_exception()
+ //! exception. Calls timed_lock_sharable(abs_time) on the referenced mutex.
+ //!Postconditions: owns() == the value returned from
+ //! mutex()->timed_lock_sharable(elps_time).
+ //!Notes: The sharable_lock changes from a state of not owning the mutex,
+ //! to owning the mutex, but only if it can obtain ownership within the
+ //! specified time interval. If the mutex_type does not support
+ //! timed_lock_sharable(), this function will fail at compile time if
+ //! instantiated, but otherwise have no effect.
bool timed_lock(const boost::posix_time::ptime& abs_time)
{
if(!mp_mutex || m_locked)
@@ -288,11 +287,11 @@
return m_locked;
}
- /*!Effects: If mutex() == 0 or not locked, throws a lock_exception() exception.
- Calls unlock_sharable() on the referenced mutex.
- Postconditions: owns() == false.
- Notes: The sharable_lock changes from a state of owning the mutex, to
- not owning the mutex.*/
+ //!Effects: If mutex() == 0 or not locked, throws a lock_exception() exception.
+ //! Calls unlock_sharable() on the referenced mutex.
+ //!Postconditions: owns() == false.
+ //!Notes: The sharable_lock changes from a state of owning the mutex, to
+ //! not owning the mutex.
void unlock()
{
if(!mp_mutex || !m_locked)
@@ -301,22 +300,24 @@
m_locked = false;
}
- /*!Effects: Returns true if this scoped_lock has acquired the referenced mutex.*/
+ //!Effects: Returns true if this scoped_lock has
+ //!acquired the referenced mutex.
bool owns() const
{ return m_locked && mp_mutex; }
- /*!Conversion to bool. Returns owns().*/
+ //!Conversion to bool.
+ //!Returns owns().
operator unspecified_bool_type() const
{ return m_locked? &this_type::m_locked : 0; }
- /*!Effects: Returns a pointer to the referenced mutex, or 0 if
- there is no mutex to reference.*/
+ //!Effects: Returns a pointer to the referenced mutex, or 0 if
+ //!there is no mutex to reference.
mutex_type* mutex() const
{ return mp_mutex; }
- /*!Effects: Returns a pointer to the referenced mutex, or 0 if there is no
- mutex to reference.
- Postconditions: mutex() == 0 and owns() == false.*/
+ //!Effects: Returns a pointer to the referenced mutex, or 0 if there is no
+ //! mutex to reference.
+ //!Postconditions: mutex() == 0 and owns() == false.
mutex_type* release()
{
mutex_type *mut = mp_mutex;
@@ -325,8 +326,8 @@
return mut;
}
- /*!Effects: Swaps state with moved lock.
- Throws: Nothing.*/
+ //!Effects: Swaps state with moved lock.
+ //!Throws: Nothing.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void swap(detail::moved_object<sharable_lock<mutex_type> > other)
{
@@ -349,7 +350,8 @@
};
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class M>
struct is_movable<sharable_lock<M> >
{
Modified: trunk/boost/interprocess/sync/upgradable_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/upgradable_lock.hpp (original)
+++ trunk/boost/interprocess/sync/upgradable_lock.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -27,10 +27,9 @@
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-/*!\file
- Describes the upgradable_lock class that serves to acquire the upgradable
- lock of a mutex.
-*/
+//!\file
+//!Describes the upgradable_lock class that serves to acquire the upgradable
+//!lock of a mutex.
namespace boost {
namespace interprocess {
@@ -41,15 +40,15 @@
template<class M>
class sharable_lock;
-/*!upgradable_lock is meant to carry out the tasks for read-locking, unlocking,
- try-read-locking and timed-read-locking (recursive or not) for the Mutex.
- Additionally the upgradable_lock can transfer ownership to a scoped_lock
- using trasfer_lock syntax. The Mutex need not supply all of the functionality.
- If the client of upgradable_lock<Mutex> does not use functionality which the
- Mutex does not supply, no harm is done. Mutex ownership can be shared among
- read_locks, and a single upgradable_lock. upgradable_lock does not support
- copy semantics. However upgradable_lock supports ownership transfer from
- a upgradable_locks or scoped_locks via trasfer_lock syntax.*/
+//!upgradable_lock is meant to carry out the tasks for read-locking, unlocking,
+//!try-read-locking and timed-read-locking (recursive or not) for the Mutex.
+//!Additionally the upgradable_lock can transfer ownership to a scoped_lock
+//!using trasfer_lock syntax. The Mutex need not supply all of the functionality.
+//!If the client of upgradable_lock<Mutex> does not use functionality which the
+//!Mutex does not supply, no harm is done. Mutex ownership can be shared among
+//!read_locks, and a single upgradable_lock. upgradable_lock does not support
+//!copy semantics. However upgradable_lock supports ownership transfer from
+//!a upgradable_locks or scoped_locks via trasfer_lock syntax.
template <class UpgradableMutex>
class upgradable_lock
{
@@ -66,8 +65,8 @@
/// @endcond
public:
- /*!Effects: Default constructs a upgradable_lock.
- Postconditions: owns() == false and mutex() == 0.*/
+ //!Effects: Default constructs a upgradable_lock.
+ //!Postconditions: owns() == false and mutex() == 0.
upgradable_lock()
: mp_mutex(0), m_locked(false)
{}
@@ -76,54 +75,54 @@
: mp_mutex(&m), m_locked(false)
{ mp_mutex->lock_upgradable(); m_locked = true; }
- /*!Postconditions: owns() == false, and mutex() == &m.
- Notes: The constructor will not take ownership of the mutex. There is no effect
- required on the referenced mutex.*/
+ //!Postconditions: owns() == false, and mutex() == &m.
+ //!Notes: The constructor will not take ownership of the mutex. There is no effect
+ //! required on the referenced mutex.
upgradable_lock(mutex_type& m, detail::defer_lock_type)
: mp_mutex(&m), m_locked(false)
{}
- /*!Postconditions: owns() == true, and mutex() == &m.
- Notes: The constructor will suppose that the mutex is already upgradable
- locked. There is no effect required on the referenced mutex.*/
+ //!Postconditions: owns() == true, and mutex() == &m.
+ //!Notes: The constructor will suppose that the mutex is already upgradable
+ //! locked. There is no effect required on the referenced mutex.
upgradable_lock(mutex_type& m, detail::accept_ownership_type)
: mp_mutex(&m), m_locked(true)
{}
- /*!Effects: m.try_lock_upgradable().
- Postconditions: mutex() == &m. owns() == the return value of the
- m.try_lock_upgradable() executed within the constructor.
- Notes: The constructor will take upgradable-ownership of the mutex
- if it can do so without waiting. Whether or not this constructor
- handles recursive locking depends upon the mutex. If the mutex_type
- does not support try_lock_upgradable, this constructor will fail at
- compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: m.try_lock_upgradable().
+ //!Postconditions: mutex() == &m. owns() == the return value of the
+ //! m.try_lock_upgradable() executed within the constructor.
+ //!Notes: The constructor will take upgradable-ownership of the mutex
+ //! if it can do so without waiting. Whether or not this constructor
+ //! handles recursive locking depends upon the mutex. If the mutex_type
+ //! does not support try_lock_upgradable, this constructor will fail at
+ //! compile time if instantiated, but otherwise have no effect.
upgradable_lock(mutex_type& m, detail::try_to_lock_type)
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->try_lock_upgradable(); }
- /*!Effects: m.timed_lock_upgradable(abs_time)
- Postconditions: mutex() == &m. owns() == the return value of the
- m.timed_lock_upgradable() executed within the constructor.
- Notes: The constructor will take upgradable-ownership of the mutex if it
- can do so within the time specified. Whether or not this constructor
- handles recursive locking depends upon the mutex. If the mutex_type
- does not support timed_lock_upgradable, this constructor will fail
- at compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: m.timed_lock_upgradable(abs_time)
+ //!Postconditions: mutex() == &m. owns() == the return value of the
+ //! m.timed_lock_upgradable() executed within the constructor.
+ //!Notes: The constructor will take upgradable-ownership of the mutex if it
+ //! can do so within the time specified. Whether or not this constructor
+ //! handles recursive locking depends upon the mutex. If the mutex_type
+ //! does not support timed_lock_upgradable, this constructor will fail
+ //! at compile time if instantiated, but otherwise have no effect.
upgradable_lock(mutex_type& m, const boost::posix_time::ptime& abs_time)
: mp_mutex(&m), m_locked(false)
{ m_locked = mp_mutex->timed_lock_upgradable(abs_time); }
- /*!Effects: No effects on the underlying mutex.
- Postconditions: mutex() == the value upgr.mutex() had before the
- construction. upgr.mutex() == 0. owns() == upgr.owns() before the
- construction. upgr.owns() == false.
- Notes: If upgr is locked, this constructor will lock this upgradable_lock
- while unlocking upgr. If upgr is unlocked, then this upgradable_lock will
- be unlocked as well. Only a moved upgradable_lock's will match this
- signature. An non-moved upgradable_lock can be moved with the
- expression: "move(lock);". This constructor does not alter the
- state of the mutex, only potentially who owns it.*/
+ //!Effects: No effects on the underlying mutex.
+ //!Postconditions: mutex() == the value upgr.mutex() had before the
+ //! construction. upgr.mutex() == 0. owns() == upgr.owns() before the
+ //! construction. upgr.owns() == false.
+ //!Notes: If upgr is locked, this constructor will lock this upgradable_lock
+ //! while unlocking upgr. If upgr is unlocked, then this upgradable_lock will
+ //! be unlocked as well. Only a moved upgradable_lock's will match this
+ //! signature. An non-moved upgradable_lock can be moved with the
+ //! expression: "move(lock);". This constructor does not alter the
+ //! state of the mutex, only potentially who owns it.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit upgradable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
: mp_mutex(0), m_locked(upgr.get().owns())
@@ -134,15 +133,15 @@
{ mp_mutex = upgr.release(); }
#endif
- /*!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
- Postconditions: mutex() == the value scop.mutex() had before the construction.
- scop.mutex() == 0. owns() == scop.owns() before the constructor. After the
- construction, scop.owns() == false.
- Notes: If scop is locked, this constructor will transfer the exclusive-ownership
- to an upgradable-ownership of this upgradable_lock.
- Only a moved sharable_lock's will match this
- signature. An non-moved sharable_lock can be moved with the
- expression: "move(lock);".*/
+ //!Effects: If scop.owns(), m_.unlock_and_lock_upgradable().
+ //!Postconditions: mutex() == the value scop.mutex() had before the construction.
+ //! scop.mutex() == 0. owns() == scop.owns() before the constructor. After the
+ //! construction, scop.owns() == false.
+ //!Notes: If scop is locked, this constructor will transfer the exclusive-ownership
+ //! to an upgradable-ownership of this upgradable_lock.
+ //! Only a moved sharable_lock's will match this
+ //! signature. An non-moved sharable_lock can be moved with the
+ //! expression: "move(lock);".
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
explicit upgradable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
: mp_mutex(0), m_locked(false)
@@ -167,21 +166,21 @@
}
#endif
- /*!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable()
- on the referenced mutex.
- a)if try_unlock_sharable_and_lock_upgradable() returns true then mutex()
- obtains the value from shar.release() and owns() is set to true.
- b)if try_unlock_sharable_and_lock_upgradable() returns false then shar is
- unaffected and this upgradable_lock construction has the same
- effects as a default construction.
- c)Else shar.owns() is false. mutex() obtains the value from shar.release()
- and owns() is set to false.
- Notes: This construction will not block. It will try to obtain mutex
- ownership from shar immediately, while changing the lock type from a
- "read lock" to an "upgradable lock". If the "read lock" isn't held
- in the first place, the mutex merely changes type to an unlocked
- "upgradable lock". If the "read lock" is held, then mutex transfer
- occurs only if it can do so in a non-blocking manner.*/
+ //!Effects: If shar.owns() then calls try_unlock_sharable_and_lock_upgradable()
+ //! on the referenced mutex.
+ //! a)if try_unlock_sharable_and_lock_upgradable() returns true then mutex()
+ //! obtains the value from shar.release() and owns() is set to true.
+ //! b)if try_unlock_sharable_and_lock_upgradable() returns false then shar is
+ //! unaffected and this upgradable_lock construction has the same
+ //! effects as a default construction.
+ //! c)Else shar.owns() is false. mutex() obtains the value from shar.release()
+ //! and owns() is set to false.
+ //!Notes: This construction will not block. It will try to obtain mutex
+ //! ownership from shar immediately, while changing the lock type from a
+ //! "read lock" to an "upgradable lock". If the "read lock" isn't held
+ //! in the first place, the mutex merely changes type to an unlocked
+ //! "upgradable lock". If the "read lock" is held, then mutex transfer
+ //! occurs only if it can do so in a non-blocking manner.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
upgradable_lock( detail::moved_object<sharable_lock<mutex_type> > shar
, detail::try_to_lock_type)
@@ -214,8 +213,8 @@
}
#endif
- /*!Effects: if (owns()) m_->unlock_upgradable().
- Notes: The destructor behavior ensures that the mutex lock is not leaked.*/
+ //!Effects: if (owns()) m_->unlock_upgradable().
+ //!Notes: The destructor behavior ensures that the mutex lock is not leaked.
~upgradable_lock()
{
try{
@@ -224,12 +223,12 @@
catch(...){}
}
- /*!Effects: If owns(), then unlock_upgradable() is called on mutex().
- *this gets the state of upgr and upgr gets set to a default constructed state.
- Notes: With a recursive mutex it is possible that both this and upgr own the
- mutex before the assignment. In this case, this will own the mutex
- after the assignment (and upgr will not), but the mutex's upgradable lock
- count will be decremented by one.*/
+ //!Effects: If owns(), then unlock_upgradable() is called on mutex().
+ //! *this gets the state of upgr and upgr gets set to a default constructed state.
+ //!Notes: With a recursive mutex it is possible that both this and upgr own the
+ //! mutex before the assignment. In this case, this will own the mutex
+ //! after the assignment (and upgr will not), but the mutex's upgradable lock
+ //! count will be decremented by one.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
upgradable_lock &operator=(detail::moved_object<upgradable_lock<mutex_type> > upgr)
{
@@ -250,11 +249,11 @@
}
#endif
- /*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- exception. Calls lock_upgradable() on the referenced mutex.
- Postconditions: owns() == true.
- Notes: The sharable_lock changes from a state of not owning the mutex,
- to owning the mutex, blocking if necessary.*/
+ //!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
+ //! exception. Calls lock_upgradable() on the referenced mutex.
+ //!Postconditions: owns() == true.
+ //!Notes: The sharable_lock changes from a state of not owning the mutex,
+ //! to owning the mutex, blocking if necessary.
void lock()
{
if(!mp_mutex || m_locked)
@@ -263,14 +262,14 @@
m_locked = true;
}
- /*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- exception. Calls try_lock_upgradable() on the referenced mutex.
- Postconditions: owns() == the value returned from
- mutex()->try_lock_upgradable().
- Notes: The upgradable_lock changes from a state of not owning the mutex,
- to owning the mutex, but only if blocking was not required. If the
- mutex_type does not support try_lock_upgradable(), this function will
- fail at compile time if instantiated, but otherwise have no effect.*/
+ //!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
+ //! exception. Calls try_lock_upgradable() on the referenced mutex.
+ //!Postconditions: owns() == the value returned from
+ //! mutex()->try_lock_upgradable().
+ //!Notes: The upgradable_lock changes from a state of not owning the mutex,
+ //! to owning the mutex, but only if blocking was not required. If the
+ //! mutex_type does not support try_lock_upgradable(), this function will
+ //! fail at compile time if instantiated, but otherwise have no effect.
bool try_lock()
{
if(!mp_mutex || m_locked)
@@ -279,15 +278,15 @@
return m_locked;
}
- /*!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
- exception. Calls timed_lock_upgradable(abs_time) on the referenced mutex.
- Postconditions: owns() == the value returned from
- mutex()->timed_lock_upgradable(abs_time).
- Notes: The upgradable_lock changes from a state of not owning the mutex,
- to owning the mutex, but only if it can obtain ownership within the
- specified time. If the mutex_type does not support
- timed_lock_upgradable(abs_time), this function will fail at compile
- time if instantiated, but otherwise have no effect.*/
+ //!Effects: If mutex() == 0 or if already locked, throws a lock_exception()
+ //! exception. Calls timed_lock_upgradable(abs_time) on the referenced mutex.
+ //!Postconditions: owns() == the value returned from
+ //! mutex()->timed_lock_upgradable(abs_time).
+ //!Notes: The upgradable_lock changes from a state of not owning the mutex,
+ //! to owning the mutex, but only if it can obtain ownership within the
+ //! specified time. If the mutex_type does not support
+ //! timed_lock_upgradable(abs_time), this function will fail at compile
+ //! time if instantiated, but otherwise have no effect.
bool timed_lock(const boost::posix_time::ptime& abs_time)
{
if(!mp_mutex || m_locked)
@@ -296,11 +295,11 @@
return m_locked;
}
- /*!Effects: If mutex() == 0 or if not locked, throws a lock_exception()
- exception. Calls unlock_upgradable() on the referenced mutex.
- Postconditions: owns() == false.
- Notes: The upgradable_lock changes from a state of owning the mutex,
- to not owning the mutex.*/
+ //!Effects: If mutex() == 0 or if not locked, throws a lock_exception()
+ //! exception. Calls unlock_upgradable() on the referenced mutex.
+ //!Postconditions: owns() == false.
+ //!Notes: The upgradable_lock changes from a state of owning the mutex,
+ //! to not owning the mutex.
void unlock()
{
if(!mp_mutex || !m_locked)
@@ -309,22 +308,24 @@
m_locked = false;
}
- /*!Effects: Returns true if this scoped_lock has acquired the referenced mutex.*/
+ //!Effects: Returns true if this scoped_lock has acquired the
+ //!referenced mutex.
bool owns() const
{ return m_locked && mp_mutex; }
- /*!Conversion to bool. Returns owns().*/
+ //!Conversion to bool.
+ //!Returns owns().
operator unspecified_bool_type() const
{ return m_locked? &this_type::m_locked : 0; }
- /*!Effects: Returns a pointer to the referenced mutex, or 0 if
- there is no mutex to reference.*/
+ //!Effects: Returns a pointer to the referenced mutex, or 0 if
+ //!there is no mutex to reference.
mutex_type* mutex() const
{ return mp_mutex; }
- /*!Effects: Returns a pointer to the referenced mutex, or 0 if there is no
- mutex to reference.
- Postconditions: mutex() == 0 and owns() == false.*/
+ //!Effects: Returns a pointer to the referenced mutex, or 0 if there is no
+ //! mutex to reference.
+ //!Postconditions: mutex() == 0 and owns() == false.
mutex_type* release()
{
mutex_type *mut = mp_mutex;
@@ -333,8 +334,8 @@
return mut;
}
- /*!Effects: Swaps state with moved lock.
- Throws: Nothing.*/
+ //!Effects: Swaps state with moved lock.
+ //!Throws: Nothing.
#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
void swap(detail::moved_object<upgradable_lock<mutex_type> > other)
{
@@ -357,7 +358,8 @@
};
/// @cond
-/*!This class is movable*/
+
+//!This class is movable
template <class M>
struct is_movable<upgradable_lock<M> >
{
Modified: trunk/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/windows_shared_memory.hpp 2007-09-26 11:11:38 EDT (Wed, 26 Sep 2007)
@@ -56,7 +56,9 @@
/// @endcond
public:
- //!Default constructor. Represents an empty windows_shared_memory.
+
+ //!Default constructor.
+ //!Represents an empty windows_shared_memory.
windows_shared_memory();
//!Creates a new native shared memory with name "name" and mode "mode",
@@ -69,7 +71,7 @@
//!access mode "mode". If the file previously exists, it tries to open it with mode "mode".
//!Otherwise throws an error.
windows_shared_memory(open_or_create_t, const char *name, mode_t mode, std::size_t size)
- { this->priv_open_or_create(detail::DoCreateOrOpen, name, mode, size); }
+ { this->priv_open_or_create(detail::DoOpenOrCreate, name, mode, size); }
//!Tries to open a shared memory object with name "name", with the access mode "mode".
//!If the file does not previously exist, it throws an error.
@@ -200,7 +202,7 @@
(map_access, filename);
break;
case detail::DoCreate:
- case detail::DoCreateOrOpen:
+ case detail::DoOpenOrCreate:
{
__int64 s = size;
unsigned long high_size(s >> 32), low_size((boost::uint32_t)s);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk