Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56817 - in trunk/boost: interprocess interprocess/allocators interprocess/allocators/detail interprocess/containers interprocess/containers/container interprocess/containers/container/detail interprocess/detail interprocess/indexes interprocess/ipc interprocess/mem_algo interprocess/mem_algo/detail interprocess/smart_ptr interprocess/smart_ptr/detail interprocess/streams interprocess/sync interprocess/sync/emulation interprocess/sync/posix interprocess/sync/xsi intrusive intrusive/detail
From: igaztanaga_at_[hidden]
Date: 2009-10-14 07:59:52


Author: igaztanaga
Date: 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
New Revision: 56817
URL: http://svn.boost.org/trac/boost/changeset/56817

Log:
Fixes for 1.41
Added:
   trunk/boost/interprocess/containers/container/container_fwd.hpp (contents, props changed)
   trunk/boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp (contents, props changed)
   trunk/boost/interprocess/containers/container/detail/math_functions.hpp (contents, props changed)
   trunk/boost/interprocess/containers/container/detail/node_pool_impl.hpp (contents, props changed)
   trunk/boost/interprocess/containers/container/detail/pool_common.hpp (contents, props changed)
   trunk/boost/interprocess/containers/containers_fwd.hpp (contents, props changed)
   trunk/boost/interprocess/detail/intermodule_singleton.hpp (contents, props changed)
   trunk/boost/interprocess/detail/xsi_shared_memory.hpp (contents, props changed)
   trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp (contents, props changed)
   trunk/boost/interprocess/sync/xsi/
   trunk/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp (contents, props changed)
   trunk/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp (contents, props changed)
   trunk/boost/interprocess/sync/xsi/xsi_named_mutex.hpp (contents, props changed)
   trunk/boost/intrusive/detail/function_detector.hpp (contents, props changed)
   trunk/boost/intrusive/detail/is_stateful_value_traits.hpp (contents, props changed)
Text files modified:
   trunk/boost/interprocess/allocators/adaptive_pool.hpp | 5
   trunk/boost/interprocess/allocators/allocator.hpp | 5
   trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp | 2
   trunk/boost/interprocess/allocators/cached_node_allocator.hpp | 2
   trunk/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 539 ---------------------------------------
   trunk/boost/interprocess/allocators/detail/allocator_common.hpp | 22 +
   trunk/boost/interprocess/allocators/detail/node_pool.hpp | 314 ----------------------
   trunk/boost/interprocess/allocators/detail/node_tools.hpp | 2
   trunk/boost/interprocess/allocators/node_allocator.hpp | 5
   trunk/boost/interprocess/allocators/private_adaptive_pool.hpp | 5
   trunk/boost/interprocess/allocators/private_node_allocator.hpp | 5
   trunk/boost/interprocess/anonymous_shared_memory.hpp | 2
   trunk/boost/interprocess/containers/allocation_type.hpp | 14
   trunk/boost/interprocess/containers/container/deque.hpp | 148 ++++++----
   trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp | 20
   trunk/boost/interprocess/containers/container/detail/algorithms.hpp | 6
   trunk/boost/interprocess/containers/container/detail/allocation_type.hpp | 6
   trunk/boost/interprocess/containers/container/detail/config_begin.hpp | 2
   trunk/boost/interprocess/containers/container/detail/config_end.hpp | 2
   trunk/boost/interprocess/containers/container/detail/destroyers.hpp | 6
   trunk/boost/interprocess/containers/container/detail/flat_tree.hpp | 54 ++-
   trunk/boost/interprocess/containers/container/detail/iterators.hpp | 6
   trunk/boost/interprocess/containers/container/detail/mpl.hpp | 6
   trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp | 471 ++++++----------------------------
   trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp | 48 +-
   trunk/boost/interprocess/containers/container/detail/pair.hpp | 18 +
   trunk/boost/interprocess/containers/container/detail/preprocessor.hpp | 2
   trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp | 6
   trunk/boost/interprocess/containers/container/detail/tree.hpp | 86 ++++-
   trunk/boost/interprocess/containers/container/detail/type_traits.hpp | 6
   trunk/boost/interprocess/containers/container/detail/utilities.hpp | 25 +
   trunk/boost/interprocess/containers/container/detail/value_init.hpp | 4
   trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp | 6
   trunk/boost/interprocess/containers/container/detail/version_type.hpp | 6
   trunk/boost/interprocess/containers/container/detail/workaround.hpp | 2
   trunk/boost/interprocess/containers/container/flat_map.hpp | 75 +++--
   trunk/boost/interprocess/containers/container/flat_set.hpp | 149 ++++++++--
   trunk/boost/interprocess/containers/container/list.hpp | 106 ++++--
   trunk/boost/interprocess/containers/container/map.hpp | 78 +++--
   trunk/boost/interprocess/containers/container/set.hpp | 149 ++++++++--
   trunk/boost/interprocess/containers/container/slist.hpp | 112 +++++--
   trunk/boost/interprocess/containers/container/stable_vector.hpp | 513 ++++++++++++++++++--------------------
   trunk/boost/interprocess/containers/container/string.hpp | 48 ++-
   trunk/boost/interprocess/containers/container/vector.hpp | 158 ++++++-----
   trunk/boost/interprocess/containers/deque.hpp | 3
   trunk/boost/interprocess/containers/flat_map.hpp | 5
   trunk/boost/interprocess/containers/flat_set.hpp | 5
   trunk/boost/interprocess/containers/list.hpp | 3
   trunk/boost/interprocess/containers/map.hpp | 5
   trunk/boost/interprocess/containers/pair.hpp | 3
   trunk/boost/interprocess/containers/set.hpp | 5
   trunk/boost/interprocess/containers/slist.hpp | 3
   trunk/boost/interprocess/containers/stable_vector.hpp | 3
   trunk/boost/interprocess/containers/string.hpp | 5
   trunk/boost/interprocess/containers/vector.hpp | 3
   trunk/boost/interprocess/containers/version_type.hpp | 4
   trunk/boost/interprocess/creation_tags.hpp | 2
   trunk/boost/interprocess/detail/atomic.hpp | 23 +
   trunk/boost/interprocess/detail/cast_tags.hpp | 2
   trunk/boost/interprocess/detail/config_begin.hpp | 2
   trunk/boost/interprocess/detail/config_end.hpp | 2
   trunk/boost/interprocess/detail/file_wrapper.hpp | 4
   trunk/boost/interprocess/detail/in_place_interface.hpp | 2
   trunk/boost/interprocess/detail/interprocess_tester.hpp | 2
   trunk/boost/interprocess/detail/intersegment_ptr.hpp | 2
   trunk/boost/interprocess/detail/managed_memory_impl.hpp | 4
   trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp | 2
   trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp | 5
   trunk/boost/interprocess/detail/math_functions.hpp | 2
   trunk/boost/interprocess/detail/min_max.hpp | 2
   trunk/boost/interprocess/detail/move.hpp | 340 +++++++++++++++++++------
   trunk/boost/interprocess/detail/mpl.hpp | 2
   trunk/boost/interprocess/detail/multi_segment_services.hpp | 2
   trunk/boost/interprocess/detail/named_proxy.hpp | 2
   trunk/boost/interprocess/detail/os_file_functions.hpp | 50 ++
   trunk/boost/interprocess/detail/os_thread_functions.hpp | 2
   trunk/boost/interprocess/detail/pointer_type.hpp | 2
   trunk/boost/interprocess/detail/posix_time_types_wrk.hpp | 2
   trunk/boost/interprocess/detail/preprocessor.hpp | 2
   trunk/boost/interprocess/detail/segment_manager_helper.hpp | 2
   trunk/boost/interprocess/detail/tmp_dir_helpers.hpp | 2
   trunk/boost/interprocess/detail/transform_iterator.hpp | 2
   trunk/boost/interprocess/detail/type_traits.hpp | 2
   trunk/boost/interprocess/detail/utilities.hpp | 2
   trunk/boost/interprocess/detail/variadic_templates_tools.hpp | 2
   trunk/boost/interprocess/detail/win32_api.hpp | 29 +
   trunk/boost/interprocess/detail/workaround.hpp | 22
   trunk/boost/interprocess/errors.hpp | 2
   trunk/boost/interprocess/exceptions.hpp | 2
   trunk/boost/interprocess/file_mapping.hpp | 8
   trunk/boost/interprocess/indexes/flat_map_index.hpp | 2
   trunk/boost/interprocess/indexes/iset_index.hpp | 2
   trunk/boost/interprocess/indexes/iunordered_set_index.hpp | 2
   trunk/boost/interprocess/indexes/map_index.hpp | 2
   trunk/boost/interprocess/indexes/null_index.hpp | 2
   trunk/boost/interprocess/indexes/unordered_map_index.hpp | 2
   trunk/boost/interprocess/interprocess_fwd.hpp | 2
   trunk/boost/interprocess/ipc/message_queue.hpp | 2
   trunk/boost/interprocess/managed_external_buffer.hpp | 6
   trunk/boost/interprocess/managed_heap_memory.hpp | 6
   trunk/boost/interprocess/managed_mapped_file.hpp | 6
   trunk/boost/interprocess/managed_shared_memory.hpp | 6
   trunk/boost/interprocess/managed_windows_shared_memory.hpp | 7
   trunk/boost/interprocess/mapped_region.hpp | 12
   trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp | 526 --------------------------------------
   trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp | 2
   trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp | 3
   trunk/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 8
   trunk/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 10
   trunk/boost/interprocess/mem_algo/simple_seq_fit.hpp | 2
   trunk/boost/interprocess/offset_ptr.hpp | 2
   trunk/boost/interprocess/segment_manager.hpp | 4
   trunk/boost/interprocess/shared_memory_object.hpp | 13
   trunk/boost/interprocess/smart_ptr/deleter.hpp | 2
   trunk/boost/interprocess/smart_ptr/detail/shared_count.hpp | 2
   trunk/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp | 2
   trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp | 2
   trunk/boost/interprocess/smart_ptr/shared_ptr.hpp | 12
   trunk/boost/interprocess/smart_ptr/unique_ptr.hpp | 5
   trunk/boost/interprocess/smart_ptr/weak_ptr.hpp | 2
   trunk/boost/interprocess/streams/bufferstream.hpp | 2
   trunk/boost/interprocess/streams/vectorstream.hpp | 2
   trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp | 9
   trunk/boost/interprocess/sync/emulation/interprocess_mutex.hpp | 2
   trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp | 3
   trunk/boost/interprocess/sync/emulation/interprocess_semaphore.hpp | 56 ++--
   trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp | 2
   trunk/boost/interprocess/sync/file_lock.hpp | 8
   trunk/boost/interprocess/sync/interprocess_barrier.hpp | 2
   trunk/boost/interprocess/sync/interprocess_condition.hpp | 4
   trunk/boost/interprocess/sync/interprocess_mutex.hpp | 2
   trunk/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 2
   trunk/boost/interprocess/sync/interprocess_semaphore.hpp | 8
   trunk/boost/interprocess/sync/interprocess_upgradable_mutex.hpp | 2
   trunk/boost/interprocess/sync/lock_options.hpp | 2
   trunk/boost/interprocess/sync/mutex_family.hpp | 2
   trunk/boost/interprocess/sync/named_condition.hpp | 2
   trunk/boost/interprocess/sync/named_mutex.hpp | 2
   trunk/boost/interprocess/sync/named_recursive_mutex.hpp | 2
   trunk/boost/interprocess/sync/named_semaphore.hpp | 2
   trunk/boost/interprocess/sync/named_upgradable_mutex.hpp | 2
   trunk/boost/interprocess/sync/null_mutex.hpp | 2
   trunk/boost/interprocess/sync/posix/interprocess_condition.hpp | 2
   trunk/boost/interprocess/sync/posix/interprocess_mutex.hpp | 2
   trunk/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp | 2
   trunk/boost/interprocess/sync/posix/interprocess_semaphore.hpp | 2
   trunk/boost/interprocess/sync/posix/pthread_helpers.hpp | 2
   trunk/boost/interprocess/sync/posix/ptime_to_timespec.hpp | 2
   trunk/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 2
   trunk/boost/interprocess/sync/scoped_lock.hpp | 6
   trunk/boost/interprocess/sync/sharable_lock.hpp | 7
   trunk/boost/interprocess/sync/upgradable_lock.hpp | 7
   trunk/boost/interprocess/windows_shared_memory.hpp | 7
   trunk/boost/intrusive/any_hook.hpp | 2
   trunk/boost/intrusive/avl_set.hpp | 112 ++++++++
   trunk/boost/intrusive/avl_set_hook.hpp | 4
   trunk/boost/intrusive/avltree.hpp | 72 +++++
   trunk/boost/intrusive/avltree_algorithms.hpp | 60 ++++
   trunk/boost/intrusive/bs_set_hook.hpp | 4
   trunk/boost/intrusive/circular_list_algorithms.hpp | 4
   trunk/boost/intrusive/circular_slist_algorithms.hpp | 4
   trunk/boost/intrusive/derivation_value_traits.hpp | 2
   trunk/boost/intrusive/detail/any_node_and_algorithms.hpp | 2
   trunk/boost/intrusive/detail/assert.hpp | 2
   trunk/boost/intrusive/detail/clear_on_destructor_base.hpp | 2
   trunk/boost/intrusive/detail/common_slist_algorithms.hpp | 25 +
   trunk/boost/intrusive/detail/config_begin.hpp | 2
   trunk/boost/intrusive/detail/config_end.hpp | 2
   trunk/boost/intrusive/detail/ebo_functor_holder.hpp | 5
   trunk/boost/intrusive/detail/generic_hook.hpp | 2
   trunk/boost/intrusive/detail/hashtable_node.hpp | 20 +
   trunk/boost/intrusive/detail/list_node.hpp | 18
   trunk/boost/intrusive/detail/mpl.hpp | 5
   trunk/boost/intrusive/detail/parent_from_member.hpp | 2
   trunk/boost/intrusive/detail/rbtree_node.hpp | 2
   trunk/boost/intrusive/detail/slist_node.hpp | 18
   trunk/boost/intrusive/detail/transform_iterator.hpp | 2
   trunk/boost/intrusive/detail/tree_algorithms.hpp | 166 ++++++++----
   trunk/boost/intrusive/detail/tree_node.hpp | 31 -
   trunk/boost/intrusive/detail/utilities.hpp | 150 +++++-----
   trunk/boost/intrusive/detail/workaround.hpp | 2
   trunk/boost/intrusive/hashtable.hpp | 82 +++---
   trunk/boost/intrusive/intrusive_fwd.hpp | 2
   trunk/boost/intrusive/linear_slist_algorithms.hpp | 4
   trunk/boost/intrusive/link_mode.hpp | 2
   trunk/boost/intrusive/list.hpp | 5
   trunk/boost/intrusive/list_hook.hpp | 4
   trunk/boost/intrusive/member_value_traits.hpp | 2
   trunk/boost/intrusive/options.hpp | 2
   trunk/boost/intrusive/pointer_plus_bits.hpp | 4
   trunk/boost/intrusive/priority_compare.hpp | 2
   trunk/boost/intrusive/rbtree.hpp | 76 +++++
   trunk/boost/intrusive/rbtree_algorithms.hpp | 62 ++++
   trunk/boost/intrusive/set.hpp | 107 +++++++
   trunk/boost/intrusive/set_hook.hpp | 4
   trunk/boost/intrusive/sg_set.hpp | 111 ++++++++
   trunk/boost/intrusive/sgtree.hpp | 87 ++++++
   trunk/boost/intrusive/sgtree_algorithms.hpp | 70 +++++
   trunk/boost/intrusive/slist.hpp | 210 ++++++++++++---
   trunk/boost/intrusive/slist_hook.hpp | 4
   trunk/boost/intrusive/splay_set.hpp | 4
   trunk/boost/intrusive/splay_set_hook.hpp | 4
   trunk/boost/intrusive/splaytree.hpp | 5
   trunk/boost/intrusive/splaytree_algorithms.hpp | 99 ++++++
   trunk/boost/intrusive/treap.hpp | 187 ++++++++++---
   trunk/boost/intrusive/treap_algorithms.hpp | 165 +++++++++--
   trunk/boost/intrusive/treap_set.hpp | 207 ++++++++++++--
   trunk/boost/intrusive/trivial_value_traits.hpp | 2
   trunk/boost/intrusive/unordered_set.hpp | 49 +-
   trunk/boost/intrusive/unordered_set_hook.hpp | 4
   210 files changed, 3619 insertions(+), 3314 deletions(-)

Modified: trunk/boost/interprocess/allocators/adaptive_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/adaptive_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/adaptive_pool.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -28,6 +28,7 @@
 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
 #include <memory>
 #include <algorithm>
@@ -95,7 +96,7 @@
    typedef std::ptrdiff_t difference_type;
 
    typedef boost::interprocess::version_type<adaptive_pool_base, Version> version;
- typedef detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
 
    //!Obtains adaptive_pool_base from

Modified: trunk/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/allocator.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -22,6 +22,7 @@
 
 #include <boost/interprocess/interprocess_fwd.hpp>
 #include <boost/interprocess/containers/allocation_type.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/containers/version_type.hpp>
@@ -102,7 +103,7 @@
    /// @cond
 
    //Experimental. Don't use.
- typedef boost::interprocess::detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
    /// @endcond
 

Modified: trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp (original)
+++ trunk/boost/interprocess/allocators/cached_adaptive_pool.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -18,21 +18,17 @@
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/pointer_to_other.hpp>
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/min_max.hpp>
 #include <boost/interprocess/detail/math_functions.hpp>
-#include <boost/interprocess/exceptions.hpp>
 #include <boost/intrusive/set.hpp>
 #include <boost/intrusive/slist.hpp>
-#include <boost/math/common_factor_ct.hpp>
 #include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
 #include <boost/interprocess/allocators/detail/node_tools.hpp>
 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <cstddef>
 #include <boost/config/no_tr1/cmath.hpp>
+#include <boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp>
 #include <cassert>
 
 //!\file
@@ -42,532 +38,6 @@
 namespace interprocess {
 namespace detail {
 
-template<class SegmentManagerBase>
-class private_adaptive_node_pool_impl
-{
- //Non-copyable
- private_adaptive_node_pool_impl();
- private_adaptive_node_pool_impl(const private_adaptive_node_pool_impl &);
- private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
-
- typedef typename SegmentManagerBase::void_pointer void_pointer;
- static const std::size_t PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
- public:
- typedef typename node_slist<void_pointer>::node_t node_t;
- typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
- typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
-
- private:
- typedef typename bi::make_set_base_hook
- < bi::void_pointer<void_pointer>
- , bi::optimize_size<true>
- , bi::constant_time_size<false>
- , bi::link_mode<bi::normal_link> >::type multiset_hook_t;
-
- struct hdr_offset_holder
- {
- hdr_offset_holder(std::size_t offset = 0)
- : hdr_offset(offset)
- {}
- std::size_t hdr_offset;
- };
-
- struct block_info_t
- :
- public hdr_offset_holder,
- public multiset_hook_t
- {
- //An intrusive list of free node from this block
- free_nodes_t free_nodes;
- friend bool operator <(const block_info_t &l, const block_info_t &r)
- {
-// { return l.free_nodes.size() < r.free_nodes.size(); }
- //Let's order blocks first by free nodes and then by address
- //so that highest address fully free blocks are deallocated.
- //This improves returning memory to the OS (trimming).
- const bool is_less = l.free_nodes.size() < r.free_nodes.size();
- const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
- return is_less || (is_equal && (&l < &r));
- }
- };
- typedef typename bi::make_multiset
- <block_info_t, bi::base_hook<multiset_hook_t> >::type block_multiset_t;
- typedef typename block_multiset_t::iterator block_iterator;
-
- static const std::size_t MaxAlign = alignment_of<node_t>::value;
- static const std::size_t HdrSize = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
- static const std::size_t HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
- static std::size_t calculate_alignment
- (std::size_t overhead_percent, std::size_t real_node_size)
- {
- //to-do: handle real_node_size != node_size
- const std::size_t divisor = overhead_percent*real_node_size;
- const std::size_t dividend = HdrOffsetSize*100;
- std::size_t elements_per_subblock = (dividend - 1)/divisor + 1;
- std::size_t candidate_power_of_2 =
- upper_power_of_2(elements_per_subblock*real_node_size + HdrOffsetSize);
- bool overhead_satisfied = false;
- //Now calculate the wors-case overhead for a subblock
- const std::size_t max_subblock_overhead = HdrSize + PayloadPerAllocation;
- while(!overhead_satisfied){
- elements_per_subblock = (candidate_power_of_2 - max_subblock_overhead)/real_node_size;
- const std::size_t overhead_size = candidate_power_of_2 - elements_per_subblock*real_node_size;
- if(overhead_size*100/candidate_power_of_2 < overhead_percent){
- overhead_satisfied = true;
- }
- else{
- candidate_power_of_2 <<= 1;
- }
- }
- return candidate_power_of_2;
- }
-
- static void calculate_num_subblocks
- (std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_block
- ,std::size_t &num_subblocks, std::size_t &real_num_node, std::size_t overhead_percent)
- {
- std::size_t elements_per_subblock = (alignment - HdrOffsetSize)/real_node_size;
- std::size_t possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
- std::size_t hdr_subblock_elements = (alignment - HdrSize - PayloadPerAllocation)/real_node_size;
- while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
- ++possible_num_subblock;
- }
- elements_per_subblock = (alignment - HdrOffsetSize)/real_node_size;
- bool overhead_satisfied = false;
- while(!overhead_satisfied){
- const std::size_t total_data = (elements_per_subblock*(possible_num_subblock-1) + hdr_subblock_elements)*real_node_size;
- const std::size_t total_size = alignment*possible_num_subblock;
- if((total_size - total_data)*100/total_size < overhead_percent){
- overhead_satisfied = true;
- }
- else{
- ++possible_num_subblock;
- }
- }
- num_subblocks = possible_num_subblock;
- real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
- }
-
- public:
- //!Segment manager typedef
- typedef SegmentManagerBase segment_manager_base_type;
-
- //!Constructor from a segment manager. Never throws
- private_adaptive_node_pool_impl
- ( segment_manager_base_type *segment_mngr_base, std::size_t node_size
- , std::size_t nodes_per_block, std::size_t max_free_blocks
- , unsigned char overhead_percent
- )
- : m_max_free_blocks(max_free_blocks)
- , m_real_node_size(lcm(node_size, std::size_t(alignment_of<node_t>::value)))
- //Round the size to a power of two value.
- //This is the total memory size (including payload) that we want to
- //allocate from the general-purpose allocator
- , m_real_block_alignment(calculate_alignment(overhead_percent, m_real_node_size))
- //This is the real number of nodes per block
- , m_num_subblocks(0)
- , m_real_num_node(0)
- //General purpose allocator
- , mp_segment_mngr_base(segment_mngr_base)
- , m_block_multiset()
- , m_totally_free_blocks(0)
- {
- calculate_num_subblocks(m_real_block_alignment, m_real_node_size, nodes_per_block, m_num_subblocks, m_real_num_node, overhead_percent);
- }
-
- //!Destructor. Deallocates all allocated blocks. Never throws
- ~private_adaptive_node_pool_impl()
- { priv_clear(); }
-
- std::size_t get_real_num_node() const
- { return m_real_num_node; }
-
- //!Returns the segment manager. Never throws
- segment_manager_base_type* get_segment_manager_base()const
- { return detail::get_pointer(mp_segment_mngr_base); }
-
- //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
- void *allocate_node()
- {
- priv_invariants();
- //If there are no free nodes we allocate a new block
- if (m_block_multiset.empty()){
- priv_alloc_block(1);
- }
- //We take the first free node the multiset can't be empty
- return priv_take_first_node();
- }
-
- //!Deallocates an array pointed by ptr. Never throws
- void deallocate_node(void *pElem)
- {
- multiallocation_chain chain;
- chain.push_front(void_pointer(pElem));
- this->priv_reinsert_nodes_in_block(chain, 1);
- //Update free block count
- if(m_totally_free_blocks > m_max_free_blocks){
- this->priv_deallocate_free_blocks(m_max_free_blocks);
- }
- priv_invariants();
- }
-
- //!Allocates n nodes.
- //!Can throw boost::interprocess::bad_alloc
- multiallocation_chain allocate_nodes(const std::size_t n)
- {
- multiallocation_chain chain;
- std::size_t i = 0;
- try{
- priv_invariants();
- while(i != n){
- //If there are no free nodes we allocate all needed blocks
- if (m_block_multiset.empty()){
- priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
- }
- free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
- const std::size_t free_nodes_count_before = free_nodes.size();
- if(free_nodes_count_before == m_real_num_node){
- --m_totally_free_blocks;
- }
- const std::size_t num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
- for(std::size_t j = 0; j != num_elems; ++j){
- void *new_node = &free_nodes.front();
- free_nodes.pop_front();
- chain.push_back(new_node);
- }
-
- if(free_nodes.empty()){
- m_block_multiset.erase(m_block_multiset.begin());
- }
- i += num_elems;
- }
- }
- catch(...){
- this->deallocate_nodes(chain, i);
- throw;
- }
- priv_invariants();
- return boost::interprocess::move(chain);
- }
-
- //!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain nodes)
- {
- return deallocate_nodes(nodes, nodes.size());
- }
-
- //!Deallocates the first n nodes of a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain &nodes, std::size_t n)
- {
- this->priv_reinsert_nodes_in_block(nodes, n);
- if(m_totally_free_blocks > m_max_free_blocks){
- this->priv_deallocate_free_blocks(m_max_free_blocks);
- }
- }
-
- void deallocate_free_blocks()
- { this->priv_deallocate_free_blocks(0); }
-
- std::size_t num_free_nodes()
- {
- typedef typename block_multiset_t::const_iterator citerator;
- std::size_t count = 0;
- citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
- for(; it != itend; ++it){
- count += it->free_nodes.size();
- }
- return count;
- }
-
- void swap(private_adaptive_node_pool_impl &other)
- {
- assert(m_max_free_blocks == other.m_max_free_blocks);
- assert(m_real_node_size == other.m_real_node_size);
- assert(m_real_block_alignment == other.m_real_block_alignment);
- assert(m_real_num_node == other.m_real_num_node);
- std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
- std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
- m_block_multiset.swap(other.m_block_multiset);
- }
-
- //Deprecated, use deallocate_free_blocks
- void deallocate_free_chunks()
- { this->priv_deallocate_free_blocks(0); }
-
- private:
- void priv_deallocate_free_blocks(std::size_t max_free_blocks)
- {
- priv_invariants();
- //Now check if we've reached the free nodes limit
- //and check if we have free blocks. If so, deallocate as much
- //as we can to stay below the limit
- for( block_iterator itend = m_block_multiset.end()
- ; m_totally_free_blocks > max_free_blocks
- ; --m_totally_free_blocks
- ){
- assert(!m_block_multiset.empty());
- block_iterator it = itend;
- --it;
- std::size_t num_nodes = it->free_nodes.size();
- assert(num_nodes == m_real_num_node);
- (void)num_nodes;
- m_block_multiset.erase_and_dispose
- (it, block_destroyer(this));
- }
- }
-
- void priv_reinsert_nodes_in_block(multiallocation_chain &chain, std::size_t n)
- {
- block_iterator block_it(m_block_multiset.end());
- while(n--){
- void *pElem = detail::get_pointer(chain.front());
- chain.pop_front();
- priv_invariants();
- block_info_t *block_info = this->priv_block_from_node(pElem);
- assert(block_info->free_nodes.size() < m_real_num_node);
- //We put the node at the beginning of the free node list
- node_t * to_deallocate = static_cast<node_t*>(pElem);
- block_info->free_nodes.push_front(*to_deallocate);
-
- block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
- block_iterator next_block(this_block);
- ++next_block;
-
- //Cache the free nodes from the block
- std::size_t this_block_free_nodes = this_block->free_nodes.size();
-
- if(this_block_free_nodes == 1){
- m_block_multiset.insert(m_block_multiset.begin(), *block_info);
- }
- else{
- block_iterator next_block(this_block);
- ++next_block;
- if(next_block != block_it){
- std::size_t next_free_nodes = next_block->free_nodes.size();
- if(this_block_free_nodes > next_free_nodes){
- //Now move the block to the new position
- m_block_multiset.erase(this_block);
- m_block_multiset.insert(*block_info);
- }
- }
- }
- //Update free block count
- if(this_block_free_nodes == m_real_num_node){
- ++m_totally_free_blocks;
- }
- priv_invariants();
- }
- }
-
- node_t *priv_take_first_node()
- {
- assert(m_block_multiset.begin() != m_block_multiset.end());
- //We take the first free node the multiset can't be empty
- free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
- node_t *first_node = &free_nodes.front();
- const std::size_t free_nodes_count = free_nodes.size();
- assert(0 != free_nodes_count);
- free_nodes.pop_front();
- if(free_nodes_count == 1){
- m_block_multiset.erase(m_block_multiset.begin());
- }
- else if(free_nodes_count == m_real_num_node){
- --m_totally_free_blocks;
- }
- priv_invariants();
- return first_node;
- }
-
- class block_destroyer;
- friend class block_destroyer;
-
- class block_destroyer
- {
- public:
- block_destroyer(const private_adaptive_node_pool_impl *impl)
- : mp_impl(impl)
- {}
-
- void operator()(typename block_multiset_t::pointer to_deallocate)
- {
- std::size_t free_nodes = to_deallocate->free_nodes.size();
- (void)free_nodes;
- assert(free_nodes == mp_impl->m_real_num_node);
- assert(0 == to_deallocate->hdr_offset);
- hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(detail::get_pointer(to_deallocate));
- mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
- }
- const private_adaptive_node_pool_impl *mp_impl;
- };
-
- //This macro will activate invariant checking. Slow, but helpful for debugging the code.
- //#define BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
- void priv_invariants()
- #ifdef BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
- #undef BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
- {
- //We iterate through the block list to free the memory
- block_iterator it(m_block_multiset.begin()),
- itend(m_block_multiset.end()), to_deallocate;
- if(it != itend){
- for(++it; it != itend; ++it){
- block_iterator prev(it);
- --prev;
- std::size_t sp = prev->free_nodes.size(),
- si = it->free_nodes.size();
- assert(sp <= si);
- (void)sp; (void)si;
- }
- }
-
- {
- //Check that the total free nodes are correct
- it = m_block_multiset.begin();
- itend = m_block_multiset.end();
- std::size_t total_free_nodes = 0;
- for(; it != itend; ++it){
- total_free_nodes += it->free_nodes.size();
- }
- assert(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
- }
-
- {
- //Check that the total totally free blocks are correct
- it = m_block_multiset.begin();
- itend = m_block_multiset.end();
- std::size_t total_free_blocks = 0;
- for(; it != itend; ++it){
- total_free_blocks += (it->free_nodes.size() == m_real_num_node);
- }
- assert(total_free_blocks == m_totally_free_blocks);
- }
- {
- //Check that header offsets are correct
- it = m_block_multiset.begin();
- for(; it != itend; ++it){
- hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
- for(std::size_t i = 0, max = m_num_subblocks; i < max; ++i){
- assert(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
- assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
- assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
- hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
- }
- }
- }
- }
- #else
- {} //empty
- #endif
-
- //!Deallocates all used memory. Never throws
- void priv_clear()
- {
- #ifndef NDEBUG
- block_iterator it = m_block_multiset.begin();
- block_iterator itend = m_block_multiset.end();
- std::size_t num_free_nodes = 0;
- for(; it != itend; ++it){
- //Check for memory leak
- std::size_t n = (std::size_t)it->free_nodes.size(); (void)n;
- assert(it->free_nodes.size() == m_real_num_node);
- ++num_free_nodes;
- }
- assert(num_free_nodes == m_totally_free_blocks);
- #endif
- priv_invariants();
- m_block_multiset.clear_and_dispose
- (block_destroyer(this));
- m_totally_free_blocks = 0;
- }
-
- block_info_t *priv_block_from_node(void *node) const
- {
- hdr_offset_holder *hdr_off_holder =
- reinterpret_cast<hdr_offset_holder*>((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
- assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
- assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
- block_info_t *block = reinterpret_cast<block_info_t *>
- (reinterpret_cast<char*>(hdr_off_holder) + hdr_off_holder->hdr_offset);
- assert(block->hdr_offset == 0);
- return block;
- }
-
- hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
- {
- hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
- (reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
- assert(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
- assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
- assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
- return hdr_off_holder;
- }
-
- //!Allocates a several blocks of nodes. Can throw boost::interprocess::bad_alloc
- void priv_alloc_block(std::size_t n)
- {
- std::size_t real_block_size = m_real_block_alignment*m_num_subblocks - SegmentManagerBase::PayloadPerAllocation;
- std::size_t elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
- std::size_t hdr_subblock_elements = (m_real_block_alignment - HdrSize - SegmentManagerBase::PayloadPerAllocation)/m_real_node_size;
-
- for(std::size_t i = 0; i != n; ++i){
- //We allocate a new NodeBlock and put it the last
- //element of the tree
- char *mem_address = static_cast<char*>
- (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
- if(!mem_address) throw std::bad_alloc();
- ++m_totally_free_blocks;
-
- //First initialize header information on the last subblock
- char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
- block_info_t *c_info = new(hdr_addr)block_info_t;
- //Some structural checks
- assert(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
- static_cast<void*>(c_info));
- typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
- for( std::size_t subblock = 0, maxsubblock = m_num_subblocks - 1
- ; subblock < maxsubblock
- ; ++subblock, mem_address += m_real_block_alignment){
- //Initialize header offset mark
- new(mem_address) hdr_offset_holder(std::size_t(hdr_addr - mem_address));
- char *pNode = mem_address + HdrOffsetSize;
- for(std::size_t i = 0; i < elements_per_subblock; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
- pNode += m_real_node_size;
- }
- }
- {
- char *pNode = hdr_addr + HdrSize;
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- for(std::size_t i = 0; i < hdr_subblock_elements; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
- pNode += m_real_node_size;
- }
- }
- //Insert the block after the free node list is full
- m_block_multiset.insert(m_block_multiset.end(), *c_info);
- }
- }
-
- private:
- typedef typename boost::pointer_to_other
- <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
-
- const std::size_t m_max_free_blocks;
- const std::size_t m_real_node_size;
- //Round the size to a power of two value.
- //This is the total memory size (including payload) that we want to
- //allocate from the general-purpose allocator
- const std::size_t m_real_block_alignment;
- std::size_t m_num_subblocks;
- //This is the real number of nodes per block
- //const
- std::size_t m_real_num_node;
- segment_mngr_base_ptr_t mp_segment_mngr_base;//Segment manager
- block_multiset_t m_block_multiset; //Intrusive block list
- std::size_t m_totally_free_blocks; //Free blocks
-};
-
 template< class SegmentManager
         , std::size_t NodeSize
         , std::size_t NodesPerBlock
@@ -575,10 +45,10 @@
         , unsigned char OverheadPercent
>
 class private_adaptive_node_pool
- : public private_adaptive_node_pool_impl
+ : public boost::container::containers_detail::private_adaptive_node_pool_impl
          <typename SegmentManager::segment_manager_base_type>
 {
- typedef private_adaptive_node_pool_impl
+ typedef boost::container::containers_detail::private_adaptive_node_pool_impl
       <typename SegmentManager::segment_manager_base_type> base_t;
    //Non-copyable
    private_adaptive_node_pool();
@@ -636,4 +106,3 @@
 #include <boost/interprocess/detail/config_end.hpp>
 
 #endif //#ifndef BOOST_INTERPROCESS_DETAIL_ADAPTIVE_NODE_POOL_HPP
-

Modified: trunk/boost/interprocess/allocators/detail/allocator_common.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/detail/allocator_common.hpp (original)
+++ trunk/boost/interprocess/allocators/detail/allocator_common.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -24,6 +24,7 @@
 #include <boost/interprocess/exceptions.hpp> //bad_alloc
 #include <boost/interprocess/sync/scoped_lock.hpp> //scoped_lock
 #include <boost/interprocess/containers/allocation_type.hpp> //boost::interprocess::allocation_type
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
 #include <boost/interprocess/detail/segment_manager_helper.hpp>
 #include <algorithm> //std::swap
@@ -275,8 +276,19 @@
    //!Frees n cached nodes at once. Never throws
    void priv_deallocate_n_nodes(std::size_t n)
    {
+ //This only occurs if this allocator deallocate memory allocated
+ //with other equal allocator. Since the cache is full, and more
+ //deallocations are probably coming, we'll make some room in cache
+ //in a single, efficient multi node deallocation.
+ std::size_t count(n);
+ typename multiallocation_chain::iterator it(m_cached_nodes.before_begin());
+ while(count--){
+ ++it;
+ }
+ multiallocation_chain chain;
+ chain.splice_after(chain.before_begin(), m_cached_nodes, m_cached_nodes.before_begin(), it, n);
       //Deallocate all new linked list at once
- mp_node_pool->deallocate_nodes(m_cached_nodes, n);
+ mp_node_pool->deallocate_nodes(boost::interprocess::move(chain));
    }
 };
 
@@ -302,7 +314,7 @@
                      <const value_type>::type const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
- typedef detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
 
 
@@ -413,7 +425,7 @@
                      <const value_type>::type const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
- typedef detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
 
 
@@ -690,7 +702,7 @@
    typedef typename private_node_allocator_t::
       segment_manager segment_manager;
    typedef typename private_node_allocator_t::
- multiallocation_chain multiallocation_chain;
+ multiallocation_chain multiallocation_chain;
 
  private:
    typedef typename segment_manager::mutex_family::mutex_type mutex_type;
@@ -820,7 +832,7 @@
 
    private:
    //!This struct includes needed data and derives from
- //!interprocess_mutex to allow EBO when using null_mutex
+ //!the mutex type to allow EBO when using null_mutex
    struct header_t : mutex_type
    {
       std::size_t m_usecount; //Number of attached allocators

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -22,18 +22,11 @@
 #include <boost/math/common_factor_ct.hpp>
 #include <boost/pointer_to_other.hpp>
 
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/math_functions.hpp>
-#include <boost/interprocess/detail/type_traits.hpp>
-#include <boost/interprocess/allocators/detail/node_tools.hpp>
-#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
+#include <boost/interprocess/containers/container/detail/node_pool_impl.hpp>
 #include <cstddef>
-#include <functional>
-#include <algorithm>
-#include <cassert>
+
 
 //!\file
 //!Describes the real adaptive pool shared by many Interprocess adaptive pool allocators
@@ -42,301 +35,6 @@
 namespace interprocess {
 namespace detail {
 
-template<class SegmentManagerBase>
-class private_node_pool_impl
-{
- //Non-copyable
- private_node_pool_impl();
- private_node_pool_impl(const private_node_pool_impl &);
- private_node_pool_impl &operator=(const private_node_pool_impl &);
-
- //A node object will hold node_t when it's not allocated
- public:
- typedef typename SegmentManagerBase::void_pointer void_pointer;
- typedef typename node_slist<void_pointer>::slist_hook_t slist_hook_t;
- typedef typename node_slist<void_pointer>::node_t node_t;
- typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
- typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
-
- private:
- typedef typename bi::make_slist
- < node_t, bi::base_hook<slist_hook_t>
- , bi::linear<true>
- , bi::constant_time_size<false> >::type blockslist_t;
- public:
-
- //!Segment manager typedef
- typedef SegmentManagerBase segment_manager_base_type;
-
- //!Constructor from a segment manager. Never throws
- private_node_pool_impl(segment_manager_base_type *segment_mngr_base, std::size_t node_size, std::size_t nodes_per_block)
- : m_nodes_per_block(nodes_per_block)
- , m_real_node_size(detail::lcm(node_size, std::size_t(alignment_of<node_t>::value)))
- //General purpose allocator
- , mp_segment_mngr_base(segment_mngr_base)
- , m_blocklist()
- , m_freelist()
- //Debug node count
- , m_allocated(0)
- {}
-
- //!Destructor. Deallocates all allocated blocks. Never throws
- ~private_node_pool_impl()
- { this->purge_blocks(); }
-
- std::size_t get_real_num_node() const
- { return m_nodes_per_block; }
-
- //!Returns the segment manager. Never throws
- segment_manager_base_type* get_segment_manager_base()const
- { return detail::get_pointer(mp_segment_mngr_base); }
-
- //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
- void *allocate_node()
- {
- //If there are no free nodes we allocate a new block
- if (m_freelist.empty())
- priv_alloc_block();
- //We take the first free node
- node_t *n = &m_freelist.front();
- m_freelist.pop_front();
- ++m_allocated;
- return n;
- }
-
- //!Deallocates an array pointed by ptr. Never throws
- void deallocate_node(void *ptr)
- {
- //We put the node at the beginning of the free node list
- node_t * to_deallocate = static_cast<node_t*>(ptr);
- m_freelist.push_front(*to_deallocate);
- assert(m_allocated>0);
- --m_allocated;
- }
-
- //!Allocates a singly linked list of n nodes ending in null pointer
- //!can throw boost::interprocess::bad_alloc
- multiallocation_chain allocate_nodes(const std::size_t n)
- {
- multiallocation_chain nodes;
- std::size_t i = 0;
- try{
- for(; i < n; ++i){
- nodes.push_front(this->allocate_node());
- }
- }
- catch(...){
- this->deallocate_nodes(nodes, i);
- throw;
- }
- return boost::interprocess::move(nodes);
- }
-
- //!Deallocates the first n nodes of a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain &nodes, std::size_t n)
- {
- for(std::size_t i = 0; i < n; ++i){
- void *p = detail::get_pointer(nodes.front());
- assert(p);
- nodes.pop_front();
- this->deallocate_node(p);
- }
- }
-
- //!Deallocates the nodes pointed by the multiallocation iterator. Never throws
- void deallocate_nodes(multiallocation_chain chain)
- {
- while(!chain.empty()){
- void *addr = detail::get_pointer(chain.front());
- chain.pop_front();
- deallocate_node(addr);
- }
- }
-
- //!Deallocates all the free blocks of memory. Never throws
- void deallocate_free_blocks()
- {
- typedef typename free_nodes_t::iterator nodelist_iterator;
- typename blockslist_t::iterator bit(m_blocklist.before_begin()),
- it(m_blocklist.begin()),
- itend(m_blocklist.end());
- free_nodes_t backup_list;
- nodelist_iterator backup_list_last = backup_list.before_begin();
-
- //Execute the algorithm and get an iterator to the last value
- std::size_t blocksize = detail::get_rounded_size
- (m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
-
- while(it != itend){
- //Collect all the nodes from the block pointed by it
- //and push them in the list
- free_nodes_t free_nodes;
- nodelist_iterator last_it = free_nodes.before_begin();
- const void *addr = get_block_from_hook(&*it, blocksize);
-
- m_freelist.remove_and_dispose_if
- (is_between(addr, blocksize), push_in_list(free_nodes, last_it));
-
- //If the number of nodes is equal to m_nodes_per_block
- //this means that the block can be deallocated
- if(free_nodes.size() == m_nodes_per_block){
- //Unlink the nodes
- free_nodes.clear();
- it = m_blocklist.erase_after(bit);
- mp_segment_mngr_base->deallocate((void*)addr);
- }
- //Otherwise, insert them in the backup list, since the
- //next "remove_if" does not need to check them again.
- else{
- //Assign the iterator to the last value if necessary
- if(backup_list.empty() && !m_freelist.empty()){
- backup_list_last = last_it;
- }
- //Transfer nodes. This is constant time.
- backup_list.splice_after
- ( backup_list.before_begin()
- , free_nodes
- , free_nodes.before_begin()
- , last_it
- , free_nodes.size());
- bit = it;
- ++it;
- }
- }
- //We should have removed all the nodes from the free list
- assert(m_freelist.empty());
-
- //Now pass all the node to the free list again
- m_freelist.splice_after
- ( m_freelist.before_begin()
- , backup_list
- , backup_list.before_begin()
- , backup_list_last
- , backup_list.size());
- }
-
- std::size_t num_free_nodes()
- { return m_freelist.size(); }
-
- //!Deallocates all used memory. Precondition: all nodes allocated from this pool should
- //!already be deallocated. Otherwise, undefined behaviour. Never throws
- void purge_blocks()
- {
- //check for memory leaks
- assert(m_allocated==0);
- std::size_t blocksize = detail::get_rounded_size
- (m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
- typename blockslist_t::iterator
- it(m_blocklist.begin()), itend(m_blocklist.end()), aux;
-
- //We iterate though the NodeBlock list to free the memory
- while(!m_blocklist.empty()){
- void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
- m_blocklist.pop_front();
- mp_segment_mngr_base->deallocate((void*)addr);
- }
- //Just clear free node list
- m_freelist.clear();
- }
-
- void swap(private_node_pool_impl &other)
- {
- std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
- m_blocklist.swap(other.m_blocklist);
- m_freelist.swap(other.m_freelist);
- std::swap(m_allocated, other.m_allocated);
- }
-
- private:
-
- struct push_in_list
- {
- push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
- : slist_(l), last_it_(it)
- {}
-
- void operator()(typename free_nodes_t::pointer p) const
- {
- slist_.push_front(*p);
- if(slist_.size() == 1){ //Cache last element
- ++last_it_ = slist_.begin();
- }
- }
-
- private:
- free_nodes_t &slist_;
- typename free_nodes_t::iterator &last_it_;
- };
-
- struct is_between
- : std::unary_function<typename free_nodes_t::value_type, bool>
- {
- is_between(const void *addr, std::size_t size)
- : beg_(static_cast<const char *>(addr)), end_(beg_+size)
- {}
-
- bool operator()(typename free_nodes_t::const_reference v) const
- {
- return (beg_ <= reinterpret_cast<const char *>(&v) &&
- end_ > reinterpret_cast<const char *>(&v));
- }
- private:
- const char * beg_;
- const char * end_;
- };
-
- //!Allocates a block of nodes. Can throw boost::interprocess::bad_alloc
- void priv_alloc_block()
- {
- //We allocate a new NodeBlock and put it as first
- //element in the free Node list
- std::size_t blocksize =
- detail::get_rounded_size(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
- char *pNode = reinterpret_cast<char*>
- (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
- if(!pNode) throw bad_alloc();
- char *pBlock = pNode;
- m_blocklist.push_front(get_block_hook(pBlock, blocksize));
-
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- for(std::size_t i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
- m_freelist.push_front(*new (pNode) node_t);
- }
- }
-
- //!Deprecated, use deallocate_free_blocks
- void deallocate_free_chunks()
- { this->deallocate_free_blocks(); }
-
- //!Deprecated, use purge_blocks
- void purge_chunks()
- { this->purge_blocks(); }
-
- private:
- //!Returns a reference to the block hook placed in the end of the block
- static node_t & get_block_hook (void *block, std::size_t blocksize)
- {
- return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
- }
-
- //!Returns the starting address of the block reference to the block hook placed in the end of the block
- void *get_block_from_hook (node_t *hook, std::size_t blocksize)
- {
- return (reinterpret_cast<char*>(hook) - blocksize);
- }
-
- private:
- typedef typename boost::pointer_to_other
- <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
-
- const std::size_t m_nodes_per_block;
- const std::size_t m_real_node_size;
- segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
- blockslist_t m_blocklist; //Intrusive container of blocks
- free_nodes_t m_freelist; //Intrusive container of free nods
- std::size_t m_allocated; //Used nodes for debugging
-};
 
 
 //!Pooled shared memory allocator using single segregated storage. Includes
@@ -346,9 +44,11 @@
 template< class SegmentManager, std::size_t NodeSize, std::size_t NodesPerBlock >
 class private_node_pool
    //Inherit from the implementation to avoid template bloat
- : public private_node_pool_impl<typename SegmentManager::segment_manager_base_type>
+ : public boost::container::containers_detail::
+ private_node_pool_impl<typename SegmentManager::segment_manager_base_type>
 {
- typedef private_node_pool_impl<typename SegmentManager::segment_manager_base_type> base_t;
+ typedef boost::container::containers_detail::private_node_pool_impl
+ <typename SegmentManager::segment_manager_base_type> base_t;
    //Non-copyable
    private_node_pool();
    private_node_pool(const private_node_pool &);

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/allocators/node_allocator.hpp
==============================================================================
--- trunk/boost/interprocess/allocators/node_allocator.hpp (original)
+++ trunk/boost/interprocess/allocators/node_allocator.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -26,6 +26,7 @@
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/allocators/detail/node_pool.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <memory>
@@ -92,7 +93,7 @@
    typedef std::ptrdiff_t difference_type;
 
    typedef boost::interprocess::version_type<node_allocator_base, Version> version;
- typedef detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
 
    //!Obtains node_allocator_base from

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -24,6 +24,7 @@
 #include <boost/assert.hpp>
 #include <boost/utility/addressof.hpp>
 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
@@ -93,7 +94,7 @@
    typedef std::ptrdiff_t difference_type;
    typedef boost::interprocess::version_type
       <private_adaptive_pool_base, Version> version;
- typedef detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
 
    //!Obtains node_allocator from other node_allocator

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -24,6 +24,7 @@
 #include <boost/assert.hpp>
 #include <boost/utility/addressof.hpp>
 #include <boost/interprocess/allocators/detail/node_pool.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
@@ -87,7 +88,7 @@
    typedef std::ptrdiff_t difference_type;
    typedef boost::interprocess::version_type
       <private_node_allocator_base, Version> version;
- typedef detail::transform_multiallocation_chain
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
 
    //!Obtains node_allocator from other node_allocator

Modified: trunk/boost/interprocess/anonymous_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/anonymous_shared_memory.hpp (original)
+++ trunk/boost/interprocess/anonymous_shared_memory.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/containers/allocation_type.hpp
==============================================================================
--- trunk/boost/interprocess/containers/allocation_type.hpp (original)
+++ trunk/boost/interprocess/containers/allocation_type.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -24,13 +24,13 @@
 /// @cond
 typedef int allocation_type;
 /// @endcond
-static const allocation_type allocate_new = boost::interprocess_container::allocate_new;
-static const allocation_type expand_fwd = boost::interprocess_container::expand_fwd;
-static const allocation_type expand_bwd = boost::interprocess_container::expand_bwd;
-static const allocation_type shrink_in_place = boost::interprocess_container::shrink_in_place;
-static const allocation_type try_shrink_in_place= boost::interprocess_container::try_shrink_in_place;
-static const allocation_type nothrow_allocation = boost::interprocess_container::nothrow_allocation;
-static const allocation_type zero_memory = boost::interprocess_container::zero_memory;
+static const allocation_type allocate_new = boost::container::allocate_new;
+static const allocation_type expand_fwd = boost::container::expand_fwd;
+static const allocation_type expand_bwd = boost::container::expand_bwd;
+static const allocation_type shrink_in_place = boost::container::shrink_in_place;
+static const allocation_type try_shrink_in_place= boost::container::try_shrink_in_place;
+static const allocation_type nothrow_allocation = boost::container::nothrow_allocation;
+static const allocation_type zero_memory = boost::container::zero_memory;
 
 } //namespace interprocess {
 } //namespace boost {

Added: trunk/boost/interprocess/containers/container/container_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/container_fwd.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,187 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+#define BOOST_CONTAINERS_CONTAINERS_FWD_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Standard predeclarations
+//////////////////////////////////////////////////////////////////////////////
+
+/// @cond
+
+namespace boost{
+namespace intrusive{
+ //Create namespace to avoid compilation errors
+}}
+
+namespace boost{ namespace container{ namespace containers_detail{
+
+namespace bi = boost::intrusive;
+
+}}}
+
+namespace std {
+
+template <class T>
+class allocator;
+
+template <class T>
+struct less;
+
+template <class T1, class T2>
+struct pair;
+
+template <class CharType>
+struct char_traits;
+
+} //namespace std {
+
+/// @endcond
+
+//////////////////////////////////////////////////////////////////////////////
+// Containers
+//////////////////////////////////////////////////////////////////////////////
+
+namespace boost {
+namespace container {
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class vector;
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class stable_vector;
+
+//vector class
+template <class T
+ ,class A = std::allocator<T> >
+class deque;
+
+//list class
+template <class T
+ ,class A = std::allocator<T> >
+class list;
+
+//slist class
+template <class T
+ ,class Alloc = std::allocator<T> >
+class slist;
+
+//set class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class set;
+
+//multiset class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class multiset;
+
+//map class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<const Key, T> > >
+class map;
+
+//multimap class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<const Key, T> > >
+class multimap;
+
+//flat_set class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class flat_set;
+
+//flat_multiset class
+template <class T
+ ,class Pred = std::less<T>
+ ,class Alloc = std::allocator<T> >
+class flat_multiset;
+
+//flat_map class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<Key, T> > >
+class flat_map;
+
+//flat_multimap class
+template <class Key
+ ,class T
+ ,class Pred = std::less<Key>
+ ,class Alloc = std::allocator<std::pair<Key, T> > >
+class flat_multimap;
+
+//basic_string class
+template <class CharT
+ ,class Traits = std::char_traits<CharT>
+ ,class Alloc = std::allocator<CharT> >
+class basic_string;
+
+//! Type used to tag that the input range is
+//! guaranteed to be ordered
+struct ordered_range_impl_t {};
+
+//! Type used to tag that the input range is
+//! guaranteed to be ordered and unique
+struct ordered_unique_range_impl_t{};
+
+/// @cond
+
+typedef ordered_range_impl_t * ordered_range_t;
+typedef ordered_unique_range_impl_t *ordered_unique_range_t;
+
+/// @endcond
+
+//! Value used to tag that the input range is
+//! guaranteed to be ordered
+static const ordered_range_t ordered_range = 0;
+
+//! Value used to tag that the input range is
+//! guaranteed to be ordered and unique
+static const ordered_unique_range_t ordered_unique_range = 0;
+
+/// @cond
+
+namespace detail_really_deep_namespace {
+
+//Otherwise, gcc issues a warning of previously defined
+//anonymous_instance and unique_instance
+struct dummy
+{
+ dummy()
+ {
+ (void)ordered_range;
+ (void)ordered_unique_range;
+ }
+};
+
+} //detail_really_deep_namespace {
+
+/// @endcond
+
+}} //namespace boost { namespace container {
+
+#endif //#ifndef BOOST_CONTAINERS_CONTAINERS_FWD_HPP

Modified: trunk/boost/interprocess/containers/container/deque.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/deque.hpp (original)
+++ trunk/boost/interprocess/containers/container/deque.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -55,7 +55,7 @@
 #include <boost/interprocess/containers/container/detail/iterators.hpp>
 #include <boost/interprocess/containers/container/detail/algorithms.hpp>
 #include <boost/interprocess/containers/container/detail/mpl.hpp>
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <cstddef>
 #include <iterator>
 #include <cassert>
@@ -71,12 +71,12 @@
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/interprocess/containers/container/detail/advanced_insert_int.hpp>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -89,8 +89,8 @@
    typedef T value_type;
    typedef A allocator_type;
    static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move =
- boost::interprocess::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_dctr_after_move = false;
+ //::boost::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;
@@ -494,6 +494,8 @@
 class deque : protected deque_base<T, Alloc>
 {
    /// @cond
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
   typedef deque_base<T, Alloc> Base;
 
    public: // Basic types
@@ -530,6 +532,7 @@
 
    /// @cond
    private: // Internal typedefs
+ BOOST_COPYABLE_AND_MOVABLE(deque)
    typedef ptr_alloc_ptr index_pointer;
    static std::size_t s_buffer_size()
       { return Base::s_buffer_size(); }
@@ -542,7 +545,6 @@
    allocator_type get_allocator() const { return Base::alloc(); }
 
    public: // Basic accessors
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(deque)
 
    iterator begin()
       { return this->members_.m_start; }
@@ -653,7 +655,7 @@
       priv_destroy_range(this->members_.m_start, this->members_.m_finish);
    }
 
- deque& operator= (const deque& x)
+ deque& operator= (BOOST_INTERPROCESS_COPY_ASSIGN_REF(deque) x)
    {
       const size_type len = size();
       if (&x != this) {
@@ -695,16 +697,16 @@
       this->priv_assign_dispatch(first, last, Result());
    }
 
- void push_back(const value_type& t)
- {
- if(this->priv_push_back_simple_available()){
- new(this->priv_push_back_simple_pos())value_type(t);
- this->priv_push_back_simple_commit();
- }
- else{
- this->priv_insert_aux(cend(), size_type(1), t);
- }
- }
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_back(T &x) { push_back(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_push_back(u); }
+ #endif
+
+ void push_back(insert_const_ref_type t)
+ { return priv_push_back(t); }
 
    void push_back(BOOST_INTERPROCESS_RV_REF(value_type) t)
    {
@@ -717,16 +719,16 @@
       }
    }
 
- void push_front(const value_type& t)
- {
- if(this->priv_push_front_simple_available()){
- new(this->priv_push_front_simple_pos())value_type(t);
- this->priv_push_front_simple_commit();
- }
- else{
- this->priv_insert_aux(cbegin(), size_type(1), t);
- }
- }
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_front(T &x) { push_front(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_front(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_push_front(u); }
+ #endif
+
+ void push_front(insert_const_ref_type t)
+ { return priv_push_front(t); }
 
    void push_front(BOOST_INTERPROCESS_RV_REF(value_type) t)
    {
@@ -759,22 +761,17 @@
          this->priv_pop_front_aux();
    }
 
- iterator insert(const_iterator position, const value_type& x)
- {
- if (position == cbegin()){
- this->push_front(x);
- return begin();
- }
- else if (position == cend()){
- this->push_back(x);
- return (end()-1);
- }
- else {
- size_type n = position - cbegin();
- this->priv_insert_aux(position, size_type(1), x);
- return iterator(this->begin() + n);
- }
- }
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
+
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
 
    iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(value_type) mx)
    {
@@ -807,7 +804,7 @@
       this->priv_insert_dispatch(pos, first, last, Result());
    }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    template <class... Args>
    void emplace_back(Args&&... args)
@@ -1048,6 +1045,46 @@
    /// @cond
    private:
 
+ iterator priv_insert(const_iterator position, const value_type &x)
+ {
+ if (position == cbegin()){
+ this->push_front(x);
+ return begin();
+ }
+ else if (position == cend()){
+ this->push_back(x);
+ return (end()-1);
+ }
+ else {
+ size_type n = position - cbegin();
+ this->priv_insert_aux(position, size_type(1), x);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ void priv_push_front(const value_type &t)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(t);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), size_type(1), t);
+ }
+ }
+
+ void priv_push_back(const value_type &t)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(t);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), size_type(1), t);
+ }
+ }
+
+
    bool priv_push_back_simple_available() const
    {
       return this->members_.m_map &&
@@ -1208,7 +1245,7 @@
          pos = this->members_.m_start + elemsbefore;
          if (elemsbefore >= difference_type(n)) {
             iterator start_n = this->members_.m_start + difference_type(n);
- boost::interprocess::uninitialized_move(this->members_.m_start, start_n, new_start);
+ ::boost::interprocess::uninitialized_move(this->members_.m_start, start_n, new_start);
             this->members_.m_start = new_start;
             boost::interprocess::move(start_n, pos, old_start);
             interf.copy_all_to(pos - difference_type(n));
@@ -1218,7 +1255,7 @@
             iterator mid_start = old_start - mid_count;
             interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
             this->members_.m_start = mid_start;
- boost::interprocess::uninitialized_move(old_start, pos, new_start);
+ ::boost::interprocess::uninitialized_move(old_start, pos, new_start);
             this->members_.m_start = new_start;
             interf.copy_all_to(old_start);
          }
@@ -1231,7 +1268,7 @@
          pos = this->members_.m_finish - elemsafter;
          if (elemsafter >= difference_type(n)) {
             iterator finish_n = this->members_.m_finish - difference_type(n);
- boost::interprocess::uninitialized_move(finish_n, this->members_.m_finish, this->members_.m_finish);
+ ::boost::interprocess::uninitialized_move(finish_n, this->members_.m_finish, this->members_.m_finish);
             this->members_.m_finish = new_finish;
             boost::interprocess::move_backward(pos, finish_n, old_finish);
             interf.copy_all_to(pos);
@@ -1239,7 +1276,7 @@
          else {
             interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
             this->members_.m_finish += n-elemsafter;
- boost::interprocess::uninitialized_move(pos, old_finish, this->members_.m_finish);
+ ::boost::interprocess::uninitialized_move(pos, old_finish, this->members_.m_finish);
             this->members_.m_finish = new_finish;
             interf.copy_all_to(pos);
          }
@@ -1299,10 +1336,10 @@
                ++cur_node) {
             FwdIt mid = first;
             std::advance(mid, this->s_buffer_size());
- boost::interprocess::uninitialized_copy_or_move(first, mid, *cur_node);
+ ::boost::interprocess::uninitialized_copy_or_move(first, mid, *cur_node);
             first = mid;
          }
- boost::interprocess::uninitialized_copy_or_move(first, last, this->members_.m_finish.m_first);
+ ::boost::interprocess::uninitialized_copy_or_move(first, last, this->members_.m_finish.m_first);
       }
       BOOST_CATCH(...){
          this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
@@ -1463,17 +1500,16 @@
 /// @cond
 
 namespace boost {
-namespace interprocess {
-
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::deque<T, A> >
+struct has_trivial_destructor_after_move<boost::container::deque<T, A> >
 {
    enum { value = has_trivial_destructor<A>::value };
 };
-
-}}
+*/
+}
 
 /// @endcond
 

Added: trunk/boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/adaptive_node_pool_impl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,638 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <boost/interprocess/containers/container/detail/math_functions.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/pool_common.hpp>
+#include <cassert>
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+struct hdr_offset_holder
+{
+ hdr_offset_holder(std::size_t offset = 0)
+ : hdr_offset(offset)
+ {}
+ std::size_t hdr_offset;
+};
+
+template<class VoidPointer>
+struct adaptive_pool_types
+{
+ typedef VoidPointer void_pointer;
+ typedef typename bi::make_set_base_hook
+ < bi::void_pointer<void_pointer>
+ , bi::optimize_size<true>
+ , bi::constant_time_size<false>
+ , bi::link_mode<bi::normal_link> >::type multiset_hook_t;
+
+ struct block_info_t
+ :
+ public hdr_offset_holder,
+ public multiset_hook_t
+ {
+ typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
+ //An intrusive list of free node from this block
+ free_nodes_t free_nodes;
+ friend bool operator <(const block_info_t &l, const block_info_t &r)
+ {
+// { return l.free_nodes.size() < r.free_nodes.size(); }
+ //Let's order blocks first by free nodes and then by address
+ //so that highest address fully free blocks are deallocated.
+ //This improves returning memory to the OS (trimming).
+ const bool is_less = l.free_nodes.size() < r.free_nodes.size();
+ const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
+ return is_less || (is_equal && (&l < &r));
+ }
+ };
+ typedef typename bi::make_multiset
+ <block_info_t, bi::base_hook<multiset_hook_t> >::type block_multiset_t;
+};
+
+
+inline std::size_t calculate_alignment
+ ( std::size_t overhead_percent, std::size_t real_node_size
+ , std::size_t hdr_size, std::size_t hdr_offset_size, std::size_t payload_per_allocation)
+{
+ //to-do: handle real_node_size != node_size
+ const std::size_t divisor = overhead_percent*real_node_size;
+ const std::size_t dividend = hdr_offset_size*100;
+ std::size_t elements_per_subblock = (dividend - 1)/divisor + 1;
+ std::size_t candidate_power_of_2 =
+ upper_power_of_2(elements_per_subblock*real_node_size + hdr_offset_size);
+ bool overhead_satisfied = false;
+ //Now calculate the wors-case overhead for a subblock
+ const std::size_t max_subblock_overhead = hdr_size + payload_per_allocation;
+ while(!overhead_satisfied){
+ elements_per_subblock = (candidate_power_of_2 - max_subblock_overhead)/real_node_size;
+ const std::size_t overhead_size = candidate_power_of_2 - elements_per_subblock*real_node_size;
+ if(overhead_size*100/candidate_power_of_2 < overhead_percent){
+ overhead_satisfied = true;
+ }
+ else{
+ candidate_power_of_2 <<= 1;
+ }
+ }
+ return candidate_power_of_2;
+}
+
+inline void calculate_num_subblocks
+ (std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_block
+ , std::size_t &num_subblocks, std::size_t &real_num_node, std::size_t overhead_percent
+ , std::size_t hdr_size, std::size_t hdr_offset_size, std::size_t payload_per_allocation)
+{
+ std::size_t elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
+ std::size_t possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
+ std::size_t hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
+ while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
+ ++possible_num_subblock;
+ }
+ elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
+ bool overhead_satisfied = false;
+ while(!overhead_satisfied){
+ const std::size_t total_data = (elements_per_subblock*(possible_num_subblock-1) + hdr_subblock_elements)*real_node_size;
+ const std::size_t total_size = alignment*possible_num_subblock;
+ if((total_size - total_data)*100/total_size < overhead_percent){
+ overhead_satisfied = true;
+ }
+ else{
+ ++possible_num_subblock;
+ }
+ }
+ num_subblocks = possible_num_subblock;
+ real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
+}
+
+template<class SegmentManagerBase, bool AlignOnly = false>
+class private_adaptive_node_pool_impl
+{
+ //Non-copyable
+ private_adaptive_node_pool_impl();
+ private_adaptive_node_pool_impl(const private_adaptive_node_pool_impl &);
+ private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
+ typedef private_adaptive_node_pool_impl this_type;
+
+ typedef typename SegmentManagerBase::void_pointer void_pointer;
+ static const std::size_t PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
+ typedef bool_<AlignOnly> IsAlignOnly;
+ typedef true_ AlignOnlyTrue;
+ typedef false_ AlignOnlyFalse;
+
+ public:
+ typedef typename node_slist<void_pointer>::node_t node_t;
+ typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
+
+ private:
+ typedef typename adaptive_pool_types<void_pointer>::block_info_t block_info_t;
+ typedef typename adaptive_pool_types<void_pointer>::block_multiset_t block_multiset_t;
+ typedef typename block_multiset_t::iterator block_iterator;
+
+ static const std::size_t MaxAlign = alignment_of<node_t>::value;
+ static const std::size_t HdrSize = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
+ static const std::size_t HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
+
+
+ public:
+ //!Segment manager typedef
+ typedef SegmentManagerBase segment_manager_base_type;
+
+ //!Constructor from a segment manager. Never throws
+ private_adaptive_node_pool_impl
+ ( segment_manager_base_type *segment_mngr_base
+ , std::size_t node_size
+ , std::size_t nodes_per_block
+ , std::size_t max_free_blocks
+ , unsigned char overhead_percent
+ )
+ : m_max_free_blocks(max_free_blocks)
+ , m_real_node_size(lcm(node_size, std::size_t(alignment_of<node_t>::value)))
+ //Round the size to a power of two value.
+ //This is the total memory size (including payload) that we want to
+ //allocate from the general-purpose allocator
+ , m_real_block_alignment
+ (AlignOnly ?
+ upper_power_of_2(HdrSize + m_real_node_size*nodes_per_block) :
+ calculate_alignment( overhead_percent, m_real_node_size
+ , HdrSize, HdrOffsetSize, PayloadPerAllocation))
+ //This is the real number of nodes per block
+ , m_num_subblocks(0)
+ , m_real_num_node(AlignOnly ? (m_real_block_alignment - PayloadPerAllocation - HdrSize)/m_real_node_size : 0)
+ //General purpose allocator
+ , mp_segment_mngr_base(segment_mngr_base)
+ , m_block_multiset()
+ , m_totally_free_blocks(0)
+ {
+ if(!AlignOnly){
+ calculate_num_subblocks
+ ( m_real_block_alignment
+ , m_real_node_size
+ , nodes_per_block
+ , m_num_subblocks
+ , m_real_num_node
+ , overhead_percent
+ , HdrSize
+ , HdrOffsetSize
+ , PayloadPerAllocation);
+ }
+ }
+
+ //!Destructor. Deallocates all allocated blocks. Never throws
+ ~private_adaptive_node_pool_impl()
+ { priv_clear(); }
+
+ std::size_t get_real_num_node() const
+ { return m_real_num_node; }
+
+ //!Returns the segment manager. Never throws
+ segment_manager_base_type* get_segment_manager_base()const
+ { return containers_detail::get_pointer(mp_segment_mngr_base); }
+
+ //!Allocates array of count elements. Can throw
+ void *allocate_node()
+ {
+ priv_invariants();
+ //If there are no free nodes we allocate a new block
+ if (m_block_multiset.empty()){
+ priv_alloc_block(1);
+ }
+ //We take the first free node the multiset can't be empty
+ return priv_take_first_node();
+ }
+
+ //!Deallocates an array pointed by ptr. Never throws
+ void deallocate_node(void *pElem)
+ {
+ multiallocation_chain chain;
+ chain.push_front(void_pointer(pElem));
+ this->priv_reinsert_nodes_in_block(chain, 1);
+ //Update free block count<
+ if(m_totally_free_blocks > m_max_free_blocks){
+ this->priv_deallocate_free_blocks(m_max_free_blocks);
+ }
+ priv_invariants();
+ }
+
+ //!Allocates n nodes.
+ //!Can throw
+ multiallocation_chain allocate_nodes(const std::size_t n)
+ {
+ multiallocation_chain chain;
+ std::size_t i = 0;
+ try{
+ priv_invariants();
+ while(i != n){
+ //If there are no free nodes we allocate all needed blocks
+ if (m_block_multiset.empty()){
+ priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
+ }
+ free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+ const std::size_t free_nodes_count_before = free_nodes.size();
+ if(free_nodes_count_before == m_real_num_node){
+ --m_totally_free_blocks;
+ }
+ const std::size_t num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
+ for(std::size_t j = 0; j != num_elems; ++j){
+ void *new_node = &free_nodes.front();
+ free_nodes.pop_front();
+ chain.push_back(new_node);
+ }
+
+ if(free_nodes.empty()){
+ m_block_multiset.erase(m_block_multiset.begin());
+ }
+ i += num_elems;
+ }
+ }
+ catch(...){
+ this->deallocate_nodes(boost::interprocess::move(chain));
+ throw;
+ }
+ priv_invariants();
+ return boost::interprocess::move(chain);
+ }
+
+ //!Deallocates a linked list of nodes. Never throws
+ void deallocate_nodes(multiallocation_chain nodes)
+ {
+ this->priv_reinsert_nodes_in_block(nodes, nodes.size());
+ if(m_totally_free_blocks > m_max_free_blocks){
+ this->priv_deallocate_free_blocks(m_max_free_blocks);
+ }
+ }
+
+ void deallocate_free_blocks()
+ { this->priv_deallocate_free_blocks(0); }
+
+ std::size_t num_free_nodes()
+ {
+ typedef typename block_multiset_t::const_iterator citerator;
+ std::size_t count = 0;
+ citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
+ for(; it != itend; ++it){
+ count += it->free_nodes.size();
+ }
+ return count;
+ }
+
+ void swap(private_adaptive_node_pool_impl &other)
+ {
+ assert(m_max_free_blocks == other.m_max_free_blocks);
+ assert(m_real_node_size == other.m_real_node_size);
+ assert(m_real_block_alignment == other.m_real_block_alignment);
+ assert(m_real_num_node == other.m_real_num_node);
+ std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+ std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
+ m_block_multiset.swap(other.m_block_multiset);
+ }
+
+ //Deprecated, use deallocate_free_blocks
+ void deallocate_free_chunks()
+ { this->priv_deallocate_free_blocks(0); }
+
+ private:
+ void priv_deallocate_free_blocks(std::size_t max_free_blocks)
+ {
+ priv_invariants();
+ //Now check if we've reached the free nodes limit
+ //and check if we have free blocks. If so, deallocate as much
+ //as we can to stay below the limit
+ for( block_iterator itend = m_block_multiset.end()
+ ; m_totally_free_blocks > max_free_blocks
+ ; --m_totally_free_blocks
+ ){
+ assert(!m_block_multiset.empty());
+ block_iterator it = itend;
+ --it;
+ assert(it->free_nodes.size() == m_real_num_node);
+ m_block_multiset.erase_and_dispose(it, block_destroyer(this));
+ }
+ }
+
+ void priv_reinsert_nodes_in_block(multiallocation_chain &chain, std::size_t n)
+ {
+ block_iterator block_it(m_block_multiset.end());
+ while(n--){
+ void *pElem = containers_detail::get_pointer(chain.front());
+ chain.pop_front();
+ priv_invariants();
+ block_info_t *block_info = this->priv_block_from_node(pElem);
+ assert(block_info->free_nodes.size() < m_real_num_node);
+ //We put the node at the beginning of the free node list
+ node_t * to_deallocate = static_cast<node_t*>(pElem);
+ block_info->free_nodes.push_front(*to_deallocate);
+
+ block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
+ block_iterator next_block(this_block);
+ ++next_block;
+
+ //Cache the free nodes from the block
+ std::size_t this_block_free_nodes = this_block->free_nodes.size();
+
+ if(this_block_free_nodes == 1){
+ m_block_multiset.insert(m_block_multiset.begin(), *block_info);
+ }
+ else{
+ block_iterator next_block(this_block);
+ ++next_block;
+ if(next_block != block_it){
+ std::size_t next_free_nodes = next_block->free_nodes.size();
+ if(this_block_free_nodes > next_free_nodes){
+ //Now move the block to the new position
+ m_block_multiset.erase(this_block);
+ m_block_multiset.insert(*block_info);
+ }
+ }
+ }
+ //Update free block count
+ if(this_block_free_nodes == m_real_num_node){
+ ++m_totally_free_blocks;
+ }
+ priv_invariants();
+ }
+ }
+
+ node_t *priv_take_first_node()
+ {
+ assert(m_block_multiset.begin() != m_block_multiset.end());
+ //We take the first free node the multiset can't be empty
+ free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+ node_t *first_node = &free_nodes.front();
+ const std::size_t free_nodes_count = free_nodes.size();
+ assert(0 != free_nodes_count);
+ free_nodes.pop_front();
+ if(free_nodes_count == 1){
+ m_block_multiset.erase(m_block_multiset.begin());
+ }
+ else if(free_nodes_count == m_real_num_node){
+ --m_totally_free_blocks;
+ }
+ priv_invariants();
+ return first_node;
+ }
+
+ class block_destroyer;
+ friend class block_destroyer;
+
+ class block_destroyer
+ {
+ public:
+ block_destroyer(const this_type *impl)
+ : mp_impl(impl)
+ {}
+
+ void operator()(typename block_multiset_t::pointer to_deallocate)
+ { return this->do_destroy(to_deallocate, IsAlignOnly()); }
+
+ private:
+ void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyTrue)
+ {
+ std::size_t free_nodes = to_deallocate->free_nodes.size();
+ (void)free_nodes;
+ assert(free_nodes == mp_impl->m_real_num_node);
+ mp_impl->mp_segment_mngr_base->deallocate(to_deallocate);
+ }
+
+ void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyFalse)
+ {
+ std::size_t free_nodes = to_deallocate->free_nodes.size();
+ (void)free_nodes;
+ assert(free_nodes == mp_impl->m_real_num_node);
+ assert(0 == to_deallocate->hdr_offset);
+ hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(containers_detail::get_pointer(to_deallocate));
+ mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
+ }
+
+ const this_type *mp_impl;
+ };
+
+ //This macro will activate invariant checking. Slow, but helpful for debugging the code.
+ //#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ void priv_invariants()
+ #ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ #undef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ {
+ //We iterate through the block tree to free the memory
+ block_iterator it(m_block_multiset.begin()),
+ itend(m_block_multiset.end()), to_deallocate;
+ if(it != itend){
+ for(++it; it != itend; ++it){
+ block_iterator prev(it);
+ --prev;
+ std::size_t sp = prev->free_nodes.size(),
+ si = it->free_nodes.size();
+ assert(sp <= si);
+ (void)sp; (void)si;
+ }
+ }
+ //Check that the total free nodes are correct
+ it = m_block_multiset.begin();
+ itend = m_block_multiset.end();
+ std::size_t total_free_nodes = 0;
+ for(; it != itend; ++it){
+ total_free_nodes += it->free_nodes.size();
+ }
+ assert(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+
+ //Check that the total totally free blocks are correct
+ it = m_block_multiset.begin();
+ itend = m_block_multiset.end();
+ total_free = 0;
+ for(; it != itend; ++it){
+ total_free += it->free_nodes.size() == m_real_num_node;
+ }
+ assert(total_free >= m_totally_free_blocks);
+
+ if(!AlignOnly){
+ //Check that header offsets are correct
+ it = m_block_multiset.begin();
+ for(; it != itend; ++it){
+ hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
+ for(std::size_t i = 0, max = m_num_subblocks; i < max; ++i){
+ assert(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
+ assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+ hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
+ }
+ }
+ }
+ }
+ #else
+ {} //empty
+ #endif
+
+ //!Deallocates all used memory. Never throws
+ void priv_clear()
+ {
+ #ifndef NDEBUG
+ block_iterator it = m_block_multiset.begin();
+ block_iterator itend = m_block_multiset.end();
+ std::size_t num_free_nodes = 0;
+ for(; it != itend; ++it){
+ //Check for memory leak
+ assert(it->free_nodes.size() == m_real_num_node);
+ ++num_free_nodes;
+ }
+ assert(num_free_nodes == m_totally_free_blocks);
+ #endif
+ //Check for memory leaks
+ priv_invariants();
+ m_block_multiset.clear_and_dispose(block_destroyer(this));
+ m_totally_free_blocks = 0;
+ }
+
+ block_info_t *priv_block_from_node(void *node, AlignOnlyFalse) const
+ {
+ hdr_offset_holder *hdr_off_holder =
+ reinterpret_cast<hdr_offset_holder*>((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
+ assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+ block_info_t *block = reinterpret_cast<block_info_t *>
+ (reinterpret_cast<char*>(hdr_off_holder) + hdr_off_holder->hdr_offset);
+ assert(block->hdr_offset == 0);
+ return block;
+ }
+
+ block_info_t *priv_block_from_node(void *node, AlignOnlyTrue) const
+ {
+ return (block_info_t *)((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
+ }
+
+ block_info_t *priv_block_from_node(void *node) const
+ { return priv_block_from_node(node, IsAlignOnly()); }
+
+ hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
+ {
+ hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
+ (reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
+ assert(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
+ assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+ return hdr_off_holder;
+ }
+
+ //!Allocates a several blocks of nodes. Can throw
+ void priv_alloc_block(std::size_t n, AlignOnlyTrue)
+ {
+ std::size_t real_block_size = m_real_block_alignment - PayloadPerAllocation;
+ for(std::size_t i = 0; i != n; ++i){
+ //We allocate a new NodeBlock and put it the last
+ //element of the tree
+ char *mem_address = static_cast<char*>
+ (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
+ if(!mem_address) throw std::bad_alloc();
+ ++m_totally_free_blocks;
+ block_info_t *c_info = new(mem_address)block_info_t;
+ m_block_multiset.insert(m_block_multiset.end(), *c_info);
+
+ mem_address += HdrSize;
+ //We initialize all Nodes in Node Block to insert
+ //them in the free Node list
+ typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
+ for(std::size_t i = 0; i < m_real_num_node; ++i){
+ prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *(node_t*)mem_address);
+ mem_address += m_real_node_size;
+ }
+ }
+ }
+
+ void priv_alloc_block(std::size_t n, AlignOnlyFalse)
+ {
+ std::size_t real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
+ std::size_t elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
+ std::size_t hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+
+ for(std::size_t i = 0; i != n; ++i){
+ //We allocate a new NodeBlock and put it the last
+ //element of the tree
+ char *mem_address = static_cast<char*>
+ (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
+ if(!mem_address) throw std::bad_alloc();
+ ++m_totally_free_blocks;
+
+ //First initialize header information on the last subblock
+ char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
+ block_info_t *c_info = new(hdr_addr)block_info_t;
+ //Some structural checks
+ assert(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
+ static_cast<void*>(c_info));
+ typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
+ for( std::size_t subblock = 0, maxsubblock = m_num_subblocks - 1
+ ; subblock < maxsubblock
+ ; ++subblock, mem_address += m_real_block_alignment){
+ //Initialize header offset mark
+ new(mem_address) hdr_offset_holder(std::size_t(hdr_addr - mem_address));
+ char *pNode = mem_address + HdrOffsetSize;
+ for(std::size_t i = 0; i < elements_per_subblock; ++i){
+ prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
+ pNode += m_real_node_size;
+ }
+ }
+ {
+ char *pNode = hdr_addr + HdrSize;
+ //We initialize all Nodes in Node Block to insert
+ //them in the free Node list
+ for(std::size_t i = 0; i < hdr_subblock_elements; ++i){
+ prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
+ pNode += m_real_node_size;
+ }
+ }
+ //Insert the block after the free node list is full
+ m_block_multiset.insert(m_block_multiset.end(), *c_info);
+ }
+ }
+
+ //!Allocates a block of nodes. Can throw std::bad_alloc
+ void priv_alloc_block(std::size_t n)
+ { return priv_alloc_block(n, IsAlignOnly()); }
+
+ private:
+ typedef typename boost::pointer_to_other
+ <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
+ const std::size_t m_max_free_blocks;
+ const std::size_t m_real_node_size;
+ //Round the size to a power of two value.
+ //This is the total memory size (including payload) that we want to
+ //allocate from the general-purpose allocator
+ const std::size_t m_real_block_alignment;
+ std::size_t m_num_subblocks;
+ //This is the real number of nodes per block
+ //const
+ std::size_t m_real_num_node;
+ segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
+ block_multiset_t m_block_multiset; //Intrusive block list
+ std::size_t m_totally_free_blocks; //Free blocks
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP

Modified: trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/advanced_insert_int.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -23,7 +23,7 @@
 #include <new> //placement new
 #include <cassert>
 
-namespace boost { namespace interprocess_container { namespace containers_detail {
+namespace boost { namespace container { namespace containers_detail {
 
 //This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
 template<class T, class Iterator>
@@ -54,18 +54,18 @@
    { std::copy(first_, last_, p); }
 
    virtual void uninitialized_copy_all_to(Iterator p)
- { boost::interprocess::uninitialized_copy_or_move(first_, last_, p); }
+ { ::boost::interprocess::uninitialized_copy_or_move(first_, last_, p); }
 
    virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
    {
       FwdIt mid = first_;
       std::advance(mid, division_count);
       if(first_n){
- boost::interprocess::uninitialized_copy_or_move(first_, mid, pos);
+ ::boost::interprocess::uninitialized_copy_or_move(first_, mid, pos);
          first_ = mid;
       }
       else{
- boost::interprocess::uninitialized_copy_or_move(mid, last_, pos);
+ ::boost::interprocess::uninitialized_copy_or_move(mid, last_, pos);
          last_ = mid;
       }
    }
@@ -159,7 +159,7 @@
    SizeType count_;
 };
 
-}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+}}} //namespace boost { namespace container { namespace containers_detail {
 
 #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
 
@@ -169,7 +169,7 @@
 //#include <iostream> //For debugging purposes
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 //This class template will adapt each FwIt types to advanced_insert_aux_int
@@ -247,7 +247,7 @@
    bool used_;
 };
 
-}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+}}} //namespace boost { namespace container { namespace containers_detail {
 
 #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
 
@@ -255,7 +255,7 @@
 #include <boost/interprocess/containers/container/detail/value_init.hpp>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 //This class template will adapt each FwIt types to advanced_insert_aux_int
@@ -377,7 +377,7 @@
 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
 #include BOOST_PP_LOCAL_ITERATE()
 
-}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+}}} //namespace boost { namespace container { namespace containers_detail {
 
 #endif //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
 

Modified: trunk/boost/interprocess/containers/container/detail/algorithms.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/algorithms.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -33,7 +33,7 @@
 #include <cstring>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 
 #if !defined(BOOST_HAS_RVALUE_REFS)
 template<class T>
@@ -206,7 +206,7 @@
    BOOST_CATCH_END
 }
 
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/allocation_type.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/allocation_type.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/allocation_type.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -19,7 +19,7 @@
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 
 /// @cond
 enum allocation_type_v
@@ -46,7 +46,7 @@
 static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
 static const allocation_type zero_memory = (allocation_type)zero_memory_v;
 
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/config_begin.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/config_begin.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/config_begin.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/containers/container/detail/config_end.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/config_end.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/config_end.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/containers/container/detail/destroyers.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/destroyers.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/destroyers.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -23,7 +23,7 @@
 #include <boost/interprocess/containers/container/detail/utilities.hpp>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 //!A deleter for scoped_ptr that deallocates the memory
@@ -117,7 +117,7 @@
 {
    typedef typename A::value_type value_type;
    typedef containers_detail::integral_constant<unsigned,
- boost::interprocess_container::containers_detail::
+ boost::container::containers_detail::
          version<A>::value> alloc_version;
    typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
    typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
@@ -146,7 +146,7 @@
 
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/flat_tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/flat_tree.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/flat_tree.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -35,6 +35,8 @@
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
+#include <boost/interprocess/containers/container/container_fwd.hpp>
+
 #include <algorithm>
 #include <functional>
 #include <utility>
@@ -50,7 +52,7 @@
 
 namespace boost {
 
-namespace interprocess_container {
+namespace container {
 
 namespace containers_detail {
 
@@ -58,7 +60,7 @@
           class Compare, class Alloc>
 class flat_tree
 {
- typedef boost::interprocess_container::vector<Value, Alloc> vector_t;
+ typedef boost::container::vector<Value, Alloc> vector_t;
    typedef Alloc allocator_t;
 
    public:
@@ -91,7 +93,12 @@
       //Inherit from value_compare to do EBO
       : public value_compare
    {
- public:
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(Data)
+ public:
+ Data(const Data &d)
+ : value_compare(d), m_vect(d.m_vect)
+ {}
       Data(const Compare &comp,
            const vector_t &vect)
          : value_compare(comp), m_vect(vect){}
@@ -103,14 +110,28 @@
       Data(const Compare &comp,
            const allocator_t &alloc)
          : value_compare(comp), m_vect(alloc){}
- public:
+
+ Data& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(Data) d)
+ {
+ value_compare::operator=(d);
+ m_vect = d.m_vect;
+ return *this;
+ }
+
+ Data& operator=(BOOST_INTERPROCESS_RV_REF(Data) d)
+ {
+ value_compare::operator=(boost::interprocess::move(static_cast<value_compare &>(d)));
+ m_vect = boost::interprocess::move(d.m_vect);
+ return *this;
+ }
+
       vector_t m_vect;
    };
 
    Data m_data;
+ BOOST_COPYABLE_AND_MOVABLE(flat_tree)
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_tree)
 
    typedef typename vector_t::value_type value_type;
    typedef typename vector_t::pointer pointer;
@@ -143,10 +164,17 @@
       : m_data(boost::interprocess::move(x.m_data))
    { }
 
+ template <class InputIterator>
+ flat_tree( ordered_range_t, InputIterator first, InputIterator last
+ , const Compare& comp = Compare()
+ , const allocator_type& a = allocator_type())
+ : m_data(comp, a)
+ { this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
+
    ~flat_tree()
    { }
 
- flat_tree& operator=(const flat_tree& x)
+ flat_tree& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(flat_tree) x)
    { m_data = x.m_data; return *this; }
 
    flat_tree& operator=(BOOST_INTERPROCESS_RV_REF(flat_tree) mx)
@@ -815,21 +843,17 @@
 
 } //namespace containers_detail {
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class V, class KOV,
 class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::containers_detail::flat_tree<K, V, KOV, C, A> >
+struct has_trivial_destructor_after_move<boost::container::containers_detail::flat_tree<K, V, KOV, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
+*/
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/iterators.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/iterators.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/iterators.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
@@ -31,7 +31,7 @@
 #include <iterator>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 
 template <class T, class Difference = std::ptrdiff_t>
 class constant_iterator
@@ -483,7 +483,7 @@
 
 #endif
 
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Added: trunk/boost/interprocess/containers/container/detail/math_functions.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/math_functions.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,110 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Stephen Cleary 2000.
+// (C) Copyright Ion Gaztanaga 2007-2009.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+// This file is a slightly modified file from Boost.Pool
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+
+#include <climits>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+// Greatest common divisor and least common multiple
+
+//
+// gcd is an algorithm that calculates the greatest common divisor of two
+// integers, using Euclid's algorithm.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer gcd(Integer A, Integer B)
+{
+ do
+ {
+ const Integer tmp(B);
+ B = A % B;
+ A = tmp;
+ } while (B != 0);
+
+ return A;
+}
+
+//
+// lcm is an algorithm that calculates the least common multiple of two
+// integers.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer lcm(const Integer & A, const Integer & B)
+{
+ Integer ret = A;
+ ret /= gcd(A, B);
+ ret *= B;
+ return ret;
+}
+
+template <typename Integer>
+inline Integer log2_ceil(const Integer & A)
+{
+ Integer i = 0;
+ Integer power_of_2 = 1;
+
+ while(power_of_2 < A){
+ power_of_2 <<= 1;
+ ++i;
+ }
+ return i;
+}
+
+template <typename Integer>
+inline Integer upper_power_of_2(const Integer & A)
+{
+ Integer power_of_2 = 1;
+
+ while(power_of_2 < A){
+ power_of_2 <<= 1;
+ }
+ return power_of_2;
+}
+
+//This function uses binary search to discover the
+//highest set bit of the integer
+inline std::size_t floor_log2 (std::size_t x)
+{
+ const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
+ const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
+ BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
+
+ std::size_t n = x;
+ std::size_t log2 = 0;
+
+ for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
+ std::size_t tmp = n >> shift;
+ if (tmp)
+ log2 += shift, n = tmp;
+ }
+
+ return log2;
+}
+
+} // namespace containers_detail
+} // namespace container
+} // namespace boost
+
+#endif

Modified: trunk/boost/interprocess/containers/container/detail/mpl.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/mpl.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/mpl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,7 +20,7 @@
 #include <cstddef>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template <class T, T val>
@@ -145,7 +145,7 @@
 };
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_MPL_HPP

Modified: trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/multiallocation_chain.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -12,423 +12,122 @@
 #define BOOST_CONTAINERS_DETAIL_MULTIALLOCATION_CHAIN_HPP
 
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <boost/interprocess/containers/container/detail/utilities.hpp>
 #include <boost/interprocess/containers/container/detail/type_traits.hpp>
 #include <boost/interprocess/containers/container/detail/transform_iterator.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/interprocess/detail/move.hpp>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template<class VoidPointer>
-class basic_multiallocation_slist
+class basic_multiallocation_chain
 {
-public:
- typedef VoidPointer void_pointer;
+ private:
+ typedef bi::slist_base_hook<bi::void_pointer<VoidPointer>
+ ,bi::link_mode<bi::normal_link>
+ > node;
+
+ typedef bi::slist< node
+ , bi::linear<true>
+ , bi::cache_last<true>
+ > slist_impl_t;
+ slist_impl_t slist_impl_;
 
-private:
- static VoidPointer &priv_get_ref(const VoidPointer &p)
- { return *static_cast<void_pointer*>(containers_detail::get_pointer(p)); }
-
- basic_multiallocation_slist(basic_multiallocation_slist &);
- basic_multiallocation_slist &operator=(basic_multiallocation_slist &);
-
-public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_slist)
-
- //!This iterator is returned by "allocate_many" functions so that
- //!the user can access the multiple buffers allocated in a single call
- class iterator
- : public std::iterator<std::input_iterator_tag, char>
- {
- friend class basic_multiallocation_slist<void_pointer>;
- void unspecified_bool_type_func() const {}
- typedef void (iterator::*unspecified_bool_type)() const;
-
- iterator(void_pointer node_range)
- : next_node_(node_range)
- {}
+ static node & to_node(VoidPointer p)
+ { return *static_cast<node*>(static_cast<void*>(containers_detail::get_pointer(p))); }
 
- public:
- typedef char value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
-
- iterator()
- : next_node_(0)
- {}
-
- iterator &operator=(const iterator &other)
- { next_node_ = other.next_node_; return *this; }
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
 
    public:
- iterator& operator++()
- {
- next_node_ = *static_cast<void_pointer*>(containers_detail::get_pointer(next_node_));
- return *this;
- }
-
- iterator operator++(int)
- {
- iterator result(*this);
- ++*this;
- return result;
- }
-
- bool operator== (const iterator& other) const
- { return next_node_ == other.next_node_; }
-
- bool operator!= (const iterator& other) const
- { return !operator== (other); }
-
- reference operator*() const
- { return *static_cast<char*>(containers_detail::get_pointer(next_node_)); }
-
- operator unspecified_bool_type() const
- { return next_node_? &iterator::unspecified_bool_type_func : 0; }
-
- pointer operator->() const
- { return &(*(*this)); }
-
- private:
- void_pointer next_node_;
- };
 
-private:
- iterator it_;
 
-public:
- basic_multiallocation_slist()
- : it_(iterator())
- {}
+ typedef VoidPointer void_pointer;
+ typedef typename slist_impl_t::iterator iterator;
 
- basic_multiallocation_slist(void_pointer p)
- : it_(p ? iterator_to(p) : iterator())
+ basic_multiallocation_chain()
+ : slist_impl_()
    {}
 
- basic_multiallocation_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
- : it_(iterator())
- { this->swap(other); }
+ basic_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_chain) other)
+ : slist_impl_()
+ { slist_impl_.swap(other.slist_impl_); }
 
- basic_multiallocation_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
+ basic_multiallocation_chain& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_chain) other)
    {
- basic_multiallocation_slist tmp(boost::interprocess::move(other));
+ basic_multiallocation_chain tmp(boost::interprocess::move(other));
       this->swap(tmp);
       return *this;
    }
 
    bool empty() const
- { return !it_; }
-
- iterator before_begin() const
- { return iterator(void_pointer(const_cast<void*>(static_cast<const void*>(&it_.next_node_)))); }
-
- iterator begin() const
- { return it_; }
-
- iterator end() const
- { return iterator(); }
-
- void clear()
- { this->it_.next_node_ = void_pointer(0); }
-
- iterator insert_after(iterator it, void_pointer m)
- {
- priv_get_ref(m) = priv_get_ref(it.next_node_);
- priv_get_ref(it.next_node_) = m;
- return iterator(m);
- }
-
- void push_front(void_pointer m)
- {
- priv_get_ref(m) = this->it_.next_node_;
- this->it_.next_node_ = m;
- }
-
- void pop_front()
- { ++it_; }
-
- void *front() const
- { return containers_detail::get_pointer(it_.next_node_); }
-
- void splice_after(iterator after_this, iterator before_begin, iterator before_end)
- {
- if (after_this != before_begin && after_this != before_end && before_begin != before_end) {
- void_pointer next_b = priv_get_ref(before_begin.next_node_);
- void_pointer next_e = priv_get_ref(before_end.next_node_);
- void_pointer next_p = priv_get_ref(after_this.next_node_);
- priv_get_ref(before_begin.next_node_) = next_e;
- priv_get_ref(before_end.next_node_) = next_p;
- priv_get_ref(after_this.next_node_) = next_b;
- }
- }
-
- void swap(basic_multiallocation_slist &other_chain)
- {
- std::swap(this->it_, other_chain.it_);
- }
-
- static iterator iterator_to(void_pointer p)
- { return iterator(p); }
+ { return slist_impl_.empty(); }
 
- void_pointer extract_data()
- {
- void_pointer ret = empty() ? void_pointer(0) : void_pointer(&*it_);
- it_ = iterator();
- return ret;
- }
-};
-
-template<class VoidPointer>
-class basic_multiallocation_cached_slist
-{
-private:
- basic_multiallocation_slist<VoidPointer> slist_;
- typename basic_multiallocation_slist<VoidPointer>::iterator last_;
-
- basic_multiallocation_cached_slist(basic_multiallocation_cached_slist &);
- basic_multiallocation_cached_slist &operator=(basic_multiallocation_cached_slist &);
-
-public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_slist)
-
- typedef typename basic_multiallocation_slist<VoidPointer>::void_pointer void_pointer;
- typedef typename basic_multiallocation_slist<VoidPointer>::iterator iterator;
-
- basic_multiallocation_cached_slist()
- : slist_(), last_(slist_.before_begin())
- {}
- /*
- basic_multiallocation_cached_slist(iterator first_node)
- : slist_(first_node), last_(slist_.before_begin())
- {
- iterator end;
- while(first_node != end){
- ++last_;
- }
- }*/
-
- basic_multiallocation_cached_slist(void_pointer p1, void_pointer p2)
- : slist_(p1), last_(p2 ? iterator_to(p2) : slist_.before_begin())
- {}
-
- basic_multiallocation_cached_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
- : slist_(), last_(slist_.before_begin())
- { this->swap(other); }
-
- basic_multiallocation_cached_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
- {
- basic_multiallocation_cached_slist tmp(boost::interprocess::move(other));
- this->swap(tmp);
- return *this;
- }
-
- bool empty() const
- { return slist_.empty(); }
+ std::size_t size() const
+ { return slist_impl_.size(); }
 
- iterator before_begin() const
- { return slist_.before_begin(); }
+ iterator before_begin()
+ { return slist_impl_.before_begin(); }
 
- iterator begin() const
- { return slist_.begin(); }
+ iterator begin()
+ { return slist_impl_.begin(); }
 
- iterator end() const
- { return slist_.end(); }
+ iterator end()
+ { return slist_impl_.end(); }
 
- iterator last() const
- { return last_; }
+ iterator last()
+ { return slist_impl_.last(); }
 
    void clear()
- {
- slist_.clear();
- last_ = slist_.before_begin();
- }
+ { slist_impl_.clear(); }
 
    iterator insert_after(iterator it, void_pointer m)
- {
- slist_.insert_after(it, m);
- if(it == last_){
- last_ = slist_.iterator_to(m);
- }
- return iterator_to(m);
- }
+ { return slist_impl_.insert_after(it, to_node(m)); }
 
    void push_front(void_pointer m)
- { this->insert_after(this->before_begin(), m); }
+ { return slist_impl_.push_front(to_node(m)); }
 
    void push_back(void_pointer m)
- { this->insert_after(last_, m); }
+ { return slist_impl_.push_back(to_node(m)); }
 
    void pop_front()
- {
- if(last_ == slist_.begin()){
- last_ = slist_.before_begin();
- }
- slist_.pop_front();
- }
-
- void *front() const
- { return slist_.front(); }
-
- void splice_after(iterator after_this, iterator before_begin, iterator before_end)
- {
- if(before_begin == before_end)
- return;
- if(after_this == last_){
- last_ = before_end;
- }
- slist_.splice_after(after_this, before_begin, before_end);
- }
-
- void swap(basic_multiallocation_cached_slist &x)
- {
- slist_.swap(x.slist_);
- using std::swap;
- swap(last_, x.last_);
- if(last_ == x.before_begin()){
- last_ = this->before_begin();
- }
- if(x.last_ == this->before_begin()){
- x.last_ = x.before_begin();
- }
- }
-
- static iterator iterator_to(void_pointer p)
- { return basic_multiallocation_slist<VoidPointer>::iterator_to(p); }
-
- std::pair<void_pointer, void_pointer> extract_data()
- {
- if(this->empty()){
- return std::pair<void_pointer, void_pointer>(void_pointer(0), void_pointer(0));
- }
- else{
- void_pointer p1 = slist_.extract_data();
- void_pointer p2 = void_pointer(&*last_);
- last_ = iterator();
- return std::pair<void_pointer, void_pointer>(p1, p2);
- }
- }
-};
-
-template<class MultiallocatorCachedSlist>
-class basic_multiallocation_cached_counted_slist
-{
-private:
- MultiallocatorCachedSlist cached_slist_;
- std::size_t size_;
-
- basic_multiallocation_cached_counted_slist(basic_multiallocation_cached_counted_slist &);
- basic_multiallocation_cached_counted_slist &operator=(basic_multiallocation_cached_counted_slist &);
-
-public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_counted_slist)
-
- typedef typename MultiallocatorCachedSlist::void_pointer void_pointer;
- typedef typename MultiallocatorCachedSlist::iterator iterator;
-
- basic_multiallocation_cached_counted_slist()
- : cached_slist_(), size_(0)
- {}
-
- basic_multiallocation_cached_counted_slist(void_pointer p1, void_pointer p2, std::size_t n)
- : cached_slist_(p1, p2), size_(n)
- {}
-
- basic_multiallocation_cached_counted_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
- : cached_slist_(), size_(0)
- { this->swap(other); }
-
- basic_multiallocation_cached_counted_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
- {
- basic_multiallocation_cached_counted_slist tmp(boost::interprocess::move(other));
- this->swap(tmp);
- return *this;
- }
-
- basic_multiallocation_cached_counted_slist (MultiallocatorCachedSlist mem, std::size_t n)
- : cached_slist_(boost::interprocess::move(mem)), size_(n)
- {}
-
- bool empty() const
- { return cached_slist_.empty(); }
-
- std::size_t size() const
- { return size_; }
-
- iterator before_begin() const
- { return cached_slist_.before_begin(); }
-
- iterator begin() const
- { return cached_slist_.begin(); }
+ { return slist_impl_.pop_front(); }
 
- iterator end() const
- { return cached_slist_.end(); }
+ void *front()
+ { return &*slist_impl_.begin(); }
 
- iterator last() const
- { return cached_slist_.last(); }
+ void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
+ { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end); }
 
- void clear()
- {
- cached_slist_.clear();
- size_ = 0;
- }
-
- iterator insert_after(iterator it, void_pointer m)
- {
- iterator ret = cached_slist_.insert_after(it, m);
- ++size_;
- return ret;
- }
-
- void push_front(void_pointer m)
- { this->insert_after(this->before_begin(), m); }
+ void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
+ { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end, n); }
 
- void push_back(void_pointer m)
- { this->insert_after(this->before_begin(), m); }
+ void splice_after(iterator after_this, basic_multiallocation_chain &x)
+ { slist_impl_.splice_after(after_this, x.slist_impl_); }
 
- void pop_front()
- {
- cached_slist_.pop_front();
- --size_;
- }
+ void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
+ { slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end)); }
 
- void *front() const
- { return cached_slist_.front(); }
+ void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, std::size_t n)
+ { slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n); }
 
- void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end)
- {
- std::size_t n = static_cast<std::size_t>(std::distance(before_begin, before_end));
- this->splice_after(after_this, x, before_begin, before_end, n);
- }
-
- void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end, std::size_t n)
- {
- cached_slist_.splice_after(after_this, before_begin, before_end);
- size_ += n;
- x.size_ -= n;
- }
-
- void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x)
- {
- cached_slist_.splice_after(after_this, x.before_begin(), x.last());
- size_ += x.size_;
- x.size_ = 0;
- }
-
- void swap(basic_multiallocation_cached_counted_slist &x)
- {
- cached_slist_.swap(x.cached_slist_);
- using std::swap;
- swap(size_, x.size_);
- }
+ void swap(basic_multiallocation_chain &x)
+ { slist_impl_.swap(x.slist_impl_); }
 
    static iterator iterator_to(void_pointer p)
- { return MultiallocatorCachedSlist::iterator_to(p); }
+ { return slist_impl_t::s_iterator_to(to_node(p)); }
 
    std::pair<void_pointer, void_pointer> extract_data()
    {
- size_ = 0;
- return cached_slist_.extract_data();
+ std::pair<void_pointer, void_pointer> ret
+ (slist_impl_.begin().operator->()
+ ,slist_impl_.last().operator->());
+ slist_impl_.clear();
+ return ret;
    }
 };
 
@@ -436,40 +135,32 @@
 struct cast_functor
 {
    typedef typename containers_detail::add_reference<T>::type result_type;
- result_type operator()(char &ptr) const
+ template<class U>
+ result_type operator()(U &ptr) const
    { return *static_cast<T*>(static_cast<void*>(&ptr)); }
 };
 
-
 template<class MultiallocationChain, class T>
 class transform_multiallocation_chain
 {
-private:
+ private:
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
 
    MultiallocationChain holder_;
    typedef typename MultiallocationChain::void_pointer void_pointer;
    typedef typename boost::pointer_to_other
       <void_pointer, T>::type pointer;
 
- transform_multiallocation_chain(transform_multiallocation_chain &);
- transform_multiallocation_chain &operator=(transform_multiallocation_chain &);
-
    static pointer cast(void_pointer p)
    {
       return pointer(static_cast<T*>(containers_detail::get_pointer(p)));
    }
 
-public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(transform_multiallocation_chain)
-
- typedef transform_iterator
+ public:
+ typedef transform_iterator
       < typename MultiallocationChain::iterator
       , containers_detail::cast_functor <T> > iterator;
 
- transform_multiallocation_chain(void_pointer p1, void_pointer p2, std::size_t n)
- : holder_(p1, p2, n)
- {}
-
    transform_multiallocation_chain()
       : holder_()
    {}
@@ -494,32 +185,32 @@
 
    void swap(transform_multiallocation_chain &other_chain)
    { holder_.swap(other_chain.holder_); }
- /*
- void splice_after(iterator after_this, iterator before_begin, iterator before_end)
- { holder_.splice_after(after_this.base(), before_begin.base(), before_end.base()); }
- */
+
    void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
    { holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
 
+ void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, std::size_t n)
+ { holder_.incorporate_after(after_this.base(), begin, before_end, n); }
+
    void pop_front()
    { holder_.pop_front(); }
 
- pointer front() const
+ pointer front()
    { return cast(holder_.front()); }
 
    bool empty() const
    { return holder_.empty(); }
 
- iterator before_begin() const
+ iterator before_begin()
    { return iterator(holder_.before_begin()); }
 
- iterator begin() const
+ iterator begin()
    { return iterator(holder_.begin()); }
 
- iterator end() const
+ iterator end()
    { return iterator(holder_.end()); }
 
- iterator last() const
+ iterator last()
    { return iterator(holder_.last()); }
 
    std::size_t size() const
@@ -546,7 +237,7 @@
 }}}
 
 // namespace containers_detail {
-// namespace interprocess_container {
+// namespace container {
 // namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/node_alloc_holder.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -38,7 +38,7 @@
 
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 //!A deleter for scoped_ptr that deallocates the memory
@@ -48,7 +48,7 @@
 {
    typedef typename Allocator::pointer pointer;
    typedef containers_detail::integral_constant<unsigned,
- boost::interprocess_container::containers_detail::
+ boost::container::containers_detail::
          version<Allocator>::value> alloc_version;
    typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
    typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
@@ -60,13 +60,10 @@
    void priv_deallocate(allocator_v2)
    { m_alloc.deallocate_one(m_ptr); }
 
- scoped_deallocator(scoped_deallocator &);
- scoped_deallocator& operator=(scoped_deallocator &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
 
    public:
 
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(scoped_deallocator)
-
    pointer m_ptr;
    Allocator& m_alloc;
 
@@ -173,18 +170,16 @@
    typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
    typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
    typedef containers_detail::integral_constant<unsigned,
- boost::interprocess_container::containers_detail::
+ boost::container::containers_detail::
          version<NodeAlloc>::value> alloc_version;
    typedef typename ICont::iterator icont_iterator;
    typedef typename ICont::const_iterator icont_citerator;
    typedef allocator_destroyer<NodeAlloc> Destroyer;
 
    private:
- node_alloc_holder(node_alloc_holder&);
- node_alloc_holder & operator=(node_alloc_holder&);
+ BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(node_alloc_holder)
 
    node_alloc_holder(const ValAlloc &a)
       : members_(a)
@@ -198,6 +193,12 @@
       : members_(boost::interprocess::move(other.node_alloc()))
    { this->swap(other); }
 
+ node_alloc_holder & operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(node_alloc_holder) other)
+ { members_.assign(other.node_alloc()); }
+
+ node_alloc_holder & operator=(BOOST_INTERPROCESS_RV_REF(node_alloc_holder) other)
+ { members_.assign(other.node_alloc()); }
+
    template<class Pred>
    node_alloc_holder(const ValAlloc &a, const Pred &c)
       : members_(a, typename ICont::value_compare(c))
@@ -239,12 +240,7 @@
 
    template<class Convertible1, class Convertible2>
    static void construct(const NodePtr &ptr,
- #ifdef BOOST_HAS_RVALUE_REFS
- std::pair<Convertible1, Convertible2> &&
- #else
- boost::interprocess::rv<std::pair<Convertible1, Convertible2> > &
- #endif
- value)
+ BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
    {
       typedef typename Node::hook_type hook_type;
       typedef typename Node::value_type::first_type first_type;
@@ -337,7 +333,7 @@
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
- ::boost::interprocess_container::construct_in_place(containers_detail::get_pointer(p), it);
+ ::boost::container::construct_in_place(containers_detail::get_pointer(p), it);
       node_deallocator.release();
       return (p);
    }
@@ -372,12 +368,12 @@
          int constructed = 0;
          Node *p = 0;
          BOOST_TRY{
- for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
+ for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
                p = containers_detail::get_pointer(mem.front());
                mem.pop_front();
                //This can throw
                constructed = 0;
- boost::interprocess_container::construct_in_place(p, beg);
+ boost::container::construct_in_place(p, beg);
                ++constructed;
                //This can throw in some containers (predicate might throw)
                inserter(*p);
@@ -393,7 +389,6 @@
          BOOST_CATCH_END
       }
       return beg;
-
    }
 
    void clear(allocator_v1)
@@ -404,7 +399,7 @@
       typename NodeAlloc::multiallocation_chain chain;
       allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
       this->icont().clear_and_dispose(builder);
- BOOST_STATIC_ASSERT((boost::interprocess::is_movable<typename NodeAlloc::multiallocation_chain>::value == true));
+ BOOST_STATIC_ASSERT((::boost::interprocess::is_movable<typename NodeAlloc::multiallocation_chain>::value == true));
       if(!chain.empty())
          this->node_alloc().deallocate_individual(boost::interprocess::move(chain));
    }
@@ -470,6 +465,13 @@
       members_holder(const ConvertibleToAlloc &c2alloc, const Pred &c)
          : NodeAlloc(c2alloc), m_icont(c)
       {}
+
+ template<class ConvertibleToAlloc>
+ void assign (const ConvertibleToAlloc &c2alloc)
+ {
+ NodeAlloc::operator=(c2alloc);
+ }
+
       //The intrusive container
       ICont m_icont;
    } members_;
@@ -491,7 +493,7 @@
 };
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Added: trunk/boost/interprocess/containers/container/detail/node_pool_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/node_pool_impl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,366 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/pointer_to_other.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
+#include <boost/interprocess/containers/container/detail/math_functions.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/pool_common.hpp>
+#include <cassert>
+#include <cstddef>
+#include <functional> //std::unary_function
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class SegmentManagerBase>
+class private_node_pool_impl
+{
+ //Non-copyable
+ private_node_pool_impl();
+ private_node_pool_impl(const private_node_pool_impl &);
+ private_node_pool_impl &operator=(const private_node_pool_impl &);
+
+ //A node object will hold node_t when it's not allocated
+ public:
+ typedef typename SegmentManagerBase::void_pointer void_pointer;
+ typedef typename node_slist<void_pointer>::slist_hook_t slist_hook_t;
+ typedef typename node_slist<void_pointer>::node_t node_t;
+ typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
+
+ private:
+ typedef typename bi::make_slist
+ < node_t, bi::base_hook<slist_hook_t>
+ , bi::linear<true>
+ , bi::constant_time_size<false> >::type blockslist_t;
+ public:
+
+ //!Segment manager typedef
+ typedef SegmentManagerBase segment_manager_base_type;
+
+ //!Constructor from a segment manager. Never throws
+ private_node_pool_impl(segment_manager_base_type *segment_mngr_base, std::size_t node_size, std::size_t nodes_per_block)
+ : m_nodes_per_block(nodes_per_block)
+ , m_real_node_size(lcm(node_size, std::size_t(alignment_of<node_t>::value)))
+ //General purpose allocator
+ , mp_segment_mngr_base(segment_mngr_base)
+ , m_blocklist()
+ , m_freelist()
+ //Debug node count
+ , m_allocated(0)
+ {}
+
+ //!Destructor. Deallocates all allocated blocks. Never throws
+ ~private_node_pool_impl()
+ { this->purge_blocks(); }
+
+ std::size_t get_real_num_node() const
+ { return m_nodes_per_block; }
+
+ //!Returns the segment manager. Never throws
+ segment_manager_base_type* get_segment_manager_base()const
+ { return containers_detail::get_pointer(mp_segment_mngr_base); }
+
+ void *allocate_node()
+ { return priv_alloc_node(); }
+
+ //!Deallocates an array pointed by ptr. Never throws
+ void deallocate_node(void *ptr)
+ { priv_dealloc_node(ptr); }
+
+ //!Allocates a singly linked list of n nodes ending in null pointer.
+ multiallocation_chain allocate_nodes(const std::size_t n)
+ {
+ //Preallocate all needed blocks to fulfill the request
+ std::size_t cur_nodes = m_freelist.size();
+ if(cur_nodes < n){
+ priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
+ }
+
+ //We just iterate the needed nodes to get the last we'll erase
+ typedef typename free_nodes_t::iterator free_iterator;
+ free_iterator before_last_new_it = m_freelist.before_begin();
+ for(std::size_t j = 0; j != n; ++j){
+ ++before_last_new_it;
+ }
+
+ //Cache the first node of the allocated range before erasing
+ free_iterator first_node(m_freelist.begin());
+ free_iterator last_node (before_last_new_it);
+
+ //Erase the range. Since we already have the distance, this is O(1)
+ m_freelist.erase_after( m_freelist.before_begin()
+ , ++free_iterator(before_last_new_it)
+ , n);
+
+ //Now take the last erased node and just splice it in the end
+ //of the intrusive list that will be traversed by the multialloc iterator.
+ multiallocation_chain chain;
+ chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
+ m_allocated += n;
+ return boost::interprocess::move(chain);
+ }
+
+ void deallocate_nodes(multiallocation_chain chain)
+ {
+ typedef typename multiallocation_chain::iterator iterator;
+ iterator it(chain.begin()), itend(chain.end());
+ while(it != itend){
+ void *pElem = &*it;
+ ++it;
+ priv_dealloc_node(pElem);
+ }
+ }
+
+ //!Deallocates all the free blocks of memory. Never throws
+ void deallocate_free_blocks()
+ {
+ typedef typename free_nodes_t::iterator nodelist_iterator;
+ typename blockslist_t::iterator bit(m_blocklist.before_begin()),
+ it(m_blocklist.begin()),
+ itend(m_blocklist.end());
+ free_nodes_t backup_list;
+ nodelist_iterator backup_list_last = backup_list.before_begin();
+
+ //Execute the algorithm and get an iterator to the last value
+ std::size_t blocksize = get_rounded_size
+ (m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
+
+ while(it != itend){
+ //Collect all the nodes from the block pointed by it
+ //and push them in the list
+ free_nodes_t free_nodes;
+ nodelist_iterator last_it = free_nodes.before_begin();
+ const void *addr = get_block_from_hook(&*it, blocksize);
+
+ m_freelist.remove_and_dispose_if
+ (is_between(addr, blocksize), push_in_list(free_nodes, last_it));
+
+ //If the number of nodes is equal to m_nodes_per_block
+ //this means that the block can be deallocated
+ if(free_nodes.size() == m_nodes_per_block){
+ //Unlink the nodes
+ free_nodes.clear();
+ it = m_blocklist.erase_after(bit);
+ mp_segment_mngr_base->deallocate((void*)addr);
+ }
+ //Otherwise, insert them in the backup list, since the
+ //next "remove_if" does not need to check them again.
+ else{
+ //Assign the iterator to the last value if necessary
+ if(backup_list.empty() && !m_freelist.empty()){
+ backup_list_last = last_it;
+ }
+ //Transfer nodes. This is constant time.
+ backup_list.splice_after
+ ( backup_list.before_begin()
+ , free_nodes
+ , free_nodes.before_begin()
+ , last_it
+ , free_nodes.size());
+ bit = it;
+ ++it;
+ }
+ }
+ //We should have removed all the nodes from the free list
+ assert(m_freelist.empty());
+
+ //Now pass all the node to the free list again
+ m_freelist.splice_after
+ ( m_freelist.before_begin()
+ , backup_list
+ , backup_list.before_begin()
+ , backup_list_last
+ , backup_list.size());
+ }
+
+ std::size_t num_free_nodes()
+ { return m_freelist.size(); }
+
+ //!Deallocates all used memory. Precondition: all nodes allocated from this pool should
+ //!already be deallocated. Otherwise, undefined behaviour. Never throws
+ void purge_blocks()
+ {
+ //check for memory leaks
+ assert(m_allocated==0);
+ std::size_t blocksize = get_rounded_size
+ (m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
+ typename blockslist_t::iterator
+ it(m_blocklist.begin()), itend(m_blocklist.end()), aux;
+
+ //We iterate though the NodeBlock list to free the memory
+ while(!m_blocklist.empty()){
+ void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
+ m_blocklist.pop_front();
+ mp_segment_mngr_base->deallocate((void*)addr);
+ }
+ //Just clear free node list
+ m_freelist.clear();
+ }
+
+ void swap(private_node_pool_impl &other)
+ {
+ assert(m_nodes_per_block == other.m_nodes_per_block);
+ assert(m_real_node_size == other.m_real_node_size);
+ std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+ m_blocklist.swap(other.m_blocklist);
+ m_freelist.swap(other.m_freelist);
+ std::swap(m_allocated, other.m_allocated);
+ }
+
+ private:
+
+ struct push_in_list
+ {
+ push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
+ : slist_(l), last_it_(it)
+ {}
+
+ void operator()(typename free_nodes_t::pointer p) const
+ {
+ slist_.push_front(*p);
+ if(slist_.size() == 1){ //Cache last element
+ ++last_it_ = slist_.begin();
+ }
+ }
+
+ private:
+ free_nodes_t &slist_;
+ typename free_nodes_t::iterator &last_it_;
+ };
+
+ struct is_between
+ : std::unary_function<typename free_nodes_t::value_type, bool>
+ {
+ is_between(const void *addr, std::size_t size)
+ : beg_(static_cast<const char *>(addr)), end_(beg_+size)
+ {}
+
+ bool operator()(typename free_nodes_t::const_reference v) const
+ {
+ return (beg_ <= reinterpret_cast<const char *>(&v) &&
+ end_ > reinterpret_cast<const char *>(&v));
+ }
+ private:
+ const char * beg_;
+ const char * end_;
+ };
+
+ //!Allocates one node, using single segregated storage algorithm.
+ //!Never throws
+ node_t *priv_alloc_node()
+ {
+ //If there are no free nodes we allocate a new block
+ if (m_freelist.empty())
+ priv_alloc_block();
+ //We take the first free node
+ node_t *n = (node_t*)&m_freelist.front();
+ m_freelist.pop_front();
+ ++m_allocated;
+ return n;
+ }
+
+ //!Deallocates one node, using single segregated storage algorithm.
+ //!Never throws
+ void priv_dealloc_node(void *pElem)
+ {
+ //We put the node at the beginning of the free node list
+ node_t * to_deallocate = static_cast<node_t*>(pElem);
+ m_freelist.push_front(*to_deallocate);
+ assert(m_allocated>0);
+ --m_allocated;
+ }
+
+ //!Allocates several blocks of nodes. Can throw
+ void priv_alloc_block(std::size_t num_blocks = 1)
+ {
+ if(!num_blocks)
+ return;
+ std::size_t blocksize =
+ get_rounded_size(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
+
+ try{
+ for(std::size_t i = 0; i != num_blocks; ++i){
+ //We allocate a new NodeBlock and put it as first
+ //element in the free Node list
+ char *pNode = reinterpret_cast<char*>
+ (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
+ char *pBlock = pNode;
+ m_blocklist.push_front(get_block_hook(pBlock, blocksize));
+
+ //We initialize all Nodes in Node Block to insert
+ //them in the free Node list
+ for(std::size_t i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
+ m_freelist.push_front(*new (pNode) node_t);
+ }
+ }
+ }
+ catch(...){
+ //to-do: if possible, an efficient way to deallocate allocated blocks
+ throw;
+ }
+ }
+
+ //!Deprecated, use deallocate_free_blocks
+ void deallocate_free_chunks()
+ { this->deallocate_free_blocks(); }
+
+ //!Deprecated, use purge_blocks
+ void purge_chunks()
+ { this->purge_blocks(); }
+
+ private:
+ //!Returns a reference to the block hook placed in the end of the block
+ static node_t & get_block_hook (void *block, std::size_t blocksize)
+ {
+ return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
+ }
+
+ //!Returns the starting address of the block reference to the block hook placed in the end of the block
+ void *get_block_from_hook (node_t *hook, std::size_t blocksize)
+ {
+ return (reinterpret_cast<char*>(hook) - blocksize);
+ }
+
+ private:
+ typedef typename boost::pointer_to_other
+ <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
+
+ const std::size_t m_nodes_per_block;
+ const std::size_t m_real_node_size;
+ segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
+ blockslist_t m_blocklist; //Intrusive container of blocks
+ free_nodes_t m_freelist; //Intrusive container of free nods
+ std::size_t m_allocated; //Used nodes for debugging
+};
+
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP

Modified: trunk/boost/interprocess/containers/container/detail/pair.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/pair.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/pair.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -32,14 +32,16 @@
 #endif
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template <class T1, class T2>
 struct pair
 {
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(pair)
+ private:
+ BOOST_COPYABLE_AND_MOVABLE(pair)
 
+ public:
    typedef T1 first_type;
    typedef T2 second_type;
 
@@ -100,7 +102,7 @@
    pair( BOOST_CONTAINERS_PARAM(U, u)
        #ifndef BOOST_HAS_RVALUE_REFS
        , typename containers_detail::disable_if
- < containers_detail::is_same<U, boost::interprocess::rv<pair> > >::type* = 0
+ < containers_detail::is_same<U, ::boost::interprocess::rv<pair> > >::type* = 0
        #endif
       )
       : first(boost::interprocess::forward<U>(const_cast<U&>(u)))
@@ -118,6 +120,13 @@
    #include BOOST_PP_LOCAL_ITERATE()
    #endif
 
+ pair& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(pair) p)
+ {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+
    pair& operator=(BOOST_INTERPROCESS_RV_REF(pair) p)
    {
       first = boost::interprocess::move(p.first);
@@ -181,7 +190,8 @@
 }
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
+
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Added: trunk/boost/interprocess/containers/container/detail/pool_common.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/container/detail/pool_common.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,52 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/intrusive/slist.hpp>
+#include <new>
+
+namespace boost {
+namespace container {
+namespace containers_detail {
+
+template<class VoidPointer>
+struct node_slist
+{
+ //This hook will be used to chain the individual nodes
+ typedef typename bi::make_slist_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type slist_hook_t;
+
+ //A node object will hold node_t when it's not allocated
+ typedef slist_hook_t node_t;
+
+ typedef typename bi::make_slist
+ <node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
+};
+
+template<class T>
+struct is_stateless_segment_manager
+{
+ static const bool value = false;
+};
+
+} //namespace containers_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP

Modified: trunk/boost/interprocess/containers/container/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/preprocessor.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/preprocessor.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/transform_iterator.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
@@ -24,7 +24,7 @@
 #include <iterator>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 
 template <class PseudoReference>
 struct operator_arrow_proxy
@@ -168,7 +168,7 @@
    return transform_iterator<Iterator, UnaryFunc>(it, fun);
 }
 
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/tree.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/tree.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/tree.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -44,6 +44,7 @@
 
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/pointer_to_other.hpp>
@@ -65,7 +66,7 @@
 #include <algorithm>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template<class Key, class Value, class KeyCompare, class KeyOfValue>
@@ -202,7 +203,7 @@
 #if !defined(BOOST_HAS_RVALUE_REFS)
 template<class T, class VoidPointer>
 struct has_own_construct_from_it
- < boost::interprocess_container::containers_detail::rbtree_node<T, VoidPointer> >
+ < boost::container::containers_detail::rbtree_node<T, VoidPointer> >
 {
    static const bool value = true;
 };
@@ -297,9 +298,9 @@
       AllocHolder &m_holder;
       Icont &m_icont;
    };
+ BOOST_COPYABLE_AND_MOVABLE(rbtree)
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(rbtree)
 
    typedef Key key_type;
    typedef Value value_type;
@@ -451,6 +452,15 @@
       priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
    }
 
+ template <class InputIterator>
+ rbtree( ordered_range_t, InputIterator first, InputIterator last
+ , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type())
+ : AllocHolder(a, comp)
+ {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
+ priv_create_and_insert_ordered_nodes(first, last, alloc_version(), ItCat());
+ }
+
    rbtree(const rbtree& x)
       : AllocHolder(x, x.key_comp())
    {
@@ -465,7 +475,7 @@
    ~rbtree()
    {} //AllocHolder clears the tree
 
- rbtree& operator=(const rbtree& x)
+ rbtree& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(rbtree) x)
    {
       if (this != &x) {
          //Transfer all the nodes to a temporary tree
@@ -873,14 +883,6 @@
    //Iterator range version
    template<class InpIterator>
    void priv_create_and_insert_nodes
- (InpIterator beg, InpIterator end, bool unique)
- {
- typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(beg, end, unique, alloc_version(), ItCat());
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
       (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
    {
       if(unique){
@@ -934,6 +936,52 @@
          }
       }
    }
+
+ //Iterator range version
+ template<class InpIterator>
+ void priv_create_and_insert_ordered_nodes
+ (InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+ {
+ const_iterator cend_n(this->cend());
+ for (; beg != end; ++beg){
+ this->insert_before(cend_n, *beg);
+ }
+ }
+
+ template<class InpIterator>
+ void priv_create_and_insert_ordered_nodes
+ (InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+ { //Just forward to the default one
+ priv_create_and_insert_ordered_nodes(beg, end, allocator_v1(), std::input_iterator_tag());
+ }
+
+ class back_insertion_functor;
+ friend class back_insertion_functor;
+
+ class back_insertion_functor
+ {
+ Icont &icont_;
+
+ public:
+ back_insertion_functor(Icont &icont)
+ : icont_(icont)
+ {}
+
+ void operator()(Node &n)
+ { this->icont_.push_back(n); }
+ };
+
+
+ template<class FwdIterator>
+ void priv_create_and_insert_ordered_nodes
+ (FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+ {
+ if(beg != end){
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), back_insertion_functor(this->icont()));
+ }
+ }
 };
 
 template <class Key, class Value, class KeyOfValue,
@@ -999,22 +1047,18 @@
 }
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class V, class KOV,
 class C, class A>
 struct has_trivial_destructor_after_move
- <boost::interprocess_container::containers_detail::rbtree<K, V, KOV, C, A> >
+ <boost::container::containers_detail::rbtree<K, V, KOV, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
+*/
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/type_traits.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/type_traits.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/type_traits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -22,7 +22,7 @@
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 struct nat{};
@@ -157,7 +157,7 @@
 };
 
 } // namespace containers_detail
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #endif //#ifndef BOOST_CONTAINERS_CONTAINER_DETAIL_TYPE_TRAITS_HPP

Modified: trunk/boost/interprocess/containers/container/detail/utilities.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/utilities.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/utilities.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -13,10 +13,14 @@
 
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <cstdio>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/containers/container/detail/mpl.hpp>
+#include <boost/interprocess/containers/container/detail/type_traits.hpp>
 #include <algorithm>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template <class SizeType>
@@ -79,14 +83,29 @@
    swap(x, y);
 }
 
+//Rounds "orig_size" by excess to round_to bytes
+inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
+{
+ return ((orig_size-1)/round_to+1)*round_to;
+}
+
 template <std::size_t OrigSize, std::size_t RoundTo>
 struct ct_rounded_size
 {
    enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
 };
 
+template<class T>
+struct move_const_ref_type
+ : if_c
+ < ::boost::is_fundamental<T>::value
+ ,const T &
+ ,BOOST_INTERPROCESS_CATCH_CONST_RLVALUE(T)
+ >
+{};
+
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 

Modified: trunk/boost/interprocess/containers/container/detail/value_init.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/value_init.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/value_init.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -21,7 +21,7 @@
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template<class T>
@@ -35,7 +35,7 @@
 };
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>

Modified: trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/variadic_templates_tools.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -21,7 +21,7 @@
 #include <cstddef> //std::size_t
 
 namespace boost {
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 template<typename... Values>
@@ -146,7 +146,7 @@
 { typedef index_tuple<Indexes...> type; };
 
 
-}}} //namespace boost { namespace interprocess_container { namespace containers_detail {
+}}} //namespace boost { namespace container { namespace containers_detail {
 
 #include <boost/interprocess/containers/container/detail/config_end.hpp>
 

Modified: trunk/boost/interprocess/containers/container/detail/version_type.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/version_type.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/version_type.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -21,7 +21,7 @@
 
 
 namespace boost{
-namespace interprocess_container {
+namespace container {
 namespace containers_detail {
 
 //using namespace boost;
@@ -83,7 +83,7 @@
 };
 
 } //namespace containers_detail {
-} //namespace interprocess_container {
+} //namespace container {
 } //namespace boost{
 
 #endif //#define BOOST_CONTAINERS_DETAIL_VERSION_TYPE_HPP

Modified: trunk/boost/interprocess/containers/container/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/detail/workaround.hpp (original)
+++ trunk/boost/interprocess/containers/container/detail/workaround.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/containers/container/flat_map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/flat_map.hpp (original)
+++ trunk/boost/interprocess/containers/container/flat_map.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -18,23 +18,22 @@
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <utility>
 #include <functional>
 #include <memory>
 #include <stdexcept>
 #include <boost/interprocess/containers/container/detail/flat_tree.hpp>
-#include <boost/interprocess/containers/container/detail/utilities.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/interprocess/containers/container/detail/mpl.hpp>
 #include <boost/interprocess/detail/move.hpp>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -77,6 +76,7 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_map)
    //This is the tree that we should store if pair was movable
    typedef containers_detail::flat_tree<Key,
                            std::pair<Key, T>,
@@ -119,7 +119,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_map)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -158,6 +157,20 @@
       : m_flat_tree(comp, force<impl_allocator_type>(a))
       { m_flat_tree.insert_unique(first, last); }
 
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
    //! <b>Effects</b>: Copy constructs a flat_map.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -177,8 +190,8 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_map<Key,T,Pred,Alloc>& operator=(const flat_map<Key, T, Pred, Alloc>& x)
- { m_flat_tree = x.m_flat_tree; return *this; }
+ flat_map<Key,T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(flat_map) x)
+ { m_flat_tree = x.m_flat_tree; return *this; }
 
    //! <b>Effects</b>: Move constructs a flat_map.
    //! Constructs *this using x's resources.
@@ -509,7 +522,7 @@
    void insert(InputIterator first, InputIterator last)
    { m_flat_tree.insert_unique(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... if and only if there is no element in the container
@@ -750,21 +763,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::flat_map<K, T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
 template <class Key, class T,
@@ -800,6 +809,7 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
    typedef containers_detail::flat_tree<Key,
                            std::pair<Key, T>,
                            containers_detail::select1st< std::pair<Key, T> >,
@@ -839,7 +849,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_multimap)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -880,6 +889,20 @@
       : m_flat_tree(comp, force<impl_allocator_type>(a))
       { m_flat_tree.insert_equal(first, last); }
 
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_multimap(ordered_range_t, InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
    //! <b>Effects</b>: Copy constructs a flat_multimap.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -898,7 +921,7 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_multimap<Key,T,Pred,Alloc>& operator=(const flat_multimap<Key,T,Pred,Alloc>& x)
+ flat_multimap<Key,T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(flat_multimap) x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
@@ -1126,7 +1149,7 @@
    void insert(InputIterator first, InputIterator last)
       { m_flat_tree.insert_equal(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1370,17 +1393,15 @@
 /// @cond
 
 namespace boost {
-namespace interprocess {
-
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move< boost::interprocess_container::flat_multimap<K, T, C, A> >
+struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
+*/
 } //namespace boost {
 
 /// @endcond

Modified: trunk/boost/interprocess/containers/container/flat_set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/flat_set.hpp (original)
+++ trunk/boost/interprocess/containers/container/flat_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -18,7 +18,7 @@
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <utility>
 #include <functional>
 #include <memory>
@@ -26,12 +26,12 @@
 #include <boost/interprocess/containers/container/detail/mpl.hpp>
 #include <boost/interprocess/detail/move.hpp>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -65,12 +65,14 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_set)
    typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, Alloc> tree_t;
    tree_t m_flat_tree; // flat tree representing flat_set
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_set)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -111,6 +113,21 @@
       : m_flat_tree(comp, a)
       { m_flat_tree.insert_unique(first, last); }
 
+ //! <b>Effects</b>: Constructs an empty flat_set using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_set(ordered_unique_range_t, InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
    //! <b>Effects</b>: Copy constructs a map.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -129,7 +146,7 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_set<T,Pred,Alloc>& operator=(const flat_set<T, Pred, Alloc>& x)
+ flat_set<T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(flat_set) x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
    //! <b>Effects</b>: Makes *this a copy of x.
@@ -311,8 +328,17 @@
    //! to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- std::pair<iterator,bool> insert(const value_type& x)
- { return m_flat_tree.insert_unique(x); }
+ std::pair<iterator, bool> insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ std::pair<iterator, bool> insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ std::pair<iterator, bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
 
    //! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
    //! only if there is no element in the container with key equivalent to the key of x.
@@ -339,8 +365,17 @@
    //! right before p) plus insertion linear to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const_iterator position, const value_type& x)
- { return m_flat_tree.insert_unique(position, x); }
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
 
    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -367,7 +402,7 @@
    void insert(InputIterator first, InputIterator last)
       { m_flat_tree.insert_unique(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... if and only if there is no element in the container
@@ -562,6 +597,13 @@
 
    template <class K1, class C1, class A1>
    friend bool operator< (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
+
+ private:
+ std::pair<iterator, bool> priv_insert(const T &x)
+ { return m_flat_tree.insert_unique(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_flat_tree.insert_unique(p, x); }
    /// @endcond
 };
 
@@ -601,21 +643,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::flat_set<T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::flat_set<T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value &&has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
 
@@ -647,13 +685,14 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
    typedef containers_detail::flat_tree<T, T, containers_detail::identity<T>, Pred, Alloc> tree_t;
    tree_t m_flat_tree; // flat tree representing flat_multiset
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(flat_multiset)
-
    // typedefs:
    typedef typename tree_t::key_type key_type;
    typedef typename tree_t::value_type value_type;
@@ -684,6 +723,20 @@
       : m_flat_tree(comp, a)
       { m_flat_tree.insert_equal(first, last); }
 
+ //! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ flat_multiset(ordered_range_t, InputIterator first, InputIterator last,
+ const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_flat_tree(ordered_range, first, last, comp, a)
+ {}
+
    flat_multiset(const flat_multiset<T,Pred,Alloc>& x)
       : m_flat_tree(x.m_flat_tree) {}
 
@@ -691,7 +744,7 @@
       : m_flat_tree(boost::interprocess::move(x.m_flat_tree))
    {}
 
- flat_multiset<T,Pred,Alloc>& operator=(const flat_multiset<T,Pred,Alloc>& x)
+ flat_multiset<T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(flat_multiset) x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
    flat_multiset<T,Pred,Alloc>& operator=(BOOST_INTERPROCESS_RV_REF(flat_multiset) mx)
@@ -866,8 +919,17 @@
    //! to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const value_type& x)
- { return m_flat_tree.insert_equal(x); }
+ iterator insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
 
    //! <b>Effects</b>: Inserts a new value_type move constructed from x
    //! and returns the iterator pointing to the newly inserted element.
@@ -889,8 +951,17 @@
    //! right before p) plus insertion linear to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(const_iterator position, const value_type& x)
- { return m_flat_tree.insert_equal(position, x); }
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
 
    //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -917,7 +988,7 @@
    void insert(InputIterator first, InputIterator last)
       { m_flat_tree.insert_equal(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1108,6 +1179,12 @@
    template <class K1, class C1, class A1>
    friend bool operator< (const flat_multiset<K1,C1,A1>&,
                           const flat_multiset<K1,C1,A1>&);
+ private:
+ iterator priv_insert(const T &x)
+ { return m_flat_tree.insert_equal(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_flat_tree.insert_equal(p, x); }
    /// @endcond
 };
 
@@ -1147,21 +1224,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::flat_multiset<T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::flat_multiset<T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 /// @endcond
 

Modified: trunk/boost/interprocess/containers/container/list.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/list.hpp (original)
+++ trunk/boost/interprocess/containers/container/list.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -49,7 +49,7 @@
 
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <boost/interprocess/containers/container/detail/version_type.hpp>
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/pointer_to_other.hpp>
@@ -60,11 +60,13 @@
 #include <boost/intrusive/list.hpp>
 #include <boost/interprocess/containers/container/detail/node_alloc_holder.hpp>
 
-#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#else
 //Preprocessor library to emulate perfect forwarding
 #include <boost/interprocess/containers/container/detail/preprocessor.hpp>
 #endif
 
+#include <stdexcept>
 #include <iterator>
 #include <utility>
 #include <memory>
@@ -72,12 +74,12 @@
 #include <algorithm>
 #include <stdexcept>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -95,7 +97,18 @@
    : public list_hook<VoidPointer>::type
 {
 
- #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ list_node()
+ : m_data()
+ {}
+
+ template<class ...Args>
+ list_node(Args &&...args)
+ : m_data(boost::interprocess::forward<Args>(args)...)
+ {}
+
+ #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
 
    list_node()
       : m_data()
@@ -110,16 +123,6 @@
    #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
    #include BOOST_PP_LOCAL_ITERATE()
 
- #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
-
- list_node()
- : m_data()
- {}
-
- template<class ...Args>
- list_node(Args &&...args)
- : m_data(boost::interprocess::forward<Args>(args)...)
- {}
    #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
 
    T m_data;
@@ -161,8 +164,10 @@
       <A, typename containers_detail::intrusive_list_type<A>::type>
 {
    /// @cond
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    typedef typename
- containers_detail::intrusive_list_type<A>::type Icont;
+ containers_detail::intrusive_list_type<A>::type Icont;
    typedef list <T, A> ThisType;
    typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
    typedef typename AllocHolder::NodePtr NodePtr;
@@ -226,6 +231,7 @@
 
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(list)
    typedef difference_type list_difference_type;
    typedef pointer list_pointer;
    typedef const_pointer list_const_pointer;
@@ -234,8 +240,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(list)
-
    //! Const iterator used to iterate through a list.
    class const_iterator
       /// @cond
@@ -387,7 +391,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    list(BOOST_INTERPROCESS_RV_REF(list) x)
- : AllocHolder(boost::interprocess::move((AllocHolder&)x))
+ : AllocHolder(boost::interprocess::move(static_cast<AllocHolder&>(x)))
    {}
 
    //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
@@ -565,9 +569,17 @@
    //! T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- void push_front(const T& x)
+ void push_front(insert_const_ref_type x)
    { this->insert(this->cbegin(), x); }
 
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_front(T &x) { push_front(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_front(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { this->insert(this->cbegin(), u); }
+ #endif
+
    //! <b>Effects</b>: Constructs a new element in the beginning of the list
    //! and moves the resources of t to this new element.
    //!
@@ -582,9 +594,18 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- void push_back (const T& x)
+ void push_back (insert_const_ref_type x)
    { this->insert(this->cend(), x); }
 
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_back(T &x) { push_back(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { this->insert(this->cend(), u); }
+
+ #endif
+
    //! <b>Effects</b>: Removes the first element from the list.
    //!
    //! <b>Throws</b>: Nothing.
@@ -728,7 +749,7 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in x.
- ThisType& operator=(const ThisType& x)
+ ThisType& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(ThisType) x)
    {
       if (this != &x) {
          this->assign(x.begin(), x.end());
@@ -784,11 +805,16 @@
    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- iterator insert(const_iterator p, const T& x)
- {
- NodePtr tmp = AllocHolder::create_node(x);
- return iterator(this->icont().insert(p.get(), *tmp));
- }
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
    //!
@@ -803,7 +829,7 @@
       return iterator(this->icont().insert(p.get(), *tmp));
    }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... in the end of the list.
@@ -1167,6 +1193,12 @@
    /// @cond
    private:
 
+ iterator priv_insert(const_iterator p, const T &x)
+ {
+ NodePtr tmp = AllocHolder::create_node(x);
+ return iterator(this->icont().insert(p.get(), *tmp));
+ }
+
    //Iterator range version
    template<class InpIterator>
    void priv_create_and_insert_nodes
@@ -1351,21 +1383,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::list<T, A> >
+struct has_trivial_destructor_after_move<boost::container::list<T, A> >
 {
    static const bool value = has_trivial_destructor<A>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 /// @endcond
 

Modified: trunk/boost/interprocess/containers/container/map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/map.hpp (original)
+++ trunk/boost/interprocess/containers/container/map.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -50,7 +50,7 @@
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <utility>
 #include <functional>
 #include <memory>
@@ -63,12 +63,12 @@
 #include <boost/interprocess/containers/container/detail/pair.hpp>
 #include <boost/interprocess/detail/move.hpp>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -99,6 +99,7 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(map)
    typedef containers_detail::rbtree<Key,
                            std::pair<const Key, T>,
                            containers_detail::select1st< std::pair<const Key, T> >,
@@ -108,7 +109,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(map)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -167,6 +167,20 @@
       : m_tree(first, last, comp, a, true)
    {}
 
+ //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ map( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {}
+
    //! <b>Effects</b>: Copy constructs a map.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -186,7 +200,7 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- map& operator=(const map<Key, T, Pred, Alloc>& x)
+ map& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(map) x)
    { m_tree = x.m_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
@@ -504,7 +518,7 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_unique(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... in the container if and only if there is
@@ -706,21 +720,17 @@
 inline bool operator<(const multimap<Key,T,Pred,Alloc>& x,
                       const multimap<Key,T,Pred,Alloc>& y);
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::map<K, T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::map<K, T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 /// @endcond
 
@@ -742,6 +752,7 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(multimap)
    typedef containers_detail::rbtree<Key,
                            std::pair<const Key, T>,
                            containers_detail::select1st< std::pair<const Key, T> >,
@@ -751,7 +762,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(multimap)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -811,6 +821,20 @@
       : m_tree(first, last, comp, a, false)
    {}
 
+ //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Pred& comp = Pred(),
+ const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {}
+
+
    //! <b>Effects</b>: Copy constructs a multimap.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -830,7 +854,7 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- multimap& operator=(const multimap<Key,T,Pred,Alloc>& x)
+ multimap& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(multimap) x)
    { m_tree = x.m_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
@@ -1048,7 +1072,7 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_equal(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... in the container.
@@ -1240,21 +1264,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class K, class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::multimap<K, T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 /// @endcond
 

Modified: trunk/boost/interprocess/containers/container/set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/set.hpp (original)
+++ trunk/boost/interprocess/containers/container/set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -49,7 +49,7 @@
 
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 
 #include <utility>
 #include <functional>
@@ -63,12 +63,12 @@
 #include <boost/interprocess/containers/container/detail/preprocessor.hpp>
 #endif
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -94,13 +94,15 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(set)
    typedef containers_detail::rbtree<T, T,
                      containers_detail::identity<T>, Pred, Alloc> tree_t;
    tree_t m_tree; // red-black tree representing set
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(set)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -140,6 +142,20 @@
       : m_tree(first, last, comp, a, true)
    {}
 
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ set( ordered_unique_range_t, InputIterator first, InputIterator last
+ , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {}
+
    //! <b>Effects</b>: Copy constructs a set.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -159,7 +175,7 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- set<T,Pred,Alloc>& operator=(const set<T, Pred, Alloc>& x)
+ set& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(set) x)
    { m_tree = x.m_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
@@ -338,8 +354,17 @@
    //! points to the element with key equivalent to the key of x.
    //!
    //! <b>Complexity</b>: Logarithmic.
- std::pair<iterator,bool> insert(const value_type& x)
- { return m_tree.insert_unique(x); }
+ std::pair<iterator,bool> insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ std::pair<iterator,bool> insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
 
    //! <b>Effects</b>: Move constructs a new value from x if and only if there is
    //! no element in the container with key equivalent to the key of x.
@@ -361,8 +386,17 @@
    //!
    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
    //! is inserted right before p.
- iterator insert(const_iterator p, const value_type& x)
- { return m_tree.insert_unique(p, x); }
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
 
    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -383,7 +417,7 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_unique(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... if and only if there is
@@ -536,6 +570,14 @@
 
    template <class K1, class C1, class A1>
    friend bool operator< (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
+
+ private:
+ std::pair<iterator, bool> priv_insert(const T &x)
+ { return m_tree.insert_unique(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_tree.insert_unique(p, x); }
+
    /// @endcond
 };
 
@@ -575,21 +617,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::set<T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::set<T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 // Forward declaration of operators < and ==, needed for friend declaration.
 
@@ -614,13 +652,15 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(multiset)
    typedef containers_detail::rbtree<T, T,
                      containers_detail::identity<T>, Pred, Alloc> tree_t;
    tree_t m_tree; // red-black tree representing multiset
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(multiset)
 
    // typedefs:
    typedef typename tree_t::key_type key_type;
@@ -661,6 +701,20 @@
       : m_tree(first, last, comp, a, false)
    {}
 
+ //! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [first ,last ). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ template <class InputIterator>
+ multiset( ordered_range_t ordered_range, InputIterator first, InputIterator last
+ , const Pred& comp = Pred()
+ , const allocator_type& a = allocator_type())
+ : m_tree(ordered_range, first, last, comp, a)
+ {}
+
    //! <b>Effects</b>: Copy constructs a multiset.
    //!
    //! <b>Complexity</b>: Linear in x.size().
@@ -680,7 +734,7 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- multiset<T,Pred,Alloc>& operator=(const multiset& x)
+ multiset& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(multiset) x)
    { m_tree = x.m_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
@@ -855,8 +909,17 @@
    //! newly inserted element.
    //!
    //! <b>Complexity</b>: Logarithmic.
- iterator insert(const value_type& x)
- { return m_tree.insert_equal(x); }
+ iterator insert(insert_const_ref_type x)
+ { return priv_insert(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(T &x)
+ { return this->insert(const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(u); }
+ #endif
 
    //! <b>Effects</b>: Inserts a copy of x in the container.
    //!
@@ -876,8 +939,17 @@
    //!
    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
    //! is inserted right before p.
- iterator insert(const_iterator p, const value_type& x)
- { return m_tree.insert_equal(p, x); }
+ iterator insert(const_iterator p, insert_const_ref_type x)
+ { return priv_insert(p, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_insert(position, u); }
+ #endif
 
    //! <b>Effects</b>: Inserts a value move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -899,7 +971,7 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_equal(first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1047,6 +1119,13 @@
    template <class K1, class C1, class A1>
    friend bool operator< (const multiset<K1,C1,A1>&,
                           const multiset<K1,C1,A1>&);
+ private:
+ iterator priv_insert(const T &x)
+ { return m_tree.insert_equal(x); }
+
+ iterator priv_insert(const_iterator p, const T &x)
+ { return m_tree.insert_equal(p, x); }
+
    /// @endcond
 };
 
@@ -1086,21 +1165,17 @@
 
 /// @cond
 
-} //namespace interprocess_container {
-
-namespace interprocess {
-
+} //namespace container {
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class C, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::multiset<T, C, A> >
+struct has_trivial_destructor_after_move<boost::container::multiset<T, C, A> >
 {
    static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 /// @endcond
 

Modified: trunk/boost/interprocess/containers/container/slist.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/slist.hpp (original)
+++ trunk/boost/interprocess/containers/container/slist.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -8,7 +8,7 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 //
-// This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2008
+// This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2009
 // Renaming, isolating and porting to generic algorithms. Pointer typedef
 // set to allocator::pointer to allow placing it in shared memory.
 //
@@ -50,7 +50,7 @@
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/pointer_to_other.hpp>
 #include <boost/interprocess/containers/container/detail/utilities.hpp>
@@ -61,23 +61,25 @@
 #include <boost/intrusive/slist.hpp>
 
 
-#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+#if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 //Preprocessor library to emulate perfect forwarding
+#else
 #include <boost/interprocess/containers/container/detail/preprocessor.hpp>
 #endif
 
+#include <stdexcept>
 #include <iterator>
 #include <utility>
 #include <memory>
 #include <functional>
 #include <algorithm>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -95,7 +97,18 @@
 struct slist_node
    : public slist_hook<VoidPointer>::type
 {
- #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ slist_node()
+ : m_data()
+ {}
+
+ template<class ...Args>
+ slist_node(Args &&...args)
+ : m_data(boost::interprocess::forward<Args>(args)...)
+ {}
+
+ #else //#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
 
    slist_node()
       : m_data()
@@ -110,17 +123,7 @@
    #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
    #include BOOST_PP_LOCAL_ITERATE()
 
- #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
-
- slist_node()
- : m_data()
- {}
-
- template<class ...Args>
- slist_node(Args &&...args)
- : m_data(boost::interprocess::forward<Args>(args)...)
- {}
- #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+ #endif//#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
 
    T m_data;
 };
@@ -185,6 +188,8 @@
       <A, typename containers_detail::intrusive_slist_type<A>::type>
 {
    /// @cond
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    typedef typename
       containers_detail::intrusive_slist_type<A>::type Icont;
    typedef containers_detail::node_alloc_holder<A, Icont> AllocHolder;
@@ -249,6 +254,7 @@
 
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(slist)
    typedef difference_type list_difference_type;
    typedef pointer list_pointer;
    typedef const_pointer list_const_pointer;
@@ -257,7 +263,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(slist)
 
    //! Const iterator used to iterate through a list.
    class const_iterator
@@ -411,7 +416,7 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in x.
- slist& operator= (const slist& x)
+ slist& operator= (BOOST_INTERPROCESS_COPY_ASSIGN_REF(slist) x)
    {
       if (&x != this){
          this->assign(x.begin(), x.end());
@@ -623,8 +628,16 @@
    //! T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- void push_front(const value_type& x)
- { this->icont().push_front(*this->create_node(x)); }
+ void push_front(insert_const_ref_type x)
+ { return priv_push_front(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_front(T &x) { push_front(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_front(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_push_front(u); }
+ #endif
 
    //! <b>Effects</b>: Constructs a new element in the beginning of the list
    //! and moves the resources of t to this new element.
@@ -676,8 +689,17 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references of
    //! previous values.
- iterator insert_after(const_iterator prev_pos, const value_type& x)
- { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
+ iterator insert_after(const_iterator prev_pos, insert_const_ref_type x)
+ { return this->priv_insert_after(prev_pos, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert_after(const_iterator position, T &x)
+ { return this->insert_after(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert_after(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return this->priv_insert_after(position, u); }
+ #endif
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
    //!
@@ -735,8 +757,17 @@
    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to the elements before p.
- iterator insert(const_iterator p, const value_type& x)
- { return this->insert_after(previous(p), x); }
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x)
+ { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
    //!
@@ -771,7 +802,7 @@
    void insert(const_iterator p, InIter first, InIter last)
    { return this->insert_after(previous(p), first, last); }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... in the front of the list
@@ -1255,6 +1286,14 @@
 
    /// @cond
    private:
+ iterator priv_insert(const_iterator p, const value_type& x)
+ { return this->insert_after(previous(p), x); }
+
+ iterator priv_insert_after(const_iterator prev_pos, const value_type& x)
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
+
+ void priv_push_front(const value_type &x)
+ { this->icont().push_front(*this->create_node(x)); }
 
    //Iterator range version
    template<class InpIterator>
@@ -1461,23 +1500,20 @@
 /// @cond
 
 namespace boost {
-namespace interprocess {
-
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::slist<T, A> >
+struct has_trivial_destructor_after_move<boost::container::slist<T, A> >
 {
    static const bool value = has_trivial_destructor<A>::value;
 };
-
-} //namespace interprocess {
-
-namespace interprocess_container {
+*/
+namespace container {
 
 /// @endcond
 
-}} //namespace boost{ namespace interprocess_container {
+}} //namespace boost{ namespace container {
 
 // Specialization of insert_iterator so that insertions will be constant
 // time rather than linear time.
@@ -1489,10 +1525,10 @@
 namespace std {
 
 template <class T, class A>
-class insert_iterator<boost::interprocess_container::slist<T, A> >
+class insert_iterator<boost::container::slist<T, A> >
 {
  protected:
- typedef boost::interprocess_container::slist<T, A> Container;
+ typedef boost::container::slist<T, A> Container;
    Container* container;
    typename Container::iterator iter;
    public:

Modified: trunk/boost/interprocess/containers/container/stable_vector.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/stable_vector.hpp (original)
+++ trunk/boost/interprocess/containers/container/stable_vector.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,3 +1,12 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
 /* Stable vector.
  *
  * Copyright 2008 Joaquin M Lopez Munoz.
@@ -6,11 +15,16 @@
  * http://www.boost.org/LICENSE_1_0.txt)
  */
 
-#ifndef STABLE_VECTOR_HPP_3A7EB5C0_55BF_11DD_AE16_0800200C9A66
-#define STABLE_VECTOR_HPP_3A7EB5C0_55BF_11DD_AE16_0800200C9A66
+#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
+#define BOOST_CONTAINER_STABLE_VECTOR_HPP
 
-#include <algorithm>
-#include <stdexcept>
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/containers/container/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/not.hpp>
 #include <boost/noncopyable.hpp>
@@ -18,10 +32,17 @@
 #include <boost/interprocess/containers/container/detail/version_type.hpp>
 #include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/containers/container/detail/utilities.hpp>
+#include <boost/interprocess/containers/container/detail/iterators.hpp>
 #include <boost/interprocess/containers/container/detail/algorithms.hpp>
 #include <boost/pointer_to_other.hpp>
 #include <boost/get_pointer.hpp>
 
+#include <algorithm>
+#include <stdexcept>
+#include <memory>
+
+///@cond
+
 #define STABLE_VECTOR_USE_CONTAINERS_VECTOR
 
 #if defined (STABLE_VECTOR_USE_CONTAINERS_VECTOR)
@@ -36,15 +57,12 @@
 #include <boost/assert.hpp>
 #endif
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
-namespace boost {
-namespace interprocess {
-#else
+///@endcond
+
 namespace boost {
-namespace interprocess_container {
-#endif
+namespace container {
 
-/// @cond
+///@cond
 
 namespace stable_vector_detail{
 
@@ -96,104 +114,6 @@
    bool do_clear_;
 };
 
-template <class T, class Difference = std::ptrdiff_t>
-class constant_iterator
- : public std::iterator
- <std::random_access_iterator_tag, T, Difference, const T*, const T &>
-{
- typedef constant_iterator<T, Difference> this_type;
-
- public:
- explicit constant_iterator(const T &ref, Difference range_size)
- : m_ptr(&ref), m_num(range_size){}
-
- //Constructors
- constant_iterator()
- : m_ptr(0), m_num(0){}
-
- constant_iterator& operator++()
- { increment(); return *this; }
-
- constant_iterator operator++(int)
- {
- constant_iterator result (*this);
- increment();
- return result;
- }
-
- friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
- { return i.equal(i2); }
-
- friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
- { return !(i == i2); }
-
- friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
- { return i.less(i2); }
-
- friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
- { return i2 < i; }
-
- friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
- { return !(i > i2); }
-
- friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
- { return !(i < i2); }
-
- friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
- { return i2.distance_to(i); }
-
- //Arithmetic
- constant_iterator& operator+=(Difference off)
- { this->advance(off); return *this; }
-
- constant_iterator operator+(Difference off) const
- {
- constant_iterator other(*this);
- other.advance(off);
- return other;
- }
-
- friend constant_iterator operator+(Difference off, const constant_iterator& right)
- { return right + off; }
-
- constant_iterator& operator-=(Difference off)
- { this->advance(-off); return *this; }
-
- constant_iterator operator-(Difference off) const
- { return *this + (-off); }
-
- const T& operator*() const
- { return dereference(); }
-
- const T* operator->() const
- { return &(dereference()); }
-
- private:
- const T * m_ptr;
- Difference m_num;
-
- void increment()
- { --m_num; }
-
- void decrement()
- { ++m_num; }
-
- bool equal(const this_type &other) const
- { return m_num == other.m_num; }
-
- bool less(const this_type &other) const
- { return other.m_num < m_num; }
-
- const T & dereference() const
- { return *m_ptr; }
-
- void advance(Difference n)
- { m_num -= n; }
-
- Difference distance_to(const this_type &other)const
- { return m_num - other.m_num; }
-};
-
 template<class VoidPtr>
 struct node_type_base
 {/*
@@ -212,7 +132,18 @@
 struct node_type
    : public node_type_base<VoidPointer>
 {
- #ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ node_type()
+ : value()
+ {}
+
+ template<class ...Args>
+ node_type(Args &&...args)
+ : value(boost::interprocess::forward<Args>(args)...)
+ {}
+
+ #else //BOOST_CONTAINERS_PERFECT_FORWARDING
 
    node_type()
       : value()
@@ -227,17 +158,7 @@
    #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
    #include BOOST_PP_LOCAL_ITERATE()
 
- #else //#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
-
- node_type()
- : value()
- {}
-
- template<class ...Args>
- node_type(Args &&...args)
- : value(boost::interprocess::forward<Args>(args)...)
- {}
- #endif//#ifndef BOOST_CONTAINERS_PERFECT_FORWARDING
+ #endif//BOOST_CONTAINERS_PERFECT_FORWARDING
    
    void set_pointer(VoidPointer p)
    { node_type_base<VoidPointer>::set_pointer(p); }
@@ -245,13 +166,13 @@
    T value;
 };
 
-template<typename T, typename Value, typename Pointer>
+template<typename T, typename Reference, typename Pointer>
 class iterator
    : public std::iterator< std::random_access_iterator_tag
- , const typename std::iterator_traits<Pointer>::value_type
+ , typename std::iterator_traits<Pointer>::value_type
                          , typename std::iterator_traits<Pointer>::difference_type
                          , Pointer
- , Value &>
+ , Reference>
 {
 
    typedef typename boost::pointer_to_other
@@ -266,11 +187,11 @@
 
    public:
    typedef std::random_access_iterator_tag iterator_category;
- typedef Value value_type;
+ typedef T value_type;
    typedef typename std::iterator_traits
       <Pointer>::difference_type difference_type;
    typedef Pointer pointer;
- typedef Value & reference;
+ typedef Reference reference;
 
    iterator()
    {}
@@ -279,7 +200,7 @@
       : pn(pn)
    {}
 
- iterator(const iterator<T, T, typename boost::pointer_to_other<Pointer, T>::type >& x)
+ iterator(const iterator<T, T&, typename boost::pointer_to_other<Pointer, T>::type >& x)
       : pn(x.pn)
    {}
    
@@ -296,7 +217,7 @@
       return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::get_pointer(p)));
    }
 
- Value& dereference() const
+ reference dereference() const
    { return pn->value; }
    bool equal(const iterator& x) const
    { return pn==x.pn; }
@@ -393,18 +314,6 @@
    node_type_ptr_t pn;
 };
 
-/*
-class node_access
-{
- public:
- template<typename T, typename Value, typename VoidPointer>
- static typename iterator<T, Value, VoidPointer>::node_type_t* get(const iterator<T,Value,VoidPointer>& it)
- {
- return stable_vector_detail::get_pointer(it.pn);
- }
-};
-*/
-
 template<class Allocator, unsigned int Version>
 struct select_multiallocation_chain
 {
@@ -415,11 +324,10 @@
 struct select_multiallocation_chain<Allocator, 1>
 {
    typedef typename Allocator::template
- rebind<void>::other::pointer void_ptr;
- typedef containers_detail::basic_multiallocation_cached_slist<void_ptr> multialloc_cached;
- typedef containers_detail::basic_multiallocation_cached_counted_slist
- <multialloc_cached> multialloc_cached_counted;
- typedef boost::interprocess_container::containers_detail::transform_multiallocation_chain
+ rebind<void>::other::pointer void_ptr;
+ typedef containers_detail::basic_multiallocation_chain
+ <void_ptr> multialloc_cached_counted;
+ typedef boost::container::containers_detail::transform_multiallocation_chain
       <multialloc_cached_counted, typename Allocator::value_type> type;
 };
 
@@ -438,9 +346,37 @@
 
 /// @endcond
 
-template<typename T,typename Allocator=std::allocator<T> >
+//!Help taken from ( Introducing stable_vector)
+//!
+//!We present stable_vector, a fully STL-compliant stable container that provides
+//!most of the features of std::vector except element contiguity.
+//!
+//!General properties: stable_vector satisfies all the requirements of a container,
+//!a reversible container and a sequence and provides all the optional operations
+//!present in std::vector. Like std::vector, iterators are random access.
+//!stable_vector does not provide element contiguity; in exchange for this absence,
+//!the container is stable, i.e. references and iterators to an element of a stable_vector
+//!remain valid as long as the element is not erased, and an iterator that has been
+//!assigned the return value of end() always remain valid until the destruction of
+//!the associated stable_vector.
+//!
+//!Operation complexity: The big-O complexities of stable_vector operations match
+//!exactly those of std::vector. In general, insertion/deletion is constant time at
+//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
+//!does not internally perform any value_type destruction, copy or assignment
+//!operations other than those exactly corresponding to the insertion of new
+//!elements or deletion of stored elements, which can sometimes compensate in terms
+//!of performance for the extra burden of doing more pointer manipulation and an
+//!additional allocation per element.
+//!
+//!Exception safety: As stable_vector does not internally copy elements around, some
+//!operations provide stronger exception safety guarantees than in std::vector:
+template<typename T, typename Allocator>
 class stable_vector
 {
+ ///@cond
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    typedef typename Allocator::template
       rebind<void>::other::pointer void_ptr;
    typedef typename Allocator::template
@@ -455,7 +391,7 @@
       rebind<node_type_base_t>::other::pointer node_type_base_ptr_t;
    typedef
    #if defined (STABLE_VECTOR_USE_CONTAINERS_VECTOR)
- ::boost::interprocess_container::
+ ::boost::container::
    #else
    ::std::
    #endif //STABLE_VECTOR_USE_CONTAINERS_VECTOR
@@ -466,12 +402,12 @@
    typedef typename impl_type::iterator impl_iterator;
    typedef typename impl_type::const_iterator const_impl_iterator;
 
- typedef ::boost::interprocess_container::containers_detail::
+ typedef ::boost::container::containers_detail::
       integral_constant<unsigned, 1> allocator_v1;
- typedef ::boost::interprocess_container::containers_detail::
+ typedef ::boost::container::containers_detail::
       integral_constant<unsigned, 2> allocator_v2;
- typedef ::boost::interprocess_container::containers_detail::integral_constant
- <unsigned, boost::interprocess_container::containers_detail::
+ typedef ::boost::container::containers_detail::integral_constant
+ <unsigned, boost::container::containers_detail::
       version<Allocator>::value> alloc_version;
    typedef typename Allocator::
       template rebind<node_type_t>::other node_allocator_type;
@@ -495,8 +431,10 @@
    { get_al().deallocate_one(p); }
 
    friend class stable_vector_detail::clear_on_destroy<stable_vector>;
-
+ ///@endcond
    public:
+
+
    // types:
 
    typedef typename Allocator::reference reference;
@@ -504,9 +442,9 @@
    typedef typename Allocator::pointer pointer;
    typedef typename Allocator::const_pointer const_pointer;
    typedef stable_vector_detail::iterator
- <T,T, pointer> iterator;
+ <T,T&, pointer> iterator;
    typedef stable_vector_detail::iterator
- <T,const T, const_pointer> const_iterator;
+ <T,const T&, const_pointer> const_iterator;
    typedef typename impl_type::size_type size_type;
    typedef typename iterator::difference_type difference_type;
    typedef T value_type;
@@ -514,16 +452,17 @@
    typedef std::reverse_iterator<iterator> reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
 
+ ///@cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(stable_vector)
    static const size_type ExtraPointers = 3;
    typedef typename stable_vector_detail::
       select_multiallocation_chain
       < node_allocator_type
       , alloc_version::value
>::type multiallocation_chain;
-
+ ///@endcond
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(stable_vector)
 
    // construct/copy/destroy:
    explicit stable_vector(const Allocator& al=Allocator())
@@ -541,7 +480,7 @@
       cod.release();
    }
 
- stable_vector(size_type n,const T& t=T(),const Allocator& al=Allocator())
+ stable_vector(size_type n, const T& t, const Allocator& al=Allocator())
    : internal_data(al),impl(al)
    {
       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
@@ -579,7 +518,7 @@
       clear_pool();
    }
 
- stable_vector& operator=(const stable_vector &x)
+ stable_vector& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(stable_vector) x)
    {
       STABLE_VECTOR_CHECK_INVARIANT;
       if (this != &x) {
@@ -605,7 +544,7 @@
 
    void assign(size_type n,const T& t)
    {
- typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
       return assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
    }
 
@@ -697,99 +636,6 @@
       }
    }
 
- void clear_pool(allocator_v1)
- {
- if(!impl.empty() && impl.back()){
- void_ptr &p1 = *(impl.end()-2);
- void_ptr &p2 = impl.back();
-
- multiallocation_chain holder(p1, p2, this->internal_data.pool_size);
- while(!holder.empty()){
- node_type_ptr_t n = holder.front();
- holder.pop_front();
- this->deallocate_one(n);
- }
- p1 = p2 = 0;
- this->internal_data.pool_size = 0;
- }
- }
-
- void clear_pool(allocator_v2)
- {
-
- if(!impl.empty() && impl.back()){
- void_ptr &p1 = *(impl.end()-2);
- void_ptr &p2 = impl.back();
- multiallocation_chain holder(p1, p2, this->internal_data.pool_size);
- get_al().deallocate_individual(boost::interprocess::move(holder));
- p1 = p2 = 0;
- this->internal_data.pool_size = 0;
- }
- }
-
- void clear_pool()
- {
- this->clear_pool(alloc_version());
- }
-
- void add_to_pool(size_type n)
- {
- this->add_to_pool(n, alloc_version());
- }
-
- void add_to_pool(size_type n, allocator_v1)
- {
- size_type remaining = n;
- while(remaining--){
- this->put_in_pool(this->allocate_one());
- }
- }
-
- void add_to_pool(size_type n, allocator_v2)
- {
- void_ptr &p1 = *(impl.end()-2);
- void_ptr &p2 = impl.back();
- multiallocation_chain holder(p1, p2, this->internal_data.pool_size);
- BOOST_STATIC_ASSERT((boost::interprocess::is_movable<multiallocation_chain>::value == true));
- multiallocation_chain m (get_al().allocate_individual(n));
- holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
- this->internal_data.pool_size += n;
- std::pair<void_ptr, void_ptr> data(holder.extract_data());
- p1 = data.first;
- p2 = data.second;
- }
-
- void put_in_pool(node_type_ptr_t p)
- {
- void_ptr &p1 = *(impl.end()-2);
- void_ptr &p2 = impl.back();
- multiallocation_chain holder(p1, p2, internal_data.pool_size);
- holder.push_front(p);
- ++this->internal_data.pool_size;
- std::pair<void_ptr, void_ptr> ret(holder.extract_data());
- p1 = ret.first;
- p2 = ret.second;
- }
-
- node_type_ptr_t get_from_pool()
- {
- if(!impl.back()){
- return node_type_ptr_t(0);
- }
- else{
- void_ptr &p1 = *(impl.end()-2);
- void_ptr &p2 = impl.back();
- multiallocation_chain holder(p1, p2, internal_data.pool_size);
- node_type_ptr_t ret = holder.front();
- holder.pop_front();
- std::pair<void_ptr, void_ptr> data(holder.extract_data());
- p1 = data.first;
- p2 = data.second;
- --this->internal_data.pool_size;
- return ret;
- }
- }
-
    // element access:
 
    reference operator[](size_type n){return value(impl[n]);}
@@ -823,8 +669,16 @@
 
    // modifiers:
 
- void push_back(const T& t)
- { this->insert(end(), t); }
+ void push_back(insert_const_ref_type x)
+ { return priv_push_back(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_back(T &x) { push_back(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_push_back(u); }
+ #endif
 
    void push_back(BOOST_INTERPROCESS_RV_REF(T) t)
    { this->insert(end(), boost::interprocess::move(t)); }
@@ -832,11 +686,16 @@
    void pop_back()
    { this->erase(this->end()-1); }
 
- iterator insert(const_iterator position, const T& t)
- {
- typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
- return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
- }
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
 
    iterator insert(const_iterator position, BOOST_INTERPROCESS_RV_REF(T) x)
    {
@@ -864,7 +723,7 @@
                         boost::mpl::not_<boost::is_integral<InputIterator> >());
    }
 
- #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... in the end of the vector.
@@ -976,6 +835,118 @@
    /// @cond
    private:
 
+ iterator priv_insert(const_iterator position, const value_type &t)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
+ }
+
+ void priv_push_back(const value_type &t)
+ { this->insert(end(), t); }
+
+ void clear_pool(allocator_v1)
+ {
+ if(!impl.empty() && impl.back()){
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), p1, p2, this->internal_data.pool_size);
+ while(!holder.empty()){
+ node_type_ptr_t n = holder.front();
+ holder.pop_front();
+ this->deallocate_one(n);
+ }
+ p1 = p2 = 0;
+ this->internal_data.pool_size = 0;
+ }
+ }
+
+ void clear_pool(allocator_v2)
+ {
+
+ if(!impl.empty() && impl.back()){
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), p1, p2, internal_data.pool_size);
+ get_al().deallocate_individual(boost::interprocess::move(holder));
+ p1 = p2 = 0;
+ this->internal_data.pool_size = 0;
+ }
+ }
+
+ void clear_pool()
+ {
+ this->clear_pool(alloc_version());
+ }
+
+ void add_to_pool(size_type n)
+ {
+ this->add_to_pool(n, alloc_version());
+ }
+
+ void add_to_pool(size_type n, allocator_v1)
+ {
+ size_type remaining = n;
+ while(remaining--){
+ this->put_in_pool(this->allocate_one());
+ }
+ }
+
+ void add_to_pool(size_type n, allocator_v2)
+ {
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), p1, p2, internal_data.pool_size);
+ BOOST_STATIC_ASSERT((::boost::interprocess::is_movable<multiallocation_chain>::value == true));
+ multiallocation_chain m (get_al().allocate_individual(n));
+ holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
+ this->internal_data.pool_size += n;
+ std::pair<void_ptr, void_ptr> data(holder.extract_data());
+ p1 = data.first;
+ p2 = data.second;
+ }
+
+ void put_in_pool(node_type_ptr_t p)
+ {
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), p1, p2, internal_data.pool_size);
+ holder.push_front(p);
+ ++this->internal_data.pool_size;
+ std::pair<void_ptr, void_ptr> ret(holder.extract_data());
+ p1 = ret.first;
+ p2 = ret.second;
+ }
+
+ node_type_ptr_t get_from_pool()
+ {
+ if(!impl.back()){
+ return node_type_ptr_t(0);
+ }
+ else{
+ void_ptr &p1 = *(impl.end()-2);
+ void_ptr &p2 = impl.back();
+ multiallocation_chain holder;
+ holder.incorporate_after(holder.before_begin(), p1, p2, internal_data.pool_size);
+ node_type_ptr_t ret = holder.front();
+ holder.pop_front();
+ --this->internal_data.pool_size;
+ if(!internal_data.pool_size){
+ p1 = p2 = 0;
+ }
+ else{
+ std::pair<void_ptr, void_ptr> data(holder.extract_data());
+ p1 = data.first;
+ p2 = data.second;
+ }
+ return ret;
+ }
+ }
+
    void insert_iter_prolog(size_type n, difference_type d)
    {
       initialize_end_node(n);
@@ -1009,7 +980,7 @@
    template<typename Integer>
    void assign_dispatch(Integer n, Integer t, boost::mpl::true_)
    {
- typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
       this->assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
    }
 
@@ -1039,8 +1010,8 @@
 
    template<class AllocatorVersion>
    iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
- typename boost::interprocess_container::containers_detail::enable_if_c
- <boost::interprocess_container::containers_detail::is_same<AllocatorVersion, allocator_v2>
+ typename boost::container::containers_detail::enable_if_c
+ <boost::container::containers_detail::is_same<AllocatorVersion, allocator_v2>
             ::value>::type * = 0)
    {
       STABLE_VECTOR_CHECK_INVARIANT;
@@ -1098,7 +1069,7 @@
    {
       node_type_ptr_t p = this->allocate_one();
       try{
- boost::interprocess_container::construct_in_place(&*p, it);
+ boost::container::construct_in_place(&*p, it);
          p->set_pointer(up);
       }
       catch(...){
@@ -1125,7 +1096,7 @@
 
    void insert_not_iter(const_iterator position, size_type n, const T& t)
    {
- typedef stable_vector_detail::constant_iterator<value_type, difference_type> cvalue_iterator;
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
       this->insert_iter(position, cvalue_iterator(t, n), cvalue_iterator(), std::forward_iterator_tag());
    }
 
@@ -1189,7 +1160,7 @@
             p = mem.front();
             mem.pop_front();
             //This can throw
- boost::interprocess_container::construct_in_place(&*p, first);
+ boost::container::construct_in_place(&*p, first);
             p->set_pointer(void_ptr((void*)(&*(it + i))));
             ++first;
             *(it + i) = p;
@@ -1218,7 +1189,7 @@
                break;
             }
             //This can throw
- boost::interprocess_container::construct_in_place(&*p, first);
+ boost::container::construct_in_place(&*p, first);
             p->set_pointer(void_ptr(&*(it+i)));
             ++first;
             *(it+i)=p;
@@ -1234,9 +1205,9 @@
    }
 
    template <class InputIterator>
- void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::false_)
+ void insert_iter(const_iterator position, InputIterator first, InputIterator last, boost::mpl::false_)
    {
- this->insert_not_iter(position,first,last);
+ this->insert_not_iter(position, first, last);
    }
 
    static void swap_impl(stable_vector& x,stable_vector& y)
@@ -1353,4 +1324,6 @@
 
 }}
 
-#endif
+#include <boost/interprocess/containers/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_STABLE_VECTOR_HPP

Modified: trunk/boost/interprocess/containers/container/string.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/string.hpp (original)
+++ trunk/boost/interprocess/containers/container/string.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -8,7 +8,7 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 //
-// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2008
+// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2009
 // Renaming, isolating and porting to generic algorithms. Pointer typedef
 // set to allocator::pointer to allow placing it in shared memory.
 //
@@ -31,7 +31,7 @@
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
 
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <boost/interprocess/containers/container/detail/utilities.hpp>
 #include <boost/interprocess/containers/container/detail/iterators.hpp>
 #include <boost/interprocess/containers/container/detail/algorithms.hpp>
@@ -59,12 +59,12 @@
 #include <boost/detail/no_exceptions_support.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
+namespace container {
 #else
 namespace boost {
-namespace interprocess_container {
+namespace container {
 #endif
 
 /// @cond
@@ -83,12 +83,9 @@
 class basic_string_base
 {
    basic_string_base();
- basic_string_base(basic_string_base&);
- basic_string_base & operator=(basic_string_base&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_string_base)
 
  public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_string_base)
-
    typedef A allocator_type;
    //! The stored allocator type
    typedef allocator_type stored_allocator_type;
@@ -256,7 +253,7 @@
    typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
    typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
    typedef containers_detail::integral_constant<unsigned,
- boost::interprocess_container::containers_detail::version<A>::value> alloc_version;
+ boost::container::containers_detail::version<A>::value> alloc_version;
 
    std::pair<pointer, bool>
       allocation_command(allocation_type command,
@@ -448,6 +445,7 @@
 {
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(basic_string)
    typedef containers_detail::basic_string_base<A> base_t;
    static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
 
@@ -485,7 +483,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_string)
 
    //! The allocator type
    typedef A allocator_type;
@@ -621,7 +618,7 @@
    //! <b>Postcondition</b>: x == *this.
    //!
    //! <b>Complexity</b>: Linear to the elements x contains.
- basic_string& operator=(const basic_string& s)
+ basic_string& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(basic_string) s)
    {
       if (&s != this)
          this->assign(s.begin(), s.end());
@@ -1874,6 +1871,22 @@
    /// @endcond
 };
 
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+ <char
+ ,std::char_traits<char>
+ ,std::allocator<char> >
+string;
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+ <wchar_t
+ ,std::char_traits<wchar_t>
+ ,std::allocator<wchar_t> >
+wstring;
+
 /// @cond
 
 template <class CharT, class Traits, class A>
@@ -2301,17 +2314,16 @@
 /// @cond
 
 namespace boost {
-namespace interprocess {
-
+/*
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class C, class T, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::basic_string<C, T, A> >
+struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, A> >
 {
    static const bool value = has_trivial_destructor<A>::value;
 };
-
-}}
+*/
+}
 
 /// @endcond
 

Modified: trunk/boost/interprocess/containers/container/vector.hpp
==============================================================================
--- trunk/boost/interprocess/containers/container/vector.hpp (original)
+++ trunk/boost/interprocess/containers/container/vector.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -45,6 +45,7 @@
 
 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/workaround.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 
 #include <cstddef>
 #include <memory>
@@ -64,19 +65,14 @@
 #include <boost/interprocess/containers/container/detail/iterators.hpp>
 #include <boost/interprocess/containers/container/detail/algorithms.hpp>
 #include <boost/interprocess/containers/container/detail/destroyers.hpp>
-#include <boost/interprocess/containers/container/containers_fwd.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/pointer_to_other.hpp>
 #include <boost/interprocess/containers/container/detail/mpl.hpp>
 #include <boost/interprocess/containers/container/detail/advanced_insert_int.hpp>
 
-#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
 namespace boost {
-namespace interprocess {
-#else
-namespace boost {
-namespace interprocess_container {
-#endif
+namespace container {
 
 /// @cond
 
@@ -95,10 +91,10 @@
                           ,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>::value_type value_type;
    typedef typename std::iterator_traits<Pointer>::difference_type difference_type;
    typedef typename boost::pointer_to_other<Pointer, value_type>::type pointer;
- typedef value_type& reference;
+ typedef const value_type& reference;
 
    /// @cond
    protected:
@@ -245,8 +241,8 @@
    typedef T value_type;
    typedef A allocator_type;
    static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move =
- boost::interprocess::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_dctr_after_move = false;
+ //::boost::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;
@@ -288,11 +284,6 @@
       : members_(a)
    {}
 
- //Constructor, does not throw
- vector_alloc_holder(const vector_alloc_holder<A> &h)
- : members_(h.alloc())
- {}
-
    //Destructor
    ~vector_alloc_holder()
    {
@@ -303,7 +294,7 @@
    typedef containers_detail::integral_constant<unsigned, 1> allocator_v1;
    typedef containers_detail::integral_constant<unsigned, 2> allocator_v2;
    typedef containers_detail::integral_constant<unsigned,
- boost::interprocess_container::containers_detail::version<A>::value> alloc_version;
+ boost::container::containers_detail::version<A>::value> alloc_version;
    std::pair<pointer, bool>
       allocation_command(allocation_type command,
                          size_type limit_size,
@@ -361,6 +352,12 @@
       size_type m_capacity;
    } members_;
 
+ A &alloc()
+ { return members_; }
+
+ const A &alloc() const
+ { return members_; }
+
    protected:
    void prot_deallocate()
    {
@@ -388,23 +385,17 @@
       this->destroy_n(containers_detail::get_pointer(this->members_.m_start), this->members_.m_size);
       this->members_.m_size = 0;
    }
-
- A &alloc()
- { return members_; }
-
- const A &alloc() const
- { return members_; }
 };
 
 } //namespace containers_detail {
 /// @endcond
 
-//! \class ::boost::interprocess::vector boost/interprocess/containers/container/vector.hpp <boost/interprocess/containers/vector.hpp>
+//! \class vector
 //! A vector is a sequence that supports random access to elements, constant
 //! time insertion and removal of elements at the end, and linear time insertion
 //! and removal of elements at the beginning or in the middle. The number of
 //! elements in a vector may vary dynamically; memory management is automatic.
-//! boost::interprocess_container::vector is similar to std::vector but it's compatible
+//! boost::container::vector is similar to std::vector but it's compatible
 //! with shared memory and memory mapped files.
 template <class T, class A>
 class vector : private containers_detail::vector_alloc_holder<A>
@@ -412,6 +403,8 @@
    /// @cond
    typedef vector<T, A> self_t;
    typedef containers_detail::vector_alloc_holder<A> base_t;
+ typedef typename containers_detail::
+ move_const_ref_type<T>::type insert_const_ref_type;
    /// @endcond
    public:
    //! The type of object, T, stored in the vector
@@ -446,6 +439,7 @@
 
    /// @cond
    private:
+ BOOST_COPYABLE_AND_MOVABLE(vector)
    typedef containers_detail::advanced_insert_aux_int<T, T*> advanced_insert_aux_int_t;
    typedef containers_detail::vector_value_traits<value_type, A> value_traits;
 
@@ -459,7 +453,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(vector)
 
    //! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
    //!
@@ -498,7 +491,7 @@
    //!
    //! <b>Complexity</b>: Linear to the elements x contains.
    vector(const vector<T, A>& x)
- : base_t((base_t&)x)
+ : base_t(static_cast<const base_t&>(x).alloc())
    { *this = x; }
 
    //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
@@ -507,7 +500,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    vector(BOOST_INTERPROCESS_RV_REF(vector) mx)
- : base_t(boost::interprocess::move(mx))
+ : base_t(static_cast<base_t&>(mx).alloc())
    { this->swap(mx); }
 
    //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
@@ -816,7 +809,7 @@
             //We will reuse insert code, so create a dummy input iterator
             T *dummy_it(containers_detail::get_pointer(this->members_.m_start));
             containers_detail::advanced_insert_aux_proxy<T, boost::interprocess::move_iterator<T*>, T*>
- proxy(boost::interprocess::make_move_iterator(dummy_it), boost::interprocess::make_move_iterator(dummy_it));
+ proxy(::boost::interprocess::make_move_iterator(dummy_it), ::boost::interprocess::make_move_iterator(dummy_it));
             //Backwards (and possibly forward) expansion
             if(ret.second){
                #ifdef BOOST_CONTAINERS_VECTOR_ALLOC_STATS
@@ -853,7 +846,7 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in x.
- vector& operator=(const vector& x)
+ vector& operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(vector) x)
    {
       if (&x != this){
          this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size);
@@ -868,7 +861,7 @@
    //!
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
- //! <b>Complexity</b>: Constant.
+ //! <b>Complexity</b>: Linear.
    vector& operator=(BOOST_INTERPROCESS_RV_REF(vector) x)
    {
       if (&x != this){
@@ -907,17 +900,16 @@
    //! T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- void push_back(const T& x)
- {
- if (this->members_.m_size < this->members_.m_capacity){
- //There is more memory, just construct a new object at the end
- new((void*)(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size))value_type(x);
- ++this->members_.m_size;
- }
- else{
- this->insert(this->cend(), x);
- }
- }
+ void push_back(insert_const_ref_type x)
+ { return priv_push_back(x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ void push_back(T &x) { push_back(const_cast<const T &>(x)); }
+
+ template<class U>
+ void push_back(const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return priv_push_back(u); }
+ #endif
 
    //! <b>Effects</b>: Constructs a new element in the end of the vector
    //! and moves the resources of mx to this new element.
@@ -937,7 +929,7 @@
       }
    }
 
- #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ #if defined(BOOST_CONTAINERS_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Inserts an object of type T constructed with
    //! std::forward<Args>(args)... in the end of the vector.
@@ -1067,13 +1059,16 @@
    //!
    //! <b>Complexity</b>: If position is end(), amortized constant time
    //! Linear time otherwise.
- iterator insert(const_iterator position, const T& x)
- {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position, (size_type)1, x);
- return iterator(this->members_.m_start + pos_n);
- }
+ iterator insert(const_iterator position, insert_const_ref_type x)
+ { return this->priv_insert(position, x); }
+
+ #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
+
+ template<class U>
+ iterator insert(const_iterator position, const U &u, typename containers_detail::enable_if_c<containers_detail::is_same<T, U>::value && !::boost::interprocess::is_movable<U>::value >::type* =0)
+ { return this->priv_insert(position, u); }
+ #endif
 
    //! <b>Requires</b>: position must be a valid iterator of *this.
    //!
@@ -1217,8 +1212,6 @@
    void clear()
    { this->prot_destroy_all(); }
 
- /// @cond
-
    //! <b>Effects</b>: Tries to deallocate the excess of memory created
    //! with previous allocations. The size of the vector is unchanged
    //!
@@ -1228,7 +1221,29 @@
    void shrink_to_fit()
    { priv_shrink_to_fit(alloc_version()); }
 
+ /// @cond
+
    private:
+ iterator priv_insert(const_iterator position, const T &x)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ this->insert(position, (size_type)1, x);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ void priv_push_back(const T &x)
+ {
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)(containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size))value_type(x);
+ ++this->members_.m_size;
+ }
+ else{
+ this->insert(this->cend(), x);
+ }
+ }
+
    void priv_shrink_to_fit(allocator_v1)
    {
       if(this->members_.m_capacity){
@@ -1345,7 +1360,7 @@
       if (elems_after > n){
          //New elements can be just copied.
          //Move to uninitialized memory last objects
- boost::interprocess::uninitialized_move(old_finish - n, old_finish, old_finish);
+ ::boost::interprocess::uninitialized_move(old_finish - n, old_finish, old_finish);
          this->members_.m_size += n;
          //Copy previous to last objects to the initialized end
          boost::interprocess::move_backward(pos, old_finish - n, old_finish);
@@ -1358,7 +1373,7 @@
          interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
          this->members_.m_size += n - elems_after;
          //Copy old [pos, end()) elements to the uninitialized memory
- boost::interprocess::uninitialized_move
+ ::boost::interprocess::uninitialized_move
             ( pos, old_finish, containers_detail::get_pointer(this->members_.m_start) + this->members_.m_size);
          this->members_.m_size += elems_after;
          //Copy first new elements in pos
@@ -1380,7 +1395,7 @@
       //the start of the new buffer
       T *old_buffer = containers_detail::get_pointer(this->members_.m_start);
       if(old_buffer){
- new_finish = boost::interprocess::uninitialized_move
+ new_finish = ::boost::interprocess::uninitialized_move
             (containers_detail::get_pointer(this->members_.m_start), pos, old_finish = new_finish);
          constructed_values_destroyer.increment_size(new_finish - old_finish);
       }
@@ -1391,7 +1406,7 @@
       //Initialize from the rest of the old buffer,
       //starting from previous point
       if(old_buffer){
- new_finish = boost::interprocess::uninitialized_move
+ new_finish = ::boost::interprocess::uninitialized_move
             (pos, old_buffer + this->members_.m_size, new_finish);
          //Destroy and deallocate old elements
          //If there is allocated memory, destroy and deallocate
@@ -1432,7 +1447,7 @@
       //Check if s_before is big enough to hold the beginning of old data + new data
       if(difference_type(s_before) >= difference_type(elemsbefore + n)){
          //Copy first old values before pos, after that the new objects
- boost::interprocess::uninitialized_move(old_start, pos, new_start);
+ ::boost::interprocess::uninitialized_move(old_start, pos, new_start);
          this->members_.m_size = elemsbefore;
          interf.uninitialized_copy_all_to(new_start + elemsbefore);
          this->members_.m_size += n;
@@ -1450,7 +1465,7 @@
             //|___________|__________|_________|________________________|
             //
             //Now initialize the rest of memory with the last old values
- boost::interprocess::uninitialized_move
+ ::boost::interprocess::uninitialized_move
                (pos, old_finish, new_start + elemsbefore + n);
             //All new elements correctly constructed, avoid new element destruction
             this->members_.m_size = old_size + n;
@@ -1477,7 +1492,7 @@
             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_move(pos, pos + raw_gap, new_start + elemsbefore + n);
+ ::boost::interprocess::uninitialized_move(pos, pos + raw_gap, new_start + elemsbefore + n);
             //Update size since we have a contiguous buffer
             this->members_.m_size = old_size + s_before;
             //All new elements correctly constructed, avoid old element destruction
@@ -1542,7 +1557,7 @@
             //
             //Copy the first part of old_begin to raw_mem
             T *start_n = old_start + difference_type(s_before);
- boost::interprocess::uninitialized_move(old_start, start_n, new_start);
+ ::boost::interprocess::uninitialized_move(old_start, start_n, new_start);
             //The buffer is all constructed until old_end,
             //release destroyer and update size
             old_values_destroyer.release();
@@ -1594,7 +1609,7 @@
             //|___________|_____|_________|__________________________|
             //
             //First copy whole old_begin and part of new to raw_mem
- boost::interprocess::uninitialized_move(old_start, pos, new_start);
+ ::boost::interprocess::uninitialized_move(old_start, pos, new_start);
             this->members_.m_size = elemsbefore;
 
             const size_type mid_n = difference_type(s_before) - elemsbefore;
@@ -1664,7 +1679,7 @@
                //
                //First copy the part of old_end raw_mem
                T* finish_n = old_finish - difference_type(n_after);
- boost::interprocess::uninitialized_move(finish_n, old_finish, old_finish);
+ ::boost::interprocess::uninitialized_move(finish_n, old_finish, old_finish);
                this->members_.m_size += n_after;
                //Displace the rest of old_end to the new position
                boost::interprocess::move_backward(pos, finish_n, old_finish);
@@ -1690,7 +1705,7 @@
                //The new_end part is [first + (n - n_after), last)
                interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
                this->members_.m_size += mid_last_dist;
- boost::interprocess::uninitialized_move(pos, old_finish, old_finish + mid_last_dist);
+ ::boost::interprocess::uninitialized_move(pos, old_finish, old_finish + mid_last_dist);
                this->members_.m_size += n_after - mid_last_dist;
                //Now copy the part of new_end over constructed elements
                interf.copy_all_to(pos);
@@ -1774,14 +1789,14 @@
             T *end = std::copy(first, mid, start);
             //Initialize the remaining new elements in the uninitialized memory
             // iG std::uninitialized_copy(mid, last, end);
- boost::interprocess::uninitialized_copy_or_move(mid, last, end);
+ ::boost::interprocess::uninitialized_copy_or_move(mid, last, end);
             this->members_.m_size = n;
          }
       }
       else if(!ret.second){
          typename value_traits::UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
          // iG std::uninitialized_copy(first, last, containers_detail::get_pointer(ret.first));
- boost::interprocess::uninitialized_copy_or_move(first, last, containers_detail::get_pointer(ret.first));
+ ::boost::interprocess::uninitialized_copy_or_move(first, last, containers_detail::get_pointer(ret.first));
          scoped_alloc.release();
          //Destroy and deallocate old buffer
          if(this->members_.m_start != 0){
@@ -1811,7 +1826,7 @@
          FwdIt mid = first;
          std::advance(mid, first_count);
          // iG std::uninitialized_copy(first, mid, containers_detail::get_pointer(ret.first));
- boost::interprocess::uninitialized_copy_or_move(first, mid, containers_detail::get_pointer(ret.first));
+ ::boost::interprocess::uninitialized_copy_or_move(first, mid, containers_detail::get_pointer(ret.first));
 
          if(old_offset > n){
             //All old elements will be destroyed by "old_values_destroyer"
@@ -1923,17 +1938,20 @@
 /// @cond
 
 namespace boost {
-namespace interprocess {
+
+/*
 
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class A>
-struct has_trivial_destructor_after_move<boost::interprocess_container::vector<T, A> >
+struct has_trivial_destructor_after_move<boost::container::vector<T, A> >
 {
    static const bool value = has_trivial_destructor<A>::value;
 };
 
-}}
+*/
+
+}
 
 /// @endcond
 

Added: trunk/boost/interprocess/containers/containers_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/containers/containers_fwd.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,38 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_CONTAINERS_CONTAINERS_FWD_HPP
+#define BOOST_INTERPROCESS_CONTAINERS_CONTAINERS_FWD_HPP
+
+/// @cond
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// Standard predeclarations
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/containers/container/container_fwd.hpp>
+
+namespace boost {
+namespace interprocess {
+
+using boost::container::ordered_range;
+using boost::container::ordered_unique_range;
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_CONTAINERS_FWD_HPP

Modified: trunk/boost/interprocess/containers/deque.hpp
==============================================================================
--- trunk/boost/interprocess/containers/deque.hpp (original)
+++ trunk/boost/interprocess/containers/deque.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,11 +17,12 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/deque.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::deque;
+using boost::container::deque;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/flat_map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/flat_map.hpp (original)
+++ trunk/boost/interprocess/containers/flat_map.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,12 +17,13 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/flat_map.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::flat_map;
-using boost::interprocess_container::flat_multimap;
+using boost::container::flat_map;
+using boost::container::flat_multimap;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/flat_set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/flat_set.hpp (original)
+++ trunk/boost/interprocess/containers/flat_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,12 +17,13 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/flat_set.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::flat_set;
-using boost::interprocess_container::flat_multiset;
+using boost::container::flat_set;
+using boost::container::flat_multiset;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/list.hpp
==============================================================================
--- trunk/boost/interprocess/containers/list.hpp (original)
+++ trunk/boost/interprocess/containers/list.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,11 +17,12 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/list.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::list;
+using boost::container::list;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/map.hpp
==============================================================================
--- trunk/boost/interprocess/containers/map.hpp (original)
+++ trunk/boost/interprocess/containers/map.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,12 +17,13 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/map.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::map;
-using boost::interprocess_container::multimap;
+using boost::container::map;
+using boost::container::multimap;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/pair.hpp
==============================================================================
--- trunk/boost/interprocess/containers/pair.hpp (original)
+++ trunk/boost/interprocess/containers/pair.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,11 +17,12 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/detail/pair.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::containers_detail::pair;
+using boost::container::containers_detail::pair;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/set.hpp
==============================================================================
--- trunk/boost/interprocess/containers/set.hpp (original)
+++ trunk/boost/interprocess/containers/set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,12 +17,13 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/set.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::set;
-using boost::interprocess_container::multiset;
+using boost::container::set;
+using boost::container::multiset;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/slist.hpp
==============================================================================
--- trunk/boost/interprocess/containers/slist.hpp (original)
+++ trunk/boost/interprocess/containers/slist.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,11 +17,12 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/slist.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::slist;
+using boost::container::slist;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/stable_vector.hpp
==============================================================================
--- trunk/boost/interprocess/containers/stable_vector.hpp (original)
+++ trunk/boost/interprocess/containers/stable_vector.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,11 +17,12 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/stable_vector.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
    namespace interprocess {
 
- using boost::interprocess_container::stable_vector;
+ using boost::container::stable_vector;
 
    } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/string.hpp
==============================================================================
--- trunk/boost/interprocess/containers/string.hpp (original)
+++ trunk/boost/interprocess/containers/string.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,12 +17,13 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/string.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::basic_string;
-using boost::interprocess_container::string;
+using boost::container::basic_string;
+using boost::container::string;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/vector.hpp
==============================================================================
--- trunk/boost/interprocess/containers/vector.hpp (original)
+++ trunk/boost/interprocess/containers/vector.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -17,11 +17,12 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/containers/container/vector.hpp>
+#include <boost/interprocess/containers/containers_fwd.hpp>
 
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::vector;
+using boost::container::vector;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/containers/version_type.hpp
==============================================================================
--- trunk/boost/interprocess/containers/version_type.hpp (original)
+++ trunk/boost/interprocess/containers/version_type.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -21,8 +21,8 @@
 namespace boost {
 namespace interprocess {
 
-using boost::interprocess_container::containers_detail::version_type;
-using boost::interprocess_container::containers_detail::version;
+using boost::container::containers_detail::version_type;
+using boost::container::containers_detail::version;
 
 } //namespace interprocess {
 } //namespace boost {

Modified: trunk/boost/interprocess/creation_tags.hpp
==============================================================================
--- trunk/boost/interprocess/creation_tags.hpp (original)
+++ trunk/boost/interprocess/creation_tags.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/atomic.hpp
==============================================================================
--- trunk/boost/interprocess/detail/atomic.hpp (original)
+++ trunk/boost/interprocess/detail/atomic.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 // (C) Copyright Markus Schoepflin 2007
 //
 // Distributed under the Boost Software License, Version 1.0. (See
@@ -303,7 +303,7 @@
 //! Returns the old value of *mem
 inline boost::uint32_t atomic_cas32
    (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), with, cmp); }
+{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with); }
 
 //! Atomically set an boost::uint32_t in memory
 //! "mem": pointer to the object
@@ -559,6 +559,25 @@
 
 #endif
 
+namespace boost{
+namespace interprocess{
+namespace detail{
+
+inline bool atomic_add_unless32
+ (volatile boost::uint32_t *mem, boost::uint32_t value, volatile boost::uint32_t unless_this)
+{
+ boost::uint32_t old, c(atomic_read32(mem));
+ while(c != unless_this && (old = atomic_cas32(mem, c + value, c)) != c){
+ c = old;
+ }
+ return c != unless_this;
+}
+
+} //namespace detail
+} //namespace interprocess
+} //namespace boost
+
+
 #include <boost/interprocess/detail/config_end.hpp>
 
 #endif //BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP

Modified: trunk/boost/interprocess/detail/cast_tags.hpp
==============================================================================
--- trunk/boost/interprocess/detail/cast_tags.hpp (original)
+++ trunk/boost/interprocess/detail/cast_tags.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/config_begin.hpp
==============================================================================
--- trunk/boost/interprocess/detail/config_begin.hpp (original)
+++ trunk/boost/interprocess/detail/config_begin.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/config_end.hpp
==============================================================================
--- trunk/boost/interprocess/detail/config_end.hpp (original)
+++ trunk/boost/interprocess/detail/config_end.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/file_wrapper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/file_wrapper.hpp (original)
+++ trunk/boost/interprocess/detail/file_wrapper.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -25,11 +25,9 @@
 class file_wrapper
 {
    /// @cond
- file_wrapper(file_wrapper&);
- file_wrapper & operator=(file_wrapper&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(file_wrapper)
    /// @endcond
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(file_wrapper)
 
    //!Default constructor.
    //!Represents an empty file_wrapper.

Modified: trunk/boost/interprocess/detail/in_place_interface.hpp
==============================================================================
--- trunk/boost/interprocess/detail/in_place_interface.hpp (original)
+++ trunk/boost/interprocess/detail/in_place_interface.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Added: trunk/boost/interprocess/detail/intermodule_singleton.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/intermodule_singleton.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,165 @@
+/* Copyright 2006-2009 Joaquin M Lopez Munoz.
+ * 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/flyweight for library home page.
+ */
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_HPP
+#define BOOST_INTERPROCESS_INTERMODULE_SINGLETON_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/managed_shared_memory.hpp>
+
+namespace boost{
+namespace interprocess{
+namespace detail{
+
+const char *get_singleton_unique_name()
+{ return "unique_name";
+
+template<typename C>
+struct atomic_functor
+{
+ atomic_functor(managed_shared_memory &seg)
+ : seg_(seg)
+ {}
+
+ inline void operator()()
+ {
+ referenced_instance**pptr = seg.find_or_construct<referenced_instance*>(unique_instance)();
+ detail::atomic_cas32(
+ }
+
+ managed_shared_memory &seg_;
+};
+
+template<class C>
+struct intermodule_singleton_instantiator
+{
+ intermodule_singleton_instantiator()
+ : ppref(0), pc(0)
+ {
+
+ bool done = false;
+ try{
+ managed_shared_memory seg(interprocess::create_only, get_singleton_unique_name(), 16384);
+ //Register cleanup??? We can't because the address of a local function might be the
+ //address of a dll, and that dll can be UNLOADED!!!
+ }
+ catch(interprocess_exception &ex){
+ if(ex.get_error_code() != already_exists_error){
+ managed_shared_memory seg(open_only, "unique_name", 16384);
+ seg.find_or_construct<referenced_instance*>(unique_instance)();
+ }
+ else{
+ throw;
+ }
+ }
+
+ {
+ ppref=seg.find_or_construct<referenced_instance*>(unique_instance)();
+ if(*ppref){
+ /* As in some OSes Boost.Interprocess memory segments can outlive
+ * their associated processes, there is a possibility that we
+ * retrieve a dangling pointer (coming from a previous aborted run,
+ * for instance). Try to protect against this by checking that
+ * the contents of the pointed object are consistent.
+ */
+ if(std::strcmp(segment_name,(*ppref)->segment_name)!=0){
+ *ppref=0; /* dangling pointer! */
+ }
+ else ++((*ppref)->ref);
+ }
+ }
+ if(!*ppref){
+ std::auto_ptr<referenced_instance> apc(
+ new referenced_instance(segment_name));
+ interprocess::scoped_lock<interprocess::named_mutex> lock(mutex);
+ ppref=seg.find_or_construct<referenced_instance*>(
+ typeid(C).name())((referenced_instance*)0);
+ if(!*ppref)*ppref=apc.release();
+ ++((*ppref)->ref);
+ }
+ pc=&(*ppref)->c;
+ }
+
+ ~intermodule_singleton_instantiator()
+ {
+ /* As in construction time, actual deletion is performed outside the
+ * lock to avoid leaving the lock dangling in case of crash.
+ */
+
+ referenced_instance* pref=0;
+ {
+ interprocess::scoped_lock<interprocess::named_mutex> lock(mutex);
+ if(--((*ppref)->ref)==0){
+ pref=*ppref;
+ *ppref=0;
+ }
+ }
+ if(pref)delete pref;
+ }
+};
+
+template<typename C>
+struct intermodule_singleton
+{
+ static C& get()
+ {
+ static intermodule_singleton_instantiator<C> instance;
+ return instance.get();
+ }
+
+private:
+
+ C& get()const{return *pc;}
+
+ private:
+ interprocess::managed_shared_memory seg;
+ struct referenced_instance
+ {
+ referenced_instance(const char* segment_name_):ref(0)
+ {
+ std::strcpy(segment_name,segment_name_);
+ }
+
+ ~referenced_instance(){segment_name[0]='\0';}
+
+ char segment_name[128]; /* used to detect dangling pointers */
+ mutable long ref;
+ C c;
+ }** ppref;
+ C* pc;
+ };
+};
+
+template<typename C>
+inline void atomic_functor<C>::operator()()
+{
+ referenced_instance *pptr = seg.find_or_construct<referenced_instance>(unique_instance)();
+};
+
+
+} //namespace detail{
+} //namespace interprocess{
+} //namespace boost{
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif

Modified: trunk/boost/interprocess/detail/interprocess_tester.hpp
==============================================================================
--- trunk/boost/interprocess/detail/interprocess_tester.hpp (original)
+++ trunk/boost/interprocess/detail/interprocess_tester.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/intersegment_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/detail/intersegment_ptr.hpp (original)
+++ trunk/boost/interprocess/detail/intersegment_ptr.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/managed_memory_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_memory_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_memory_impl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -263,7 +263,7 @@
    bool belongs_to_segment (const void *ptr) const
    {
       return ptr >= this->get_address() &&
- ptr < (reinterpret_cast<const char*>(ptr) + this->get_size());
+ ptr < (reinterpret_cast<const char*>(this->get_address()) + this->get_size());
    }
 
    //!Transforms previously obtained offset into an absolute address in the

Modified: trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp (original)
+++ trunk/boost/interprocess/detail/managed_multi_shared_memory.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ trunk/boost/interprocess/detail/managed_open_or_create_impl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -37,8 +37,7 @@
 class managed_open_or_create_impl
 {
    //Non-copyable
- managed_open_or_create_impl(managed_open_or_create_impl &);
- managed_open_or_create_impl &operator=(managed_open_or_create_impl &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(managed_open_or_create_impl)
 
    enum
    {
@@ -49,8 +48,6 @@
    };
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(managed_open_or_create_impl)
-
    static const std::size_t
       ManagedOpenOrCreateUserOffset =
          detail::ct_rounded_size

Modified: trunk/boost/interprocess/detail/math_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/math_functions.hpp (original)
+++ trunk/boost/interprocess/detail/math_functions.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 //////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Stephen Cleary 2000.
-// (C) Copyright Ion Gaztanaga 2007-2008.
+// (C) Copyright Ion Gaztanaga 2007-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/interprocess/detail/min_max.hpp
==============================================================================
--- trunk/boost/interprocess/detail/min_max.hpp (original)
+++ trunk/boost/interprocess/detail/min_max.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/interprocess/detail/move.hpp
==============================================================================
--- trunk/boost/interprocess/detail/move.hpp (original)
+++ trunk/boost/interprocess/detail/move.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -19,8 +19,8 @@
 
 //! \file
 
-#ifndef BOOST_INTERPROCESS_MOVE_HPP
-#define BOOST_INTERPROCESS_MOVE_HPP
+#ifndef BOOST_MOVE_HPP
+#define BOOST_MOVE_HPP
 
 #include <boost/config.hpp>
 #include <algorithm> //copy, copy_backward
@@ -28,7 +28,11 @@
 #include <iterator> //std::iterator
 #include <boost/mpl/if.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/mpl/bool.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/utility/addressof.hpp>
+
+/// @cond
 
 namespace boost {
 namespace interprocess {
@@ -52,12 +56,16 @@
    enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
 };
 
-} //namespace move_detail {
 } //namespace interprocess {
+} //namespace move_detail {
 } //namespace boost {
 
+/// @endcond
+
 #if !defined(BOOST_HAS_RVALUE_REFS) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
 
+//#define BOOST_MOVE_ASSIGN_FROM_NON_CONST_RVALUE
+
 namespace boost {
 namespace interprocess {
 
@@ -73,9 +81,6 @@
    ~rv();
    rv(rv const&);
    void operator=(rv const&);
-
- public:
- //T &get() { return *this; }
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -107,25 +112,27 @@
 //////////////////////////////////////////////////////////////////////////////
 template<class T>
 class is_movable
+ : public ::boost::mpl::bool_<move_detail::is_convertible<T, rv<T>&>::value>
 {
- public:
- static const bool value = move_detail::is_convertible<T, rv<T>&>::value;
 };
 
 template<class T>
 class is_movable< rv<T> >
+ : public ::boost::mpl::bool_<false>
 {
- public:
- static const bool value = false;
 };
 
+template <class T>
+struct has_nothrow_move : is_movable<T>
+{};
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // move()
 //
 //////////////////////////////////////////////////////////////////////////////
 template <class T>
-typename boost::disable_if<is_movable<T>, T&>::type move(T& x)
+typename ::boost::disable_if<is_movable<T>, T&>::type move(T& x)
 {
    return x;
 }
@@ -133,13 +140,13 @@
 template <class T>
 typename enable_if<is_movable<T>, rv<T>&>::type move(T& x)
 {
- return reinterpret_cast<rv<T>& >(x);
+ return *static_cast<rv<T>* >(boost::addressof(x));
 }
 
 template <class T>
-typename enable_if<is_movable<T>, rv<T>&>::type move(const rv<T>& x)
+typename enable_if<is_movable<T>, rv<T>&>::type move(rv<T>& x)
 {
- return const_cast<rv<T>& >(x);
+ return x;
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -149,60 +156,120 @@
 //////////////////////////////////////////////////////////////////////////////
 
 template <class T>
-typename enable_if<boost::interprocess::move_detail::is_rv<T>, T &>::type
+typename enable_if< ::boost::interprocess::move_detail::is_rv<T>, T &>::type
    forward(const typename move_detail::identity<T>::type &x)
 {
    return const_cast<T&>(x);
 }
 
-/*
 template <class T>
-typename enable_if<boost::interprocess::move_detail::is_rv<T>, T &>::type
-forward(typename move_detail::identity<T>::type &x)
-{
- return x;
-}
-
-template <class T>
-typename disable_if<boost::interprocess::move_detail::is_rv<T>, T &>::type
- forward(typename move_detail::identity<T>::type &x)
-{
- return x;
-}
-*/
-template <class T>
-typename disable_if<boost::interprocess::move_detail::is_rv<T>, const T &>::type
+typename disable_if< ::boost::interprocess::move_detail::is_rv<T>, const T &>::type
    forward(const typename move_detail::identity<T>::type &x)
 {
    return x;
 }
 
-//////////////////////////////////////////////////////////////////////////////
+#define BOOST_INTERPROCESS_RV_REF(TYPE)\
+ ::boost::interprocess::rv< TYPE >& \
 //
-// BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION
+
+#define BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+ ::boost::interprocess::rv< TYPE<ARG1, ARG2> >& \
 //
-//////////////////////////////////////////////////////////////////////////////
-#define BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(TYPE)\
- operator boost::interprocess::rv<TYPE>&() \
- { return reinterpret_cast<boost::interprocess::rv<TYPE>& >(*this); }\
+
+#define BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+ ::boost::interprocess::rv< TYPE<ARG1, ARG2, ARG3> >& \
 //
 
+#ifdef BOOST_MOVE_ASSIGN_FROM_NON_CONST_RVALUE
 
-#define BOOST_INTERPROCESS_RV_REF(TYPE)\
- boost::interprocess::rv< TYPE >& \
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF(TYPE)\
+ const ::boost::interprocess::rv< TYPE >& \
 //
 
-#define BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
- boost::interprocess::rv< TYPE<ARG1, ARG2> >& \
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+ const ::boost::interprocess::rv< TYPE<ARG1, ARG2> >& \
 //
 
-#define BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
- boost::interprocess::rv< TYPE<ARG1, ARG2, ARG3> >& \
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+ const ::boost::interprocess::rv< TYPE<ARG1, ARG2, ARG3> >& \
+//
+
+#else //BOOST_MOVE_ASSIGN_FROM_NON_CONST_RVALUE
+
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF(TYPE)\
+ const TYPE & \
 //
 
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+ const TYPE< ARG1, ARG2 >& \
+//
+
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+ const TYPE< ARG1, ARG2, ARG3 > & \
+//
+
+#endif
+
 #define BOOST_INTERPROCESS_FWD_REF(TYPE)\
    const TYPE & \
 //
+
+#define BOOST_INTERPROCESS_CATCH_CONST_RLVALUE(TYPE)\
+ const ::boost::interprocess::rv< TYPE >& \
+//
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE
+//
+//////////////////////////////////////////////////////////////////////////////
+#define BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+ private:\
+ TYPE(TYPE &);\
+ TYPE& operator=(TYPE &);\
+ public:\
+ operator ::boost::interprocess::rv<TYPE>&() \
+ { return *reinterpret_cast< ::boost::interprocess::rv<TYPE>* >(this); }\
+ operator const ::boost::interprocess::rv<TYPE>&() const \
+ { return *reinterpret_cast<const ::boost::interprocess::rv<TYPE>* >(this); }\
+ private:\
+//
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// BOOST_COPYABLE_AND_MOVABLE
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef BOOST_MOVE_ASSIGN_FROM_NON_CONST_RVALUE
+
+#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+ public:\
+ TYPE& operator=(TYPE &t)\
+ { this->operator=(static_cast<const ::boost::interprocess::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
+ public:\
+ operator ::boost::interprocess::rv<TYPE>&() \
+ { return *reinterpret_cast< ::boost::interprocess::rv<TYPE>* >(this); }\
+ operator const ::boost::interprocess::rv<TYPE>&() const \
+ { return *reinterpret_cast<const ::boost::interprocess::rv<TYPE>* >(this); }\
+ private:\
+//
+
+#else //#ifdef BOOST_MOVE_ASSIGN_FROM_NON_CONST_RVALUE
+
+#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+ public:\
+ operator ::boost::interprocess::rv<TYPE>&() \
+ { return *reinterpret_cast< ::boost::interprocess::rv<TYPE>* >(this); }\
+ operator const ::boost::interprocess::rv<TYPE>&() const \
+ { return *reinterpret_cast<const ::boost::interprocess::rv<TYPE>* >(this); }\
+ private:\
+//
+
+#endif
+
+
 } //namespace interprocess {
 } //namespace boost
 
@@ -213,6 +280,25 @@
 namespace boost {
 namespace interprocess {
 
+/// @cond
+
+namespace move_detail {
+
+typedef char one;
+struct two {one _[2];};
+
+template <class T>
+struct internal_member_value_traits
+{
+ template <class U> static one test(...);
+ template <class U> static two test(typename U::boost_move_emulation_t* = 0);
+ static const bool value = sizeof(test<T>(0)) == sizeof(two);
+};
+
+} //namespace move_detail {
+
+/// @endcond
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // is_movable
@@ -220,16 +306,23 @@
 //////////////////////////////////////////////////////////////////////////////
 
 //! For compilers with rvalue references, this traits class returns true
-//! if T && is convertible to T.
+//! if BOOST_ENABLE_MOVE_EMULATION is activated.
 //!
-//! For other compilers returns true if T is convertible to <i>boost::interprocess::rv<T>&</i>
+//! For other compilers returns true if T is convertible to <i>::boost::interprocess::rv<T>&</i>
 template<class T>
 class is_movable
+ : public ::boost::mpl::bool_<move_detail::internal_member_value_traits<T>::value>
 {
- public:
- static const bool value = move_detail::is_convertible<T&&, T>::value;
 };
 
+//! For compilers with rvalue references, this traits class returns true
+//! if T && is convertible to T.
+//!
+//! For other compilers returns true if T has implemented move emulation.
+template <class T>
+struct has_nothrow_move : is_movable<T>
+{};
+
 //////////////////////////////////////////////////////////////////////////////
 //
 // move
@@ -240,7 +333,7 @@
 #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
 //! This function provides a way to convert a reference into a rvalue reference
 //! in compilers with rvalue reference. For other compilers converts T & into
-//! <i>boost::interprocess::rv<T> &</i> so that move emulation is activated.
+//! <i>::boost::interprocess::rv<T> &</i> so that move emulation is activated.
 template <class T> inline
 rvalue_reference move (input_reference);
 #else
@@ -264,8 +357,8 @@
 //! For compilers with rvalue references this function provides perfect forwarding.
 //!
 //! Otherwise:
-//! * If input_reference binds to const boost::interprocess::rv<T> & then it output_reference is
-//! boost::rev<T> &
+//! * If input_reference binds to const ::boost::interprocess::rv<T> & then it output_reference is
+//! ::boost::rev<T> &
 //!
 //! * Else, input_reference is equal to output_reference is equal to input_reference.
 template <class T> inline output_reference forward(input_reference);
@@ -277,19 +370,39 @@
 
 //////////////////////////////////////////////////////////////////////////////
 //
-// BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION
+// BOOST_ENABLE_MOVE_EMULATION
 //
 //////////////////////////////////////////////////////////////////////////////
 
-//! This macro expands to nothing for compilers with rvalue references.
-//! Otherwise expands to:
-//! \code
-//! operator boost::interprocess::rv<TYPE>&()
-//! { return static_cast<boost::interprocess::rv<TYPE>& >(*this); }
-//! \endcode
-#define BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(TYPE)\
+///@cond
+
+#define BOOST_ENABLE_MOVE_EMULATION(TYPE)\
+ typedef int boost_move_emulation_t;
+\
 //
 
+/// @endcond
+
+//! This macro marks a type as movable but not copyable, disabling copy construction
+//! and assignment. The user will need to write a move constructor/assignment as explained
+//! in the documentation to fully write a movable but not copyable class.
+#define BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+ public:\
+ typedef int boost_move_emulation_t;\
+ private:\
+ TYPE(const TYPE &);\
+ TYPE& operator=(const TYPE &);\
+//
+
+//! This macro marks a type as copyable and movable.
+//! The user will need to write a move constructor/assignment and a copy assignment
+//! as explained in the documentation to fully write a copyable and movable class.
+#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+ typedef int boost_move_emulation_t;
+//
+
+/// @cond
+
 #define BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
    TYPE<ARG1, ARG2> && \
 //
@@ -298,18 +411,43 @@
    TYPE<ARG1, ARG2, ARG3> && \
 //
 
-//! This macro expands to <i>T&&</i> for compilers with rvalue references.
-//! Otherwise expands to <i>boost::interprocess::rv<T> &</i>.
+/// @endcond
+
+//!This macro is used to achieve portable syntax in move
+//!constructors and assignments for classes marked as
+//!BOOST_COPYABLE_AND_MOVABLE or BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE
 #define BOOST_INTERPROCESS_RV_REF(TYPE)\
    TYPE && \
 //
 
-//! This macro expands to <i>T&&</i> for compilers with rvalue references.
-//! Otherwise expands to <i>const T &</i>.
+//!This macro is used to achieve portable syntax in copy
+//!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
+#define BOOST_INTERPROCESS_COPY_ASSIGN_REF(TYPE)\
+ const TYPE & \
+//
+
+/// @cond
+
+#define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+ const TYPE<ARG1, ARG2> & \
+//
+
+#define BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+ TYPE<ARG1, ARG2, ARG3>& \
+//
+
+/// @endcond
+
+//! This macro is used to implement portable perfect forwarding
+//! as explained in the documentation.
 #define BOOST_INTERPROCESS_FWD_REF(TYPE)\
    TYPE && \
 //
 
+#define BOOST_INTERPROCESS_CATCH_CONST_RLVALUE(TYPE)\
+ const TYPE & \
+//
+
 } //namespace interprocess {
 } //namespace boost {
 
@@ -338,12 +476,12 @@
    #if defined(BOOST_HAS_RVALUE_REFS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
    typedef value_type && reference;
    #else
- typedef typename boost::mpl::if_
- < boost::interprocess::is_movable<value_type>
- , boost::interprocess::rv<value_type>&
+ typedef typename ::boost::mpl::if_
+ < ::boost::interprocess::is_movable<value_type>
+ , ::boost::interprocess::rv<value_type>&
       , value_type & >::type reference;
    #endif
- typedef typename std::iterator_traits<iterator_type>::pointer pointer;
+ typedef It pointer;
    typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
    typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
 
@@ -367,7 +505,7 @@
       #if defined(BOOST_HAS_RVALUE_REFS)
       return *m_it;
       #else
- return boost::interprocess::move(*m_it);
+ return ::boost::interprocess::move(*m_it);
       #endif
    }
 
@@ -403,7 +541,7 @@
       #if defined(BOOST_HAS_RVALUE_REFS)
       return m_it[n];
       #else
- return boost::interprocess::move(m_it[n]);
+ return ::boost::interprocess::move(m_it[n]);
       #endif
    }
 
@@ -441,14 +579,14 @@
 
 template <class I>
 struct is_move_iterator
+ : public ::boost::mpl::bool_<false>
 {
- static const bool value = false;
 };
 
 template <class I>
 struct is_move_iterator< ::boost::interprocess::move_iterator<I> >
+ : public ::boost::mpl::bool_<true>
 {
- static const bool value = true;
 };
 
 } //namespace move_detail {
@@ -557,7 +695,7 @@
 
    move_insert_iterator& operator=(typename C::reference x)
    {
- pos_ = container_m->insert(pos_, boost::interprocess::move(x));
+ pos_ = container_m->insert(pos_, ::boost::interprocess::move(x));
       ++pos_;
       return *this;
    }
@@ -584,7 +722,7 @@
 
 //! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
 //! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
-//! performs *(result + n) = boost::interprocess::move (*(first + n)).
+//! performs *(result + n) = ::boost::interprocess::move (*(first + n)).
 //!
 //! <b>Effects</b>: result + (last - first).
 //!
@@ -596,7 +734,7 @@
 O move(I f, I l, O result)
 {
    while (f != l) {
- *result = boost::interprocess::move(*f);
+ *result = ::boost::interprocess::move(*f);
       ++f; ++result;
    }
    return result;
@@ -611,7 +749,7 @@
 //! <b>Effects</b>: Moves elements in the range [first,last) into the range
 //! [result - (last-first),result) starting from last - 1 and proceeding to
 //! first. For each positive integer n <= (last - first),
-//! performs *(result - n) = boost::interprocess::move(*(last - n)).
+//! performs *(result - n) = ::boost::interprocess::move(*(last - n)).
 //!
 //! <b>Requires</b>: result shall not be in the range [first,last).
 //!
@@ -624,7 +762,7 @@
 {
    while (f != l) {
       --l; --result;
- *result = boost::interprocess::move(*l);
+ *result = ::boost::interprocess::move(*l);
    }
    return result;
 }
@@ -685,7 +823,7 @@
 F uninitialized_move_move_iterator(I f, I l, F r,
                              typename enable_if< is_movable<typename I::value_type> >::type* = 0)
 {
- return boost::interprocess::uninitialized_move(f, l, r);
+ return ::boost::interprocess::uninitialized_move(f, l, r);
 }
 
 template
@@ -705,7 +843,7 @@
 F uninitialized_copy_or_move(I f, I l, F r,
                              typename enable_if< move_detail::is_move_iterator<I> >::type* = 0)
 {
- return boost::interprocess::move_detail::uninitialized_move_move_iterator(f, l, r);
+ return ::boost::interprocess::move_detail::uninitialized_move_move_iterator(f, l, r);
 }
 
 /// @endcond
@@ -734,14 +872,54 @@
    return std::uninitialized_copy(f, l, r);
 }
 
-///has_trivial_destructor_after_move<> == true_type
-///specialization for optimizations
+//! If this trait yields to true
+//! (<i>has_trivial_destructor_after_move_ctor &lt;T&gt;::value == true</i>)
+//! means that if T is used as argument of a move construction,
+//! there is no need to call T's destructor.
+//! This optimization tipically is used to improve containers' performance.
+//!
+//! By default this trait is true if the type has trivial destructor,
+//! every class should specialize this trait if it wants to improve performance
+//! when inserted in containers.
+template <class T>
+struct has_trivial_destructor_after_move_ctor
+ : public ::boost::has_trivial_destructor<T>
+{};
+
+//! If this trait yields to true
+//! (<i>has_trivial_destructor_after_move &lt;T&gt;::value == true</i>)
+//! means that if T is used as argument of a move construction/assignment,
+//! there is no need to call T's destructor.
+//! This optimization tipically is used to improve containers' performance.
+//!
+//! By default this trait is true if the type has trivial destructor,
+//! every class should specialize this trait if it wants to improve performance
+//! when inserted in containers.
 template <class T>
 struct has_trivial_destructor_after_move
- : public boost::has_trivial_destructor<T>
+ : public ::boost::has_trivial_destructor<T>
+{};
+
+//! If this trait yields to true
+//! (<i>has_trivial_destructor_after_move_to_moved &lt;T&gt;::value == true</i>)
+//! means that if t1 of type T is being moved to an already moved value t2,
+//! there is no need to call t1's destructor:
+//! <pre>
+//! T t1, t2, t3(::boost::interprocess::move(t2));
+//! t2 = ::boost::interprocess::move(t1);
+//! //There is no need to call t1's destructor
+//! </pre>
+//! This optimization is used to improve containers' performance.
+//!
+//! By default this trait is true if the type has trivial destructor,
+//! every class should specialize this trait if it wants to improve performance
+//! when inserted in containers.
+template <class T>
+struct has_trivial_destructor_after_move_to_moved
+ : public has_trivial_destructor_after_move<T>
 {};
 
 } //namespace interprocess {
 } //namespace boost {
 
-#endif //#ifndef BOOST_INTERPROCESS_MOVE_HPP
+#endif //#ifndef BOOST_MOVE_HPP

Modified: trunk/boost/interprocess/detail/mpl.hpp
==============================================================================
--- trunk/boost/interprocess/detail/mpl.hpp (original)
+++ trunk/boost/interprocess/detail/mpl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/interprocess/detail/multi_segment_services.hpp
==============================================================================
--- trunk/boost/interprocess/detail/multi_segment_services.hpp (original)
+++ trunk/boost/interprocess/detail/multi_segment_services.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/named_proxy.hpp
==============================================================================
--- trunk/boost/interprocess/detail/named_proxy.hpp (original)
+++ trunk/boost/interprocess/detail/named_proxy.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/os_file_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_file_functions.hpp (original)
+++ trunk/boost/interprocess/detail/os_file_functions.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -26,6 +26,9 @@
 # include <errno.h>
 # include <cstdio>
 # include <dirent.h>
+# if 0
+# include <sys/file.h>
+# endif
 # else
 # error Unknown platform
 # endif
@@ -335,19 +338,16 @@
 { return ::mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; }
 
 inline const char *get_temporary_path()
-{
+{
+ const char *names[] = {"/tmp", "TMPDIR", "TMP", "TEMP" };
+ const int names_size = sizeof(names)/sizeof(names[0]);
    struct stat data;
- const char *dir = std::getenv("TMPDIR");
- if(!dir || ::stat(dir, &data) != 0){
- dir = std::getenv("TMP");
- if(!dir || ::stat(dir, &data) != 0){
- dir = std::getenv("TEMP");
- if(!dir || ::stat(dir, &data) != 0){
- dir = "/tmp";
- }
+ for(int i = 0; i != names_size; ++i){
+ if(::stat(names[i], &data) == 0){
+ return names[i];
       }
    }
- return dir;
+ return "/tmp";
 }
 
 inline file_handle_t create_new_file
@@ -468,6 +468,34 @@
 inline bool release_file_lock_sharable(file_handle_t hnd)
 { return release_file_lock(hnd); }
 
+#if 0
+inline bool acquire_file_lock(file_handle_t hnd)
+{ return 0 == ::flock(hnd, LOCK_EX); }
+
+inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
+{
+ int ret = ::flock(hnd, LOCK_EX | LOCK_NB);
+ acquired = ret == 0;
+ return (acquired || errno == EWOULDBLOCK);
+}
+
+inline bool release_file_lock(file_handle_t hnd)
+{ return 0 == ::flock(hnd, LOCK_UN); }
+
+inline bool acquire_file_lock_sharable(file_handle_t hnd)
+{ return 0 == ::flock(hnd, LOCK_SH); }
+
+inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
+{
+ int ret = ::flock(hnd, LOCK_SH | LOCK_NB);
+ acquired = ret == 0;
+ return (acquired || errno == EWOULDBLOCK);
+}
+
+inline bool release_file_lock_sharable(file_handle_t hnd)
+{ return 0 == ::flock(hnd, LOCK_UN); }
+#endif
+
 inline bool delete_subdirectories_recursive
    (const std::string &refcstrRootDirectory, const char *dont_delete_this)
 {

Modified: trunk/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- trunk/boost/interprocess/detail/os_thread_functions.hpp (original)
+++ trunk/boost/interprocess/detail/os_thread_functions.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/pointer_type.hpp
==============================================================================
--- trunk/boost/interprocess/detail/pointer_type.hpp (original)
+++ trunk/boost/interprocess/detail/pointer_type.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.

Modified: trunk/boost/interprocess/detail/posix_time_types_wrk.hpp
==============================================================================
--- trunk/boost/interprocess/detail/posix_time_types_wrk.hpp (original)
+++ trunk/boost/interprocess/detail/posix_time_types_wrk.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/interprocess/detail/preprocessor.hpp (original)
+++ trunk/boost/interprocess/detail/preprocessor.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/segment_manager_helper.hpp
==============================================================================
--- trunk/boost/interprocess/detail/segment_manager_helper.hpp (original)
+++ trunk/boost/interprocess/detail/segment_manager_helper.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/tmp_dir_helpers.hpp
==============================================================================
--- trunk/boost/interprocess/detail/tmp_dir_helpers.hpp (original)
+++ trunk/boost/interprocess/detail/tmp_dir_helpers.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/transform_iterator.hpp
==============================================================================
--- trunk/boost/interprocess/detail/transform_iterator.hpp (original)
+++ trunk/boost/interprocess/detail/transform_iterator.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.

Modified: trunk/boost/interprocess/detail/type_traits.hpp
==============================================================================
--- trunk/boost/interprocess/detail/type_traits.hpp (original)
+++ trunk/boost/interprocess/detail/type_traits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/interprocess/detail/utilities.hpp
==============================================================================
--- trunk/boost/interprocess/detail/utilities.hpp (original)
+++ trunk/boost/interprocess/detail/utilities.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008.
+// (C) Copyright Ion Gaztanaga 2005-2009.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.

Modified: trunk/boost/interprocess/detail/variadic_templates_tools.hpp
==============================================================================
--- trunk/boost/interprocess/detail/variadic_templates_tools.hpp (original)
+++ trunk/boost/interprocess/detail/variadic_templates_tools.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- trunk/boost/interprocess/detail/win32_api.hpp (original)
+++ trunk/boost/interprocess/detail/win32_api.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -39,8 +39,12 @@
 //Some used constants
 static const unsigned long infinite_time = 0xFFFFFFFF;
 static const unsigned long error_already_exists = 183L;
+static const unsigned long error_sharing_violation = 32L;
 static const unsigned long error_file_not_found = 2u;
 static const unsigned long error_no_more_files = 18u;
+//Retries in CreateFile, see http://support.microsoft.com/kb/316609
+static const unsigned int error_sharing_violation_tries = 3u;
+static const unsigned int error_sharing_violation_sleep_ms = 250u;
 
 static const unsigned long semaphore_all_access = (0x000F0000L)|(0x00100000L)|0x3;
 static const unsigned long mutex_all_access = (0x000F0000L)|(0x00100000L)|0x0001;
@@ -463,6 +467,9 @@
 namespace interprocess {
 namespace winapi {
 
+inline unsigned long get_last_error()
+{ return GetLastError(); }
+
 inline unsigned long format_message
    (unsigned long dwFlags, const void *lpSource,
     unsigned long dwMessageId, unsigned long dwLanguageId,
@@ -509,9 +516,6 @@
       , duplicate_same_access);
 }
 
-inline unsigned long get_last_error()
-{ return GetLastError(); }
-
 inline void get_system_time_as_file_time(interprocess_filetime *filetime)
 { GetSystemTimeAsFileTime(filetime); }
 
@@ -566,7 +570,22 @@
 { return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr); }
 
 inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0)
-{ return CreateFileA(name, access, file_share_read | file_share_write | file_share_delete, 0, creation_flags, attributes, 0); }
+{
+ for (unsigned int attempt(0); attempt < error_sharing_violation_tries; ++attempt){
+ void * const handle = CreateFileA(name, access,
+ file_share_read | file_share_write | file_share_delete,
+ 0, creation_flags, attributes, 0);
+ bool const invalid(invalid_handle_value == handle);
+ if (!invalid){
+ return handle;
+ }
+ if (error_sharing_violation != get_last_error()){
+ return handle;
+ }
+ Sleep(error_sharing_violation_sleep_ms);
+ }
+ return invalid_handle_value;
+}
 
 inline bool delete_file(const char *name)
 { return 0 != DeleteFileA(name); }

Modified: trunk/boost/interprocess/detail/workaround.hpp
==============================================================================
--- trunk/boost/interprocess/detail/workaround.hpp (original)
+++ trunk/boost/interprocess/detail/workaround.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -76,8 +76,9 @@
    # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
    # endif
    //Mac OS has some non-conformant features like names limited to SHM_NAME_MAX
- //# elif defined (__APPLE__)
- //# define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ # elif defined (__APPLE__)
+ # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
+ # define BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS_NO_GROW
    # endif
    #endif
 
@@ -91,22 +92,19 @@
    # define BOOST_INTERPROCESS_POSIX_TIMEOUTS
    #endif
 
- //Some systems have filesystem-based resources, so the
- //portable "/shmname" format does not work due to permission issues
- //For those systems we need to form a path to a temporary directory:
- // hp-ux tru64 vms freebsd
- #if defined(__hpux) || defined(__osf__) || defined(__vms) || (defined(__FreeBSD__) && (__FreeBSD__ < 8))
- #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_RESOURCES
- #endif
 
    #ifdef BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS
- #if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_RESOURCES)
+ //Some systems have filesystem-based resources, so the
+ //portable "/shmname" format does not work due to permission issues
+ //For those systems we need to form a path to a temporary directory:
+ // hp-ux tru64 vms freebsd
+ #if defined(__hpux) || defined(__osf__) || defined(__vms) || (defined(__FreeBSD__) && (__FreeBSD__ < 8))
       #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SHARED_MEMORY
       #endif
    #endif
 
    #ifdef BOOST_INTERPROCESS_POSIX_NAMED_SEMAPHORES
- #if defined(BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_RESOURCES)
+ #if defined(__osf__) || defined(__vms)
       #define BOOST_INTERPROCESS_FILESYSTEM_BASED_POSIX_SEMAPHORES
       #endif
    #endif

Added: trunk/boost/interprocess/detail/xsi_shared_memory.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/xsi_shared_memory.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,222 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP
+#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+#error "This header can't be used in Windows operating systems"
+#endif
+
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <sys/shm.h>
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <string>
+
+//!\file
+//!Describes a class representing a native xsi shared memory.
+
+namespace boost {
+namespace interprocess {
+
+//!A class that wraps XSI (System V) shared memory.
+//!Unlike shared_memory_object, xsi_shared_memory needs a valid
+//!path and a 8 bit key to identify a shared memory create
+//!when all processes destroy all their xsi_shared_memory
+//!objects and mapped regions for the same shared memory
+//!or the processes end/crash.
+//!
+//!Warning: XSI shared memory and interprocess portable
+//!shared memory (boost::interprocess::shared_memory_object)
+//!can't communicate between them.
+class xsi_shared_memory
+{
+ /// @cond
+ //Non-copyable and non-assignable
+ xsi_shared_memory(xsi_shared_memory &);
+ xsi_shared_memory &operator=(xsi_shared_memory &);
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(xsi_shared_memory)
+
+ //!Default constructor.
+ //!Represents an empty xsi_shared_memory.
+ xsi_shared_memory();
+
+ //!Creates a new XSI shared memory with a key obtained from a call to ftok (with path
+ //!"path" and id "id"), of size "size" and permissions "perm".
+ //!If the shared memory previously exists, throws an error.
+ xsi_shared_memory(create_only_t, const char *path, boost::uint8_t id, std::size_t size, int perm = 0666)
+ { this->priv_open_or_create(detail::DoCreate, path, id, perm, size); }
+
+ //!Tries to create a new XSI shared memory with a key obtained from a call to ftok (with path
+ //!"path" and id "id"), of size "size" and permissions "perm".
+ //!If the shared memory previously exists, it tries to open it.
+ //!Otherwise throws an error.
+ xsi_shared_memory(open_or_create_t, const char *path, boost::uint8_t id, std::size_t size, int perm = 0666)
+ { this->priv_open_or_create(detail::DoOpenOrCreate, path, id, perm, size); }
+
+ //!Tries to open a XSI shared memory with a key obtained from a call to ftok (with path
+ //!"path" and id "id") and permissions "perm".
+ //!If the shared memory does not previously exist, it throws an error.
+ xsi_shared_memory(open_only_t, const char *path, boost::uint8_t id, int perm = 0666)
+ { this->priv_open_or_create(detail::DoOpen, path, id, perm, 0); }
+
+ //!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
+ xsi_shared_memory(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory) moved)
+ { this->swap(moved); }
+
+ //!Moves the ownership of "moved"'s shared memory to *this.
+ //!After the call, "moved" does not represent any shared memory.
+ //!Does not throw
+ xsi_shared_memory &operator=(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory) moved)
+ {
+ xsi_shared_memory tmp(boost::interprocess::move(moved));
+ this->swap(tmp);
+ return *this;
+ }
+
+ //!Swaps two xsi_shared_memorys. Does not throw
+ void swap(xsi_shared_memory &other);
+
+ //!Destroys *this. The shared memory won't be destroyed, just
+ //!this connection to it. Use remove() to destroy the shared memory.
+ ~xsi_shared_memory();
+
+ //!Returns the path used to
+ //!obtain the key.
+ const char *get_path() const;
+
+ //!Returns the shared memory ID that
+ //!identifies the shared memory
+ int get_shmid() const;
+
+ //!Returns access
+ //!permissions
+ int get_permissions() const;
+
+ //!Returns the mapping handle.
+ //!Never throws
+ mapping_handle_t get_mapping_handle() const;
+
+ //!Erases the XSI shared memory object identified by shmid
+ //!from the system.
+ //!Returns false on error. Never throws
+ static bool remove(int shmid);
+
+ /// @cond
+ private:
+
+ //!Closes a previously opened file mapping. Never throws.
+ bool priv_open_or_create( detail::create_enum_t type
+ , const char *filename
+ , boost::uint8_t id
+ , int perm
+ , std::size_t size);
+ int m_shmid;
+ /// @endcond
+};
+
+/// @cond
+
+inline xsi_shared_memory::xsi_shared_memory()
+ : m_shmid(-1)
+{}
+
+inline xsi_shared_memory::~xsi_shared_memory()
+{}
+
+inline int xsi_shared_memory::get_shmid() const
+{ return m_shmid; }
+
+inline void xsi_shared_memory::swap(xsi_shared_memory &other)
+{
+ std::swap(m_shmid, other.m_shmid);
+}
+
+inline mapping_handle_t xsi_shared_memory::get_mapping_handle() const
+{ mapping_handle_t mhnd = { m_shmid, true}; return mhnd; }
+
+inline bool xsi_shared_memory::priv_open_or_create
+ (detail::create_enum_t type, const char *filename, boost::uint8_t id, int perm, std::size_t size)
+{
+ key_t key;
+ if(filename){
+ key = ::ftok(filename, id);
+ if(((key_t)-1) == key){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+ else{
+ key = IPC_PRIVATE;
+ }
+
+ perm &= 0x01FF;
+ int shmflg = perm;
+
+ switch(type){
+ case detail::DoOpen:
+ shmflg |= 0;
+ break;
+ case detail::DoCreate:
+ shmflg |= IPC_CREAT | IPC_EXCL;
+ break;
+ case detail::DoOpenOrCreate:
+ shmflg |= IPC_CREAT;
+ break;
+ default:
+ {
+ error_info err = other_error;
+ throw interprocess_exception(err);
+ }
+ }
+
+ int ret = ::shmget(key, size, shmflg);
+ int shmid = ret;
+ if((type == detail::DoOpen) && (-1 != ret)){
+ //Now get the size
+ ::shmid_ds xsi_ds;
+ ret = ::shmctl(ret, IPC_STAT, &xsi_ds);
+ size = xsi_ds.shm_segsz;
+ }
+ if(-1 == ret){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+
+ m_shmid = shmid;
+ return true;
+}
+
+inline bool xsi_shared_memory::remove(int shmid)
+{ return -1 != ::shmctl(shmid, IPC_RMID, 0); }
+
+///@endcond
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_HPP

Added: trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/detail/xsi_shared_memory_device.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,393 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_DEVICE_HPP
+#define BOOST_INTERPROCESS_XSI_SHARED_MEMORY_DEVICE_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+#error "This header can't be used in Windows operating systems"
+#endif
+
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/detail/tmp_dir_helpers.hpp>
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/exceptions.hpp>
+
+#include <boost/interprocess/detail/xsi_shared_memory.hpp>
+#include <boost/interprocess/sync/xsi/xsi_named_mutex.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <string>
+#include <cstring>
+
+//!\file
+//!Describes a class representing a native xsi shared memory.
+
+namespace boost {
+namespace interprocess {
+
+class xsi_shared_memory_device
+{
+ /// @cond
+ //Non-copyable and non-assignable
+ xsi_shared_memory_device(xsi_shared_memory_device &);
+ xsi_shared_memory_device &operator=(xsi_shared_memory_device &);
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(xsi_shared_memory_device)
+
+ xsi_shared_memory_device();
+
+ xsi_shared_memory_device(create_only_t, const char *name, mode_t mode, std::size_t size)
+ { this->priv_open_or_create_name_only(detail::DoCreate, name, mode, size); }
+
+ xsi_shared_memory_device(open_or_create_t, const char *name, mode_t mode, std::size_t size)
+ { this->priv_open_or_create_name_only(detail::DoOpenOrCreate, name, mode, size); }
+
+ xsi_shared_memory_device(open_only_t, const char *name, mode_t mode)
+ { this->priv_open_or_create_name_only(detail::DoOpen, name, mode, 0); }
+
+ xsi_shared_memory_device(create_only_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
+ { this->priv_open_or_create_name_id(detail::DoCreate, name, id, mode, size); }
+
+ xsi_shared_memory_device(open_or_create_t, const char *filepath, boost::uint8_t id, mode_t mode, std::size_t size)
+ { this->priv_open_or_create_name_id(detail::DoOpenOrCreate, id, name, mode, size); }
+
+ xsi_shared_memory_device(open_only_t, const char *filepath, boost::uint8_t id, mode_t mode)
+ { this->priv_open_or_create_name_id(detail::DoOpen, name, id, mode, 0); }
+
+ xsi_shared_memory_device(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory_device) moved)
+ { this->swap(moved); }
+
+ xsi_shared_memory_device &operator=(BOOST_INTERPROCESS_RV_REF(xsi_shared_memory_device) moved)
+ {
+ xsi_shared_memory_device tmp(boost::interprocess::move(moved));
+ this->swap(tmp);
+ return *this;
+ }
+
+ //!Swaps two xsi_shared_memory_device. Does not throw
+ void swap(xsi_shared_memory_device &other);
+
+ //!Destroys *this. The shared memory won't be destroyed, just
+ //!this connection to it. Use remove() to destroy the shared memory.
+ ~xsi_shared_memory_device();
+
+ //!Returns the name of the
+ //!shared memory.
+ const char *get_name() const;
+
+ //!Returns the shared memory ID that
+ //!identifies the shared memory
+ int get_shmid() const;
+
+ //!Returns access
+ //!permissions
+ mode_t get_mode() const;
+
+ //!Returns the mapping handle.
+ //!Never throws
+ mapping_handle_t get_mapping_handle() const;
+
+ //!Erases a XSI shared memory object identified by shmname
+ //!from the system.
+ //!Returns false on error. Never throws
+ static bool remove(const char *shmname);
+
+ //!Erases the XSI shared memory object identified by shmid
+ //!from the system.
+ //!Returns false on error. Never throws
+ static bool remove(int shmid);
+
+ /// @cond
+ private:
+ template<int Dummy>
+ struct info_constants_t
+ {
+ static const std::size_t MaxName = 32;
+ static const std::size_t FirstID = 2;
+ static const std::size_t LastID = 256;
+ static const std::size_t NumID = LastID - FirstID;
+ };
+
+ struct info_t
+ {
+ struct names_t
+ {
+ char buf[info_constants_t<0>::MaxName];
+ } names[info_constants_t<0>::NumID];
+ };
+
+ static void priv_obtain_index(mapped_region &m, xsi_named_mutex &m, std::string &path);
+ static bool priv_remove_dead_memory(info_t *info, const char *path);
+
+ bool priv_open_or_create_name_only( detail::create_enum_t type
+ , const char *shmname
+ , mode_t mode
+ , std::size_t size);
+ bool priv_open_or_create_name_id( detail::create_enum_t type
+ , const char *shmname
+ , boost::uint8_t id
+ , mode_t mode
+ , std::size_t size);
+ xsi_shared_memory m_shm;
+ mode_t m_mode;
+ std::string m_name;
+ /// @endcond
+};
+
+template<int Dummy>
+const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::MaxName;
+
+template<int Dummy>
+const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::FirstID;
+
+template<int Dummy>
+const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::LastID;
+
+template<int Dummy>
+const std::size_t xsi_shared_memory_device::info_constants_t<Dummy>::NumID;
+
+/// @cond
+
+inline xsi_shared_memory_device::xsi_shared_memory_device()
+ : m_shm(), m_mode(invalid_mode), m_name()
+{}
+
+inline xsi_shared_memory_device::~xsi_shared_memory_device()
+{}
+
+inline const char *xsi_shared_memory_device::get_name() const
+{ return m_name.c_str(); }
+
+inline void xsi_shared_memory_device::swap(xsi_shared_memory_device &other)
+{
+ m_shm.swap(other.m_shm);
+ std::swap(m_mode, other.m_mode);
+ m_name.swap(other.m_name);
+}
+
+inline mapping_handle_t xsi_shared_memory_device::get_mapping_handle() const
+{ return m_shm.get_mapping_handle(); }
+
+inline mode_t xsi_shared_memory_device::get_mode() const
+{ return m_mode; }
+
+inline int xsi_shared_memory::get_shmid() const
+{ return m_shm.get_shmid(); }
+
+inline void xsi_shared_memory_device::priv_obtain_index
+ (mapped_region &reg, xsi_named_mutex &mut, std::string &path)
+{
+ const char *const filename = "xsi_shm_emulation_file";
+ std::string xsi_shm_emulation_file_path;
+ detail::create_tmp_dir_and_get_filename(filename, xsi_shm_emulation_file_path);
+ detail::create_or_open_file(xsi_shm_emulation_file_path.c_str());
+ const std::size_t MemSize = sizeof(info_t);
+
+ xsi_shared_memory index_shm(open_or_create, xsi_shm_emulation_file_path.c_str(), 1, MemSize, 0666);
+ mapped_region r(index_shm, read_write, 0, MemSize, 0);
+ xsi_named_mutex m(open_or_create, xsi_shm_emulation_file_path.c_str(), 2, 0666);
+ reg = boost::interprocess::move(r);
+ mut = boost::interprocess::move(m);
+ path.swap(xsi_shm_emulation_file_path);
+}
+
+inline bool xsi_shared_memory_device::priv_remove_dead_memory
+ (xsi_shared_memory_device::info_t *info, const char *path)
+{
+ bool removed = false;
+ for(std::size_t i = 0; i != info_constants_t<0>::NumID; ++i){
+ if(info->names[i].buf[0]){
+ try{
+ xsi_shared_memory temp( open_only, path, i+info_constants_t<0>::FirstID, 0600);
+ }
+ catch(interprocess_exception &e){
+ if(e.get_error_code() == not_found_error){
+ std::memset(info->names[i].buf, 0, info_constants_t<0>::MaxName);
+ removed = true;
+ }
+ }
+ }
+ }
+ return removed;
+}
+
+inline bool xsi_shared_memory_device::priv_open_or_create_name_id
+ (detail::create_enum_t type, const char *filepath, mode_t mode, std::size_t size)
+{
+ //Set accesses
+ if (mode != read_write && mode != read_only){
+ error_info err = other_error;
+ throw interprocess_exception(err);
+ }
+
+ int perm = (mode == read_only) ? (0444) : (0666);
+
+ if(type == detail::DoOpen){
+ if(!found){
+ error_info err = not_found_error;
+ throw interprocess_exception(err);
+ }
+ xsi_shared_memory temp(open_only, filepath, id, perm);
+ m_shm = boost::interprocess::move(temp);
+ }
+ else if(type == detail::DoCreate){
+ //Try to reuse slot
+ xsi_shared_memory temp(create_only, filepath, id, size, perm);
+ std::strcpy(info->names[target_entry].buf, shmname);
+ m_shm = boost::interprocess::move(temp);
+ }
+ else{ // if(type == detail::DoOpenOrCreate){
+ xsi_shared_memory temp(open_or_create, filepath, id, size, perm);
+ m_shm = boost::interprocess::move(temp);
+ }
+
+ m_mode = mode;
+ m_name.clear();
+ return true;
+}
+
+inline bool xsi_shared_memory_device::priv_open_or_create_name_only
+ (detail::create_enum_t type, const char *shmname, mode_t mode, std::size_t size)
+{
+ //Set accesses
+ if (mode != read_write && mode != read_only){
+ error_info err = other_error;
+ throw interprocess_exception(err);
+ }
+
+ if (std::strlen(shmname) >= (info_constants_t<0>::MaxName)){
+ error_info err = other_error;
+ throw interprocess_exception(err);
+ }
+
+ {
+ //Obtain index and index lock
+ mapped_region region;
+ xsi_named_mutex mut;
+ std::string xsi_shm_emulation_file_path;
+ priv_obtain_index(region, mut, xsi_shm_emulation_file_path);
+ info_t *info = static_cast<info_t *>(region.get_address());
+ scoped_lock<xsi_named_mutex> lock(mut);
+
+ //Find the correct entry or the first empty index
+ bool found = false;
+ int target_entry = -1;
+ int tries = 2;
+ while(tries--){
+ for(std::size_t i = 0; i != info_constants_t<0>::NumID; ++i){
+ if(target_entry < 0 && !info->names[i].buf[0]){
+ target_entry = static_cast<int>(i);
+ }
+ else if(0 == std::strcmp(info->names[i].buf, shmname)){
+ found = true;
+ target_entry = static_cast<int>(i);
+ break;
+ }
+ }
+ if(target_entry < 0){
+ if(!tries || !priv_remove_dead_memory(info, xsi_shm_emulation_file_path.c_str())){
+ error_info err = out_of_resource_error;
+ throw interprocess_exception(err);
+ }
+ }
+ }
+ //Now handle the result
+ int perm = (mode == read_only) ? (0444) : (0666);
+ if(type == detail::DoOpen){
+ if(!found){
+ error_info err = not_found_error;
+ throw interprocess_exception(err);
+ }
+ xsi_shared_memory temp( open_only, xsi_shm_emulation_file_path.c_str()
+ , target_entry+info_constants_t<0>::FirstID, perm);
+ m_shm = boost::interprocess::move(temp);
+ }
+ else{
+
+ if(type == detail::DoCreate){
+ //Try to reuse slot
+ xsi_shared_memory temp( create_only, xsi_shm_emulation_file_path.c_str()
+ , target_entry+info_constants_t<0>::FirstID, size, perm);
+ std::strcpy(info->names[target_entry].buf, shmname);
+ m_shm = boost::interprocess::move(temp);
+ }
+ else{ // if(type == detail::DoOpenOrCreate){
+ xsi_shared_memory temp( open_or_create, xsi_shm_emulation_file_path.c_str()
+ , target_entry+info_constants_t<0>::FirstID, size, perm);
+ if(!found){
+ std::memset(info->names[target_entry].buf, 0, info_constants_t<0>::MaxName);
+ std::strcpy(info->names[target_entry].buf, shmname);
+ }
+ m_shm = boost::interprocess::move(temp);
+ }
+ }
+ }
+
+ m_mode = mode;
+ m_name = shmname;
+ return true;
+}
+
+inline bool xsi_shared_memory_device::remove(const char *shmname)
+{
+ try{
+ //Obtain index and index lockss
+ mapped_region region;
+ xsi_named_mutex mut;
+ std::string xsi_shm_emulation_file_path;
+ priv_obtain_index(region, mut, xsi_shm_emulation_file_path);
+ scoped_lock<xsi_named_mutex> lock(mut);
+ info_t *info = static_cast<info_t *>(region.get_address());
+
+ //Now check and remove
+ bool removed = false;
+
+ for(std::size_t i = 0; i != info_constants_t<0>::NumID; ++i){
+ if(0 == std::strcmp(info->names[i].buf, name)){
+ xsi_shared_memory temp( open_only, xsi_shm_emulation_file_path.c_str()
+ , i+info_constants_t<0>::FirstID);
+ if(!xsi_shared_memory::remove(temp.get_shmid()) && (system_error_code() != invalid_argument)){
+ return false;
+ }
+ std::memset(info->names[i].buf, 0, info_constants_t<0>::MaxName);
+ removed = true;
+ break;
+ }
+ }
+ return removed;
+ }
+ catch(...){
+ return false;
+ }
+}
+
+inline bool xsi_shared_memory_device::remove(int shmid)
+{ return xsi_shared_memory::remove(shmid); }
+
+///@endcond
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_XSI_SHARED_MEMORY_DEVICE_HPP

Modified: trunk/boost/interprocess/errors.hpp
==============================================================================
--- trunk/boost/interprocess/errors.hpp (original)
+++ trunk/boost/interprocess/errors.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/exceptions.hpp
==============================================================================
--- trunk/boost/interprocess/exceptions.hpp (original)
+++ trunk/boost/interprocess/exceptions.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/file_mapping.hpp
==============================================================================
--- trunk/boost/interprocess/file_mapping.hpp (original)
+++ trunk/boost/interprocess/file_mapping.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -33,14 +33,10 @@
 class file_mapping
 {
    /// @cond
- //Non-copyable and non-assignable
- file_mapping(file_mapping &);
- file_mapping &operator=(file_mapping &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(file_mapping)
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(file_mapping)
-
    //!Constructs an empty file mapping.
    //!Does not throw
    file_mapping();

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/indexes/iset_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/iset_index.hpp (original)
+++ trunk/boost/interprocess/indexes/iset_index.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/indexes/map_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/map_index.hpp (original)
+++ trunk/boost/interprocess/indexes/map_index.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/indexes/null_index.hpp
==============================================================================
--- trunk/boost/interprocess/indexes/null_index.hpp (original)
+++ trunk/boost/interprocess/indexes/null_index.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/interprocess_fwd.hpp
==============================================================================
--- trunk/boost/interprocess/interprocess_fwd.hpp (original)
+++ trunk/boost/interprocess/interprocess_fwd.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- trunk/boost/interprocess/ipc/message_queue.hpp (original)
+++ trunk/boost/interprocess/ipc/message_queue.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/managed_external_buffer.hpp
==============================================================================
--- trunk/boost/interprocess/managed_external_buffer.hpp (original)
+++ trunk/boost/interprocess/managed_external_buffer.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -43,12 +43,10 @@
    /// @cond
    typedef detail::basic_managed_memory_impl
       <CharType, AllocationAlgorithm, IndexType> base_t;
- basic_managed_external_buffer(basic_managed_external_buffer&);
- basic_managed_external_buffer & operator=(basic_managed_external_buffer&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_managed_external_buffer)
    /// @endcond
    
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_external_buffer)
 
    //!Default constructor. Does nothing.
    //!Useful in combination with move semantics

Modified: trunk/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_heap_memory.hpp (original)
+++ trunk/boost/interprocess/managed_heap_memory.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -46,12 +46,10 @@
 
    typedef detail::basic_managed_memory_impl
       <CharType, AllocationAlgorithm, IndexType> base_t;
- basic_managed_heap_memory(basic_managed_heap_memory&);
- basic_managed_heap_memory & operator=(basic_managed_heap_memory&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_managed_heap_memory)
    /// @endcond
 
    public: //functions
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_heap_memory)
 
    //!Default constructor. Does nothing.
    //!Useful in combination with move semantics

Modified: trunk/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- trunk/boost/interprocess/managed_mapped_file.hpp (original)
+++ trunk/boost/interprocess/managed_mapped_file.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -47,8 +47,6 @@
       <CharType, AllocationAlgorithm, IndexType,
       detail::managed_open_or_create_impl<detail::file_wrapper>::ManagedOpenOrCreateUserOffset> base_t;
    typedef detail::file_wrapper device_type;
- basic_managed_mapped_file(basic_managed_mapped_file&);
- basic_managed_mapped_file & operator=(basic_managed_mapped_file&);
 
    private:
 
@@ -60,10 +58,10 @@
 
    private:
    typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_managed_mapped_file)
    /// @endcond
 
    public: //functions
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_mapped_file)
 
    //!Creates mapped file and creates and places the segment manager.
    //!This can throw.

Modified: trunk/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/managed_shared_memory.hpp (original)
+++ trunk/boost/interprocess/managed_shared_memory.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -60,12 +60,10 @@
 
    private:
    typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
- basic_managed_shared_memory(basic_managed_shared_memory&);
- basic_managed_shared_memory & operator=(basic_managed_shared_memory&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_managed_shared_memory)
    /// @endcond
 
    public: //functions
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_shared_memory)
 
    //!Destroys *this and indicates that the calling process is finished using
    //!the resource. The destructor function will deallocate

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -60,13 +60,10 @@
 
    private:
    typedef typename base_t::char_ptr_holder_t char_ptr_holder_t;
- basic_managed_windows_shared_memory(basic_managed_windows_shared_memory&);
- basic_managed_windows_shared_memory & operator=(basic_managed_windows_shared_memory&);
-
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(basic_managed_windows_shared_memory)
    /// @endcond
 
    public: //functions
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_managed_windows_shared_memory)
 
    //!Default constructor. Does nothing.
    //!Useful in combination with move semantics

Modified: trunk/boost/interprocess/mapped_region.hpp
==============================================================================
--- trunk/boost/interprocess/mapped_region.hpp (original)
+++ trunk/boost/interprocess/mapped_region.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -31,9 +31,9 @@
 # include <unistd.h>
 # include <sys/stat.h>
 # include <sys/types.h>
-# ifdef BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS
-# include <sys/shm.h>
-# endif
+# if defined(BOOST_INTERPROCESS_XSI_SHARED_MEMORY_OBJECTS)
+# include <sys/shm.h> //System V shared memory...
+# endif
 # include <cassert>
 # else
 # error Unknown platform
@@ -59,12 +59,10 @@
 {
    /// @cond
    //Non-copyable
- mapped_region(mapped_region &);
- mapped_region &operator=(mapped_region &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(mapped_region)
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(mapped_region)
 
    //!Creates a mapping region of the mapped memory "mapping", starting in
    //!offset "offset", and the mapping's size will be "size". The mapping

Modified: trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/mem_algo_common.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -25,6 +25,7 @@
 #include <boost/interprocess/detail/math_functions.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/detail/min_max.hpp>
 #include <boost/assert.hpp>
 #include <boost/static_assert.hpp>
 #include <algorithm>
@@ -38,529 +39,6 @@
 namespace interprocess {
 namespace detail {
 
-template<class VoidPointer>
-class basic_multiallocation_slist
-{
- public:
- typedef VoidPointer void_pointer;
-
- private:
- static VoidPointer &priv_get_ref(const VoidPointer &p)
- { return *static_cast<void_pointer*>(detail::get_pointer(p)); }
-
- basic_multiallocation_slist(basic_multiallocation_slist &);
- basic_multiallocation_slist &operator=(basic_multiallocation_slist &);
-
- public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_slist)
-
- //!This iterator is returned by "allocate_many" functions so that
- //!the user can access the multiple buffers allocated in a single call
- class iterator
- : public std::iterator<std::input_iterator_tag, char>
- {
- friend class basic_multiallocation_slist<void_pointer>;
- void unspecified_bool_type_func() const {}
- typedef void (iterator::*unspecified_bool_type)() const;
-
- iterator(void_pointer node_range)
- : next_node_(node_range)
- {}
-
- public:
- typedef char value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
-
- iterator()
- : next_node_(0)
- {}
-
- iterator &operator=(const iterator &other)
- { next_node_ = other.next_node_; return *this; }
-
- public:
- iterator& operator++()
- {
- next_node_ = *static_cast<void_pointer*>(detail::get_pointer(next_node_));
- return *this;
- }
-
- iterator operator++(int)
- {
- iterator result(*this);
- ++*this;
- return result;
- }
-
- bool operator== (const iterator& other) const
- { return next_node_ == other.next_node_; }
-
- bool operator!= (const iterator& other) const
- { return !operator== (other); }
-
- reference operator*() const
- { return *static_cast<char*>(detail::get_pointer(next_node_)); }
-
- operator unspecified_bool_type() const
- { return next_node_? &iterator::unspecified_bool_type_func : 0; }
-
- pointer operator->() const
- { return &(*(*this)); }
-
- private:
- void_pointer next_node_;
- };
-
- private:
- iterator it_;
-
- public:
- basic_multiallocation_slist()
- : it_(iterator())
- {}
-
- basic_multiallocation_slist(void_pointer p)
- : it_(p ? iterator_to(p) : iterator())
- {}
-
- basic_multiallocation_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
- : it_(iterator())
- { this->swap(other); }
-
- basic_multiallocation_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_slist) other)
- {
- basic_multiallocation_slist tmp(boost::interprocess::move(other));
- this->swap(tmp);
- return *this;
- }
-
- bool empty() const
- { return !it_; }
-
- iterator before_begin() const
- { return iterator(void_pointer(const_cast<void*>(static_cast<const void*>(&it_.next_node_)))); }
-
- iterator begin() const
- { return it_; }
-
- iterator end() const
- { return iterator(); }
-
- void clear()
- { this->it_.next_node_ = void_pointer(0); }
-
- iterator insert_after(iterator it, void_pointer m)
- {
- priv_get_ref(m) = priv_get_ref(it.next_node_);
- priv_get_ref(it.next_node_) = m;
- return iterator(m);
- }
-
- void push_front(void_pointer m)
- {
- priv_get_ref(m) = this->it_.next_node_;
- this->it_.next_node_ = m;
- }
-
- void pop_front()
- { ++it_; }
-
- void *front() const
- { return detail::get_pointer(it_.next_node_); }
-
- void splice_after(iterator after_this, iterator before_begin, iterator before_end)
- {
- if (after_this != before_begin && after_this != before_end && before_begin != before_end) {
- void_pointer next_b = priv_get_ref(before_begin.next_node_);
- void_pointer next_e = priv_get_ref(before_end.next_node_);
- void_pointer next_p = priv_get_ref(after_this.next_node_);
- priv_get_ref(before_begin.next_node_) = next_e;
- priv_get_ref(before_end.next_node_) = next_p;
- priv_get_ref(after_this.next_node_) = next_b;
- }
- }
-
- void swap(basic_multiallocation_slist &other_chain)
- {
- std::swap(this->it_, other_chain.it_);
- }
-
- static iterator iterator_to(void_pointer p)
- { return iterator(p); }
-
- void_pointer extract_data()
- {
- void_pointer ret = empty() ? void_pointer(0) : void_pointer(&*it_);
- it_ = iterator();
- return ret;
- }
-};
-
-template<class VoidPointer>
-class basic_multiallocation_cached_slist
-{
- private:
- basic_multiallocation_slist<VoidPointer> slist_;
- typename basic_multiallocation_slist<VoidPointer>::iterator last_;
-
- basic_multiallocation_cached_slist(basic_multiallocation_cached_slist &);
- basic_multiallocation_cached_slist &operator=(basic_multiallocation_cached_slist &);
-
- public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_slist)
-
- typedef typename basic_multiallocation_slist<VoidPointer>::void_pointer void_pointer;
- typedef typename basic_multiallocation_slist<VoidPointer>::iterator iterator;
-
- basic_multiallocation_cached_slist()
- : slist_(), last_(slist_.before_begin())
- {}
-/*
- basic_multiallocation_cached_slist(iterator first_node)
- : slist_(first_node), last_(slist_.before_begin())
- {
- iterator end;
- while(first_node != end){
- ++last_;
- }
- }*/
-
- basic_multiallocation_cached_slist(void_pointer p1, void_pointer p2)
- : slist_(p1), last_(p2 ? iterator_to(p2) : slist_.before_begin())
- {}
-
- basic_multiallocation_cached_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
- : slist_(), last_(slist_.before_begin())
- { this->swap(other); }
-
- basic_multiallocation_cached_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_slist) other)
- {
- basic_multiallocation_cached_slist tmp(boost::interprocess::move(other));
- this->swap(tmp);
- return *this;
- }
-
- bool empty() const
- { return slist_.empty(); }
-
- iterator before_begin() const
- { return slist_.before_begin(); }
-
- iterator begin() const
- { return slist_.begin(); }
-
- iterator end() const
- { return slist_.end(); }
-
- iterator last() const
- { return last_; }
-
- void clear()
- {
- slist_.clear();
- last_ = slist_.before_begin();
- }
-
- iterator insert_after(iterator it, void_pointer m)
- {
- slist_.insert_after(it, m);
- if(it == last_){
- last_ = slist_.iterator_to(m);
- }
- return iterator_to(m);
- }
-
- void push_front(void_pointer m)
- { this->insert_after(this->before_begin(), m); }
-
- void push_back(void_pointer m)
- { this->insert_after(last_, m); }
-
- void pop_front()
- {
- if(last_ == slist_.begin()){
- last_ = slist_.before_begin();
- }
- slist_.pop_front();
- }
-
- void *front() const
- { return slist_.front(); }
-
- void splice_after(iterator after_this, iterator before_begin, iterator before_end)
- {
- if(before_begin == before_end)
- return;
- if(after_this == last_){
- last_ = before_end;
- }
- slist_.splice_after(after_this, before_begin, before_end);
- }
-
- void swap(basic_multiallocation_cached_slist &x)
- {
- slist_.swap(x.slist_);
- using std::swap;
- swap(last_, x.last_);
- if(last_ == x.before_begin()){
- last_ = this->before_begin();
- }
- if(x.last_ == this->before_begin()){
- x.last_ = x.before_begin();
- }
- }
-
- static iterator iterator_to(void_pointer p)
- { return basic_multiallocation_slist<VoidPointer>::iterator_to(p); }
-
- std::pair<void_pointer, void_pointer> extract_data()
- {
- if(this->empty()){
- return std::pair<void_pointer, void_pointer>(void_pointer(0), void_pointer(0));
- }
- else{
- void_pointer p1 = slist_.extract_data();
- void_pointer p2 = void_pointer(&*last_);
- last_ = iterator();
- return std::pair<void_pointer, void_pointer>(p1, p2);
- }
- }
-};
-
-template<class MultiallocatorCachedSlist>
-class basic_multiallocation_cached_counted_slist
-{
- private:
- MultiallocatorCachedSlist cached_slist_;
- std::size_t size_;
-
- basic_multiallocation_cached_counted_slist(basic_multiallocation_cached_counted_slist &);
- basic_multiallocation_cached_counted_slist &operator=(basic_multiallocation_cached_counted_slist &);
-
- public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(basic_multiallocation_cached_counted_slist)
-
- typedef typename MultiallocatorCachedSlist::void_pointer void_pointer;
- typedef typename MultiallocatorCachedSlist::iterator iterator;
-
- basic_multiallocation_cached_counted_slist()
- : cached_slist_(), size_(0)
- {}
-
- basic_multiallocation_cached_counted_slist(void_pointer p1, void_pointer p2, std::size_t n)
- : cached_slist_(p1, p2), size_(n)
- {}
-
- basic_multiallocation_cached_counted_slist(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
- : cached_slist_(), size_(0)
- { this->swap(other); }
-
- basic_multiallocation_cached_counted_slist& operator=(BOOST_INTERPROCESS_RV_REF(basic_multiallocation_cached_counted_slist) other)
- {
- basic_multiallocation_cached_counted_slist tmp(boost::interprocess::move(other));
- this->swap(tmp);
- return *this;
- }
-
- basic_multiallocation_cached_counted_slist (MultiallocatorCachedSlist mem, std::size_t n)
- : cached_slist_(boost::interprocess::move(mem)), size_(n)
- {}
-
- bool empty() const
- { return cached_slist_.empty(); }
-
- std::size_t size() const
- { return size_; }
-
- iterator before_begin() const
- { return cached_slist_.before_begin(); }
-
- iterator begin() const
- { return cached_slist_.begin(); }
-
- iterator end() const
- { return cached_slist_.end(); }
-
- iterator last() const
- { return cached_slist_.last(); }
-
- void clear()
- {
- cached_slist_.clear();
- size_ = 0;
- }
-
- iterator insert_after(iterator it, void_pointer m)
- {
- iterator ret = cached_slist_.insert_after(it, m);
- ++size_;
- return ret;
- }
-
- void push_front(void_pointer m)
- { this->insert_after(this->before_begin(), m); }
-
- void push_back(void_pointer m)
- { this->insert_after(this->before_begin(), m); }
-
- void pop_front()
- {
- cached_slist_.pop_front();
- --size_;
- }
-
- void *front() const
- { return cached_slist_.front(); }
-
- void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end)
- {
- std::size_t n = static_cast<std::size_t>(std::distance(before_begin, before_end));
- this->splice_after(after_this, x, before_begin, before_end, n);
- }
-
- void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x, iterator before_begin, iterator before_end, std::size_t n)
- {
- cached_slist_.splice_after(after_this, before_begin, before_end);
- size_ += n;
- x.size_ -= n;
- }
-
- void splice_after(iterator after_this, basic_multiallocation_cached_counted_slist &x)
- {
- cached_slist_.splice_after(after_this, x.before_begin(), x.last());
- size_ += x.size_;
- x.size_ = 0;
- }
-
- void swap(basic_multiallocation_cached_counted_slist &x)
- {
- cached_slist_.swap(x.cached_slist_);
- using std::swap;
- swap(size_, x.size_);
- }
-
- static iterator iterator_to(void_pointer p)
- { return MultiallocatorCachedSlist::iterator_to(p); }
-
- std::pair<void_pointer, void_pointer> extract_data()
- {
- size_ = 0;
- return cached_slist_.extract_data();
- }
-};
-
-template<class T>
-struct cast_functor
-{
- typedef typename detail::add_reference<T>::type result_type;
- result_type operator()(char &ptr) const
- { return *static_cast<T*>(static_cast<void*>(&ptr)); }
-};
-
-
-template<class MultiallocationChain, class T>
-class transform_multiallocation_chain
-{
-private:
-
- MultiallocationChain holder_;
- typedef typename MultiallocationChain::void_pointer void_pointer;
- typedef typename boost::pointer_to_other
- <void_pointer, T>::type pointer;
-
- transform_multiallocation_chain(transform_multiallocation_chain &);
- transform_multiallocation_chain &operator=(transform_multiallocation_chain &);
-
- static pointer cast(void_pointer p)
- {
- return pointer(static_cast<T*>(detail::get_pointer(p)));
- }
-
-public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(transform_multiallocation_chain)
-
- typedef transform_iterator
- < typename MultiallocationChain::iterator
- , detail::cast_functor <T> > iterator;
-
- transform_multiallocation_chain(void_pointer p1, void_pointer p2, std::size_t n)
- : holder_(p1, p2, n)
- {}
-
- transform_multiallocation_chain()
- : holder_()
- {}
-
- transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
- : holder_()
- { this->swap(other); }
-
- transform_multiallocation_chain(BOOST_INTERPROCESS_RV_REF(MultiallocationChain) other)
- : holder_(boost::interprocess::move(other))
- {}
-
- transform_multiallocation_chain& operator=(BOOST_INTERPROCESS_RV_REF(transform_multiallocation_chain) other)
- {
- transform_multiallocation_chain tmp(boost::interprocess::move(other));
- this->swap(tmp);
- return *this;
- }
-
- void push_front(pointer mem)
- { holder_.push_front(mem); }
-
- void swap(transform_multiallocation_chain &other_chain)
- { holder_.swap(other_chain.holder_); }
- /*
- void splice_after(iterator after_this, iterator before_begin, iterator before_end)
- { holder_.splice_after(after_this.base(), before_begin.base(), before_end.base()); }
- */
- void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, std::size_t n)
- { holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n); }
-
- void pop_front()
- { holder_.pop_front(); }
-
- pointer front() const
- { return cast(holder_.front()); }
-
- bool empty() const
- { return holder_.empty(); }
-
- iterator before_begin() const
- { return iterator(holder_.before_begin()); }
-
- iterator begin() const
- { return iterator(holder_.begin()); }
-
- iterator end() const
- { return iterator(holder_.end()); }
-
- iterator last() const
- { return iterator(holder_.last()); }
-
- std::size_t size() const
- { return holder_.size(); }
-
- void clear()
- { holder_.clear(); }
-
- iterator insert_after(iterator it, pointer m)
- { return iterator(holder_.insert_after(it.base(), m)); }
-
- static iterator iterator_to(pointer p)
- { return iterator(MultiallocationChain::iterator_to(p)); }
-
- std::pair<void_pointer, void_pointer> extract_data()
- { return holder_.extract_data(); }
-
- MultiallocationChain extract_multiallocation_chain()
- {
- return MultiallocationChain(boost::interprocess::move(holder_));
- }
-};
-
 //!This class implements several allocation functions shared by different algorithms
 //!(aligned allocation, multiple allocation...).
 template<class MemoryAlgorithm>

Modified: trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp
==============================================================================
--- trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp (original)
+++ trunk/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -29,6 +29,7 @@
 #include <boost/interprocess/detail/multi_segment_services.hpp>
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/interprocess/detail/min_max.hpp>
 #include <boost/interprocess/sync/scoped_lock.hpp>
 #include <algorithm>
 #include <utility>

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -22,6 +22,7 @@
 
 #include <boost/interprocess/interprocess_fwd.hpp>
 #include <boost/interprocess/containers/allocation_type.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/offset_ptr.hpp>
 #include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/exceptions.hpp>
@@ -63,9 +64,8 @@
    typedef MutexFamily mutex_family;
    //!Pointer type to be used with the rest of the Interprocess framework
    typedef VoidPointer void_pointer;
- typedef detail::basic_multiallocation_cached_slist<void_pointer> multialloc_cached;
- typedef detail::basic_multiallocation_cached_counted_slist
- <multialloc_cached> multiallocation_chain;
+ typedef boost::container::containers_detail::
+ basic_multiallocation_chain<VoidPointer> multiallocation_chain;
 
    private:
    class block_ctrl;

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -23,6 +23,7 @@
 #include <boost/interprocess/interprocess_fwd.hpp>
 #include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
 #include <boost/interprocess/containers/allocation_type.hpp>
+#include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
 #include <boost/interprocess/offset_ptr.hpp>
 #include <boost/interprocess/sync/interprocess_mutex.hpp>
 #include <boost/interprocess/exceptions.hpp>
@@ -69,11 +70,8 @@
    typedef MutexFamily mutex_family;
    //!Pointer type to be used with the rest of the Interprocess framework
    typedef VoidPointer void_pointer;
- //typedef detail::basic_multiallocation_cached_counted_slist<void_pointer> multiallocation_chain;
-
- typedef detail::basic_multiallocation_cached_slist<void_pointer> multialloc_cached;
- typedef detail::basic_multiallocation_cached_counted_slist
- <multialloc_cached> multiallocation_chain;
+ typedef boost::container::containers_detail::
+ basic_multiallocation_chain<VoidPointer> multiallocation_chain;
 
    /// @cond
 

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/offset_ptr.hpp
==============================================================================
--- trunk/boost/interprocess/offset_ptr.hpp (original)
+++ trunk/boost/interprocess/offset_ptr.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/segment_manager.hpp
==============================================================================
--- trunk/boost/interprocess/segment_manager.hpp (original)
+++ trunk/boost/interprocess/segment_manager.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -989,7 +989,7 @@
       //If not found, return false
       if(it == index.end()){
          //This name is not present in the index, wrong pointer or name!
- assert(0);
+ //assert(0);
          return false;
       }
       return this->priv_generic_named_destroy_impl<CharT>(it, index, table);

Modified: trunk/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- trunk/boost/interprocess/shared_memory_object.hpp (original)
+++ trunk/boost/interprocess/shared_memory_object.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -47,13 +47,10 @@
 {
    /// @cond
    //Non-copyable and non-assignable
- shared_memory_object(shared_memory_object &);
- shared_memory_object &operator=(shared_memory_object &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(shared_memory_object)
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(shared_memory_object)
-
    //!Default constructor. Represents an empty shared_memory_object.
    shared_memory_object();
 
@@ -109,11 +106,11 @@
    //!use remove().
    ~shared_memory_object();
 
- //!Returns the name of the file.
+ //!Returns the name of the shared memory object.
    const char *get_name() const;
 
- //!Returns the name of the file
- //!used in the constructor
+ //!Returns true if the size of the shared memory object
+ //!can be obtained and writes the size in the passed reference
    bool get_size(offset_t &size) const;
 
    //!Returns access mode

Modified: trunk/boost/interprocess/smart_ptr/deleter.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/deleter.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/deleter.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008.
+// (C) Copyright Ion Gaztanaga 2007-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -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-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2006-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/sp_counted_base.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008.
+// (C) Copyright Ion Gaztanaga 2007-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
==============================================================================
--- trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp (original)
+++ trunk/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -9,7 +9,7 @@
 
 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 // Copyright 2004-2005 Peter Dimov
-// Copyright 2007-2008 Ion Gaztanaga
+// Copyright 2007-2009 Ion Gaztanaga
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -4,7 +4,7 @@
 //
 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
 // (C) Copyright Peter Dimov 2001, 2002, 2003
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
@@ -108,8 +108,8 @@
    typedef typename boost::pointer_to_other
             <typename VoidAllocator::pointer, const VoidAllocator>::type const_allocator_pointer;
 
+ BOOST_COPYABLE_AND_MOVABLE(shared_ptr)
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(shared_ptr)
 
    //!Constructs an empty shared_ptr.
    //!Use_count() == 0 && get()== 0.
@@ -193,6 +193,14 @@
       return *this;
    }
 
+ //!Equivalent to shared_ptr(r).swap(*this).
+ //!Never throws
+ shared_ptr & operator=(BOOST_INTERPROCESS_COPY_ASSIGN_REF(shared_ptr) r)
+ {
+ m_pn = r.m_pn; // shared_count::op= doesn't throw
+ return *this;
+ }
+
    //!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
    //!Never throws
    shared_ptr & operator=(BOOST_INTERPROCESS_RV_REF(shared_ptr) other) // never throws

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -88,7 +88,6 @@
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(unique_ptr)
 
    typedef T element_type;
    typedef D deleter_type;
@@ -326,12 +325,10 @@
    /// @cond
    private:
    boost::compressed_pair<pointer, D> ptr_;
-
- unique_ptr(unique_ptr&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(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>&);
    template <class U> typename detail::unique_ptr_error<U>::type operator=(U&);
    /// @endcond

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -3,7 +3,7 @@
 // This file is the adaptation for Interprocess of boost/weak_ptr.hpp
 //
 // (C) Copyright Peter Dimov 2001, 2002, 2003
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)

Modified: trunk/boost/interprocess/streams/bufferstream.hpp
==============================================================================
--- trunk/boost/interprocess/streams/bufferstream.hpp (original)
+++ trunk/boost/interprocess/streams/bufferstream.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/streams/vectorstream.hpp
==============================================================================
--- trunk/boost/interprocess/streams/vectorstream.hpp (original)
+++ trunk/boost/interprocess/streams/vectorstream.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_condition.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -157,7 +157,8 @@
       else{
          //Notification occurred, we will lock the checking interprocess_mutex so that
          //if a notify_one notification occurs, only one thread can exit
- //---------------------------------------------------------------
+ //---------------------------------------------------------------
+ /*
          InternalLock lock;
          if(tout_enabled){
             InternalLock dummy(m_check_mut, abs_time);
@@ -167,13 +168,15 @@
             InternalLock dummy(m_check_mut);
             lock = boost::interprocess::move(dummy);
          }
-
          if(!lock){
             timed_out = true;
             unlock_enter_mut = true;
+ detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
             break;
          }
          //---------------------------------------------------------------
+ */
+ //InternalLock lock(m_check_mut);
          boost::uint32_t result = detail::atomic_cas32
                         (const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ONE);
          if(result == SLEEP){

Modified: trunk/boost/interprocess/sync/emulation/interprocess_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -112,6 +112,7 @@
    detail::systemwide_thread_id_copy(m_nOwner, old_id);
    const handle_t thr_id(detail::get_current_systemwide_thread_id());
    (void)old_id;
+ (void)thr_id;
    assert(detail::equal_systemwide_thread_id(thr_id, old_id));
    --m_nLockCount;
    if(!m_nLockCount){

Modified: trunk/boost/interprocess/sync/emulation/interprocess_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/interprocess_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/interprocess_semaphore.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -10,46 +10,34 @@
 
 #include<boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
 
 namespace boost {
 namespace interprocess {
 
+
 inline interprocess_semaphore::~interprocess_semaphore()
 {}
 
 inline interprocess_semaphore::interprocess_semaphore(unsigned int initialCount)
- : m_mut(), m_cond(), m_count(initialCount)
-{
- if(m_count < 0){
- throw interprocess_exception(size_error);
- }
-}
+{ detail::atomic_write32(&this->m_count, boost::uint32_t(initialCount)); }
 
 inline void interprocess_semaphore::post()
 {
- scoped_lock<interprocess_mutex> lock(m_mut);
- m_cond.notify_one();
- ++m_count;
+ detail::atomic_inc32(&m_count);
 }
 
 inline void interprocess_semaphore::wait()
 {
- scoped_lock<interprocess_mutex> lock(m_mut);
- while(m_count == 0){
- m_cond.wait(lock);
+ while(!detail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0))){
+ while(detail::atomic_read32(&m_count) == 0){
+ detail::thread_yield();
+ }
    }
- --m_count;
 }
 
 inline bool interprocess_semaphore::try_wait()
 {
- scoped_lock<interprocess_mutex> lock(m_mut);
- if(m_count == 0){
- return false;
- }
- --m_count;
- return true;
+ return detail::atomic_add_unless32(&m_count, boost::uint32_t(-1), boost::uint32_t(0));
 }
 
 inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
@@ -58,19 +46,29 @@
       this->wait();
       return true;
    }
- scoped_lock<interprocess_mutex> lock(m_mut);
- while(m_count == 0){
- if(!m_cond.timed_wait(lock, abs_time))
- return m_count != 0;
- }
- --m_count;
+ //Obtain current count and target time
+ boost::posix_time::ptime now(microsec_clock::universal_time());
+ if(now >= abs_time)
+ return false;
+
+ do{
+ if(this->try_wait()){
+ break;
+ }
+ now = microsec_clock::universal_time();
+
+ if(now >= abs_time){
+ return this->try_wait();
+ }
+ // relinquish current time slice
+ detail::thread_yield();
+ }while (true);
    return true;
 }
 /*
 inline int interprocess_semaphore::get_count() const
 {
- scoped_lock<interprocess_mutex> lock(m_mut);
- return count;
+ return (int)detail::atomic_read32(&m_count);
 }*/
 
 } //namespace interprocess {

Modified: trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp
==============================================================================
--- trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp (original)
+++ trunk/boost/interprocess/sync/emulation/named_creation_functor.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/file_lock.hpp (original)
+++ trunk/boost/interprocess/sync/file_lock.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -39,12 +39,10 @@
 {
    /// @cond
    //Non-copyable
- file_lock(const file_lock &);
- file_lock &operator=(const file_lock &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(file_lock)
    /// @endcond
- public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(file_lock)
 
+ public:
    //!Constructs an empty file mapping.
    //!Does not throw
    file_lock()

Modified: trunk/boost/interprocess/sync/interprocess_barrier.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_barrier.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_barrier.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_condition.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -149,7 +149,7 @@
    #if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
       enum { SLEEP = 0, NOTIFY_ONE, NOTIFY_ALL };
       interprocess_mutex m_enter_mut;
- interprocess_mutex m_check_mut;
+ //interprocess_mutex m_check_mut;
       volatile boost::uint32_t m_command;
       volatile boost::uint32_t m_num_waiters;
       bool do_timed_wait(bool tout_enabled, const boost::posix_time::ptime &abs_time, interprocess_mutex &mut);

Modified: trunk/boost/interprocess/sync/interprocess_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/interprocess_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/interprocess_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/interprocess_semaphore.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -36,8 +36,6 @@
    #include <boost/interprocess/detail/atomic.hpp>
    #include <boost/cstdint.hpp>
    #include <boost/interprocess/detail/os_thread_functions.hpp>
- #include <boost/interprocess/sync/interprocess_mutex.hpp>
- #include <boost/interprocess/sync/interprocess_condition.hpp>
    #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION
 #endif
 
@@ -95,9 +93,7 @@
    /// @cond
    private:
    #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- interprocess_mutex m_mut;
- interprocess_condition m_cond;
- int m_count;
+ volatile boost::uint32_t m_count;
    #else
    detail::semaphore_wrapper m_sem;
    #endif //#if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/lock_options.hpp
==============================================================================
--- trunk/boost/interprocess/sync/lock_options.hpp (original)
+++ trunk/boost/interprocess/sync/lock_options.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/mutex_family.hpp
==============================================================================
--- trunk/boost/interprocess/sync/mutex_family.hpp (original)
+++ trunk/boost/interprocess/sync/mutex_family.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_condition.hpp (original)
+++ trunk/boost/interprocess/sync/named_condition.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/named_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/named_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/named_semaphore.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
  //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/null_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/null_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/null_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/posix/interprocess_condition.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/interprocess_condition.hpp (original)
+++ trunk/boost/interprocess/sync/posix/interprocess_condition.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/posix/interprocess_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/interprocess_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/posix/interprocess_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp (original)
+++ trunk/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/posix/interprocess_semaphore.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/interprocess_semaphore.hpp (original)
+++ trunk/boost/interprocess/sync/posix/interprocess_semaphore.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/posix/ptime_to_timespec.hpp
==============================================================================
--- trunk/boost/interprocess/sync/posix/ptime_to_timespec.hpp (original)
+++ trunk/boost/interprocess/sync/posix/ptime_to_timespec.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

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 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/interprocess/sync/scoped_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/scoped_lock.hpp (original)
+++ trunk/boost/interprocess/sync/scoped_lock.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -53,12 +53,10 @@
    /// @cond
    private:
    typedef scoped_lock<Mutex> this_type;
- scoped_lock(scoped_lock&);
- scoped_lock& operator= (scoped_lock&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(scoped_lock)
    typedef bool this_type::*unspecified_bool_type;
    /// @endcond
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(scoped_lock)
 
    typedef Mutex mutex_type;
 

Modified: trunk/boost/interprocess/sync/sharable_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/sharable_lock.hpp (original)
+++ trunk/boost/interprocess/sync/sharable_lock.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -54,14 +54,11 @@
    /// @cond
    private:
    typedef sharable_lock<SharableMutex> this_type;
- sharable_lock(sharable_lock&);
    explicit sharable_lock(scoped_lock<mutex_type>&);
    typedef bool this_type::*unspecified_bool_type;
- sharable_lock& operator=(sharable_lock&);
- sharable_lock& operator=(scoped_lock<mutex_type>&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(sharable_lock)
    /// @endcond
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(sharable_lock)
 
    //!Effects: Default constructs a sharable_lock.
    //!Postconditions: owns() == false and mutex() == 0.

Modified: trunk/boost/interprocess/sync/upgradable_lock.hpp
==============================================================================
--- trunk/boost/interprocess/sync/upgradable_lock.hpp (original)
+++ trunk/boost/interprocess/sync/upgradable_lock.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -55,14 +55,11 @@
    /// @cond
    private:
    typedef upgradable_lock<UpgradableMutex> this_type;
- upgradable_lock(upgradable_lock&);
    explicit upgradable_lock(scoped_lock<mutex_type>&);
    typedef bool this_type::*unspecified_bool_type;
- upgradable_lock& operator=(upgradable_lock&);
- upgradable_lock& operator=(scoped_lock<mutex_type>&);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(upgradable_lock)
    /// @endcond
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(upgradable_lock)
 
    //!Effects: Default constructs a upgradable_lock.
    //!Postconditions: owns() == false and mutex() == 0.

Added: trunk/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/xsi/advanced_xsi_semaphore.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,193 @@
+/*
+ * Provide an simpler and easier to understand interface to the System V
+ * semaphore system calls. There are 7 routines available to the user:
+ *
+ * id = sem_create(key, initval); # create with initial value or open
+ * id = sem_open(key); # open (must already exist)
+ * sem_wait(id); # wait = P = down by 1
+ * sem_signal(id); # signal = V = up by 1
+ * sem_op(id, amount); # wait if (amount < 0)
+ * # signal if (amount > 0)
+ * sem_close(id); # close
+ * sem_rm(id); # remove (delete)
+ *
+ * We create and use a 3-member set for the requested semaphore.
+ * The first member, [0], is the actual semaphore value, and the second
+ * member, [1], is a counter used to know when all processes have finished
+ * with the semaphore. The counter is initialized to a large number,
+ * decremented on every create or open and incremented on every close.
+ * This way we can use the "adjust" feature provided by System V so that
+ * any process that exit's without calling sem_close() is accounted
+ * for. It doesn't help us if the last process does this (as we have
+ * no way of getting control to remove the semaphore) but it will
+ * work if any process other than the last does an exit (intentional
+ * or unintentional).
+ * The third member, [2], of the semaphore set is used as a lock variable
+ * to avoid any race conditions in the sem_create() and sem_close()
+ * functions.
+ */
+
+#ifndef BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
+#define BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <errno.h>
+
+namespace boost {
+namespace interprocess {
+namespace xsi {
+
+// Create a semaphore with a specified initial value.
+// If the semaphore already exists, we don't initialize it (of course).
+// We return the semaphore ID if all OK, else -1.
+
+inline bool advanced_sem_open_or_create(::key_t key, int initval, int &semid, int perm)
+{
+ semid = -1;
+ int id, semval;
+ union semun {
+ int val;
+ ::semid_ds *buf;
+ ushort *array;
+ } semctl_arg;
+
+ if (key == IPC_PRIVATE)
+ return false; //not intended for private semaphores
+
+ else if (key == (::key_t) -1)
+ return false; //probably an ftok() error by caller
+
+ again:
+ if ((id = ::semget(key, 3, (perm & 0x01FF) | IPC_CREAT)) < 0)
+ return false; //permission problem or tables full
+
+ // When the semaphore is created, we know that the value of all
+ // 3 members is 0.
+ // Get a lock on the semaphore by waiting for [2] to equal 0,
+ // then increment it.
+ //
+ // There is a race condition here. There is a possibility that
+ // between the semget() above and the ::semop() below, another
+ // process can call our sem_close() function which can remove
+ // the semaphore if that process is the last one using it.
+ // Therefore, we handle the error condition of an invalid
+ // semaphore ID specially below, and if it does happen, we just
+ // go back and create it again.
+ struct sembuf op_lock[2] = {
+ {2, 0, 0}, // wait for [2] (lock) to equal 0
+ {2, 1, SEM_UNDO} // then increment [2] to 1 - this locks it
+ // UNDO to release the lock if processes exits
+ // before explicitly unlocking
+ };
+
+ if (::semop(id, &op_lock[0], 2) < 0) {
+ if (errno == EINVAL)
+ goto again;
+ }
+
+ // Get the value of the process counter. If it equals 0,
+ // then no one has initialized the semaphore yet.
+ if ((semval = ::semctl(id, 1, GETVAL, 0)) < 0)
+ return false;
+
+ if (semval == 0) {
+ // We could initialize by doing a SETALL, but that
+ // would clear the adjust value that we set when we
+ // locked the semaphore above. Instead, we'll do 2
+ // system calls to initialize [0] and [1].
+ semctl_arg.val = initval;
+ if (::semctl(id, 0, SETVAL, semctl_arg) < 0)
+ return false;
+
+ semctl_arg.val = 1;
+ if (::semctl(id, 1, SETVAL, semctl_arg) < 0)
+ return false;
+ }
+
+ // Decrement the process counter and then release the lock.
+ struct sembuf op_unlock[1] = {
+ 2, -1, 0/*SEM_UNDO*/ // decrement [2] (lock) back to 0
+ };
+
+ if (::semop(id, &op_unlock[0], 1) < 0)
+ return false;
+
+ semid = id;
+ return true;
+}
+
+// Open a semaphore that must already exist.
+// This function should be used, instead of sem_create(), if the caller
+// knows that the semaphore must already exist. For example a client
+// from a client-server pair would use this, if its the server's
+// responsibility to create the semaphore.
+// We return the semaphore ID if all OK, else -1.
+/*
+inline bool advanced_sem_open(key_t key, int &semid)
+{
+ semid = -1;
+ if (key == IPC_PRIVATE)
+ return false; // not intended for private semaphores
+
+ else if (key == (::key_t) -1)
+ return false; // probably an ftok() error by caller
+
+ if ((semid = ::semget(key, 3, 0)) < 0)
+ return false; // doesn't exist, or tables full
+
+ // Decrement the process counter. We don't need a lock
+ struct sembuf op_open[1] = {
+ 1, -1, SEM_UNDO // decrement [1] (proc counter) with undo on exit
+ };
+
+ if (::semop(id, &op_open[0], 1) < 0)
+ return false;
+
+ return true;
+}
+*/
+/****************************************************************************
+ * Remove a semaphore.
+ * This call is intended to be called by a server, for example,
+ * when it is being shut down, as we do an IPC_RMID on the semaphore,
+ * regardless whether other processes may be using it or not.
+ * Most other processes should use sem_close() below.
+ */
+
+inline bool advanced_sem_rm(int id)
+{
+ if (::semctl(id, 0, IPC_RMID, 0) < 0)
+ return false;
+ return true;
+}
+
+
+/****************************************************************************
+ * General semaphore operation. Increment or decrement by a user-specified
+ * amount (positive or negative; amount can't be zero).
+ */
+
+inline bool advanced_sem_op(int id, int value, bool undo = true)
+{
+ ::sembuf op_op[1] = {
+ 0, 99, 0 // decrement or increment [0] with undo on exit
+ // the 99 is set to the actual amount to add
+ // or subtract (positive or negative)
+ };
+ if(undo){
+ op_op[0].sem_flg = SEM_UNDO;
+ }
+ if ((op_op[0].sem_op = value) == 0)
+ return false;
+
+ if (::semop(id, &op_op[0], 1) < 0)
+ return false;
+ return true;
+}
+
+} //namespace xsi {
+} //namespace interprocess {
+} //namespace boost {
+
+#endif //BOOST_INTERPROCESS_SYNC_XSI_ADVANCED_XSI_SEMAPHORE_HPP

Added: trunk/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/xsi/simple_xsi_semaphore.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,105 @@
+#ifndef BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
+#define BOOST_INTERPROCESS_SYNC_XSI_SIMPLE_XSI_SEMAPHORE_HPP
+
+/*
+ * Provide an simpler and easier to understand interface to the System V
+ * semaphore system calls. There are 7 routines available to the user:
+ *
+ * id = sem_create(key, initval); # create with initial value or open
+ * id = sem_open(key); # open (must already exist)
+ * sem_wait(id); # wait = P = down by 1
+ * sem_signal(id); # signal = V = up by 1
+ * sem_op(id, amount); # wait if (amount < 0)
+ * # signal if (amount > 0)
+ * sem_close(id); # close
+ * sem_rm(id); # remove (delete)
+ *
+ * We create and use a 3-member set for the requested semaphore.
+ * The first member, [0], is the actual semaphore value, and the second
+ * member, [1], is a counter used to know when all processes have finished
+ * with the semaphore. The counter is initialized to a large number,
+ * decremented on every create or open and incremented on every close.
+ * This way we can use the "adjust" feature provided by System V so that
+ * any process that exit's without calling sem_close() is accounted
+ * for. It doesn't help us if the last process does this (as we have
+ * no way of getting control to remove the semaphore) but it will
+ * work if any process other than the last does an exit (intentional
+ * or unintentional).
+ * The third member, [2], of the semaphore set is used as a lock variable
+ * to avoid any race conditions in the sem_create() and sem_close()
+ * functions.
+ */
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <errno.h>
+
+namespace boost {
+namespace interprocess {
+namespace xsi {
+
+// Create a semaphore with a specified initial value.
+// If the semaphore already exists, we don't initialize it (of course).
+// We return the semaphore ID if all OK, else -1.
+
+inline bool simple_sem_open_or_create(::key_t key, int initval, int &semid, int perm)
+{
+ int id, semval;
+ semid = -1;
+
+ if (key == IPC_PRIVATE)
+ return false; //not intended for private semaphores
+
+ else if (key == (::key_t) -1)
+ return false; //probably an ftok() error by caller
+
+ again:
+ if ((id = ::semget(key, 1, (perm & 0x01FF) | IPC_CREAT)) < 0)
+ return false; //permission problem or tables full
+
+ semid = id;
+ return true;
+}
+
+/****************************************************************************
+ * Remove a semaphore.
+ * This call is intended to be called by a server, for example,
+ * when it is being shut down, as we do an IPC_RMID on the semaphore,
+ * regardless whether other processes may be using it or not.
+ * Most other processes should use sem_close() below.
+ */
+
+inline bool simple_sem_rm(int id)
+{
+ if (::semctl(id, 0, IPC_RMID, 0) < 0)
+ return false;
+ return true;
+}
+
+
+/****************************************************************************
+ * General semaphore operation. Increment or decrement by a user-specified
+ * amount (positive or negative; amount can't be zero).
+ */
+
+inline bool simple_sem_op(int id, int value, bool undo = true)
+{
+ ::sembuf op_op[1] = {
+ 0, 99, 0 // decrement or increment [0] with undo on exit
+ // the 99 is set to the actual amount to add
+ // or subtract (positive or negative)
+ };
+ if(undo){
+ op_op[0].sem_flg = SEM_UNDO;
+ }
+ if ((op_op[0].sem_op = value) == 0)
+ return false;
+
+ if (::semop(id, &op_op[0], 1) < 0)
+ return false;
+ return true;
+}
+
+} //namespace xsi {
+} //namespace interprocess {
+} //namespace boost {

Added: trunk/boost/interprocess/sync/xsi/xsi_named_mutex.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/interprocess/sync/xsi/xsi_named_mutex.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,227 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
+#define BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#if defined(BOOST_INTERPROCESS_WINDOWS)
+#error "This header can't be used in Windows operating systems"
+#endif
+
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/creation_tags.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/sync/xsi/basic_xsi_semaphore.hpp>
+#include <cstddef>
+#include <cassert>
+#include <boost/cstdint.hpp>
+#include <string>
+
+//!\file
+//!Describes a class representing a xsi-based named_mutex.
+
+namespace boost {
+namespace interprocess {
+
+//!A class that wraps a XSI (System V)-based named semaphore
+//!that undoes the operation if the process crashes.
+class xsi_named_mutex
+{
+ /// @cond
+ //Non-copyable and non-assignable
+ xsi_named_mutex(xsi_named_mutex &);
+ xsi_named_mutex &operator=(xsi_named_mutex &);
+ /// @endcond
+
+ public:
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(xsi_named_mutex)
+
+ //!Default constructor.
+ //!Represents an empty xsi_named_mutex.
+ xsi_named_mutex();
+
+ //!Tries to create a new XSI-based named mutex with a key obtained from a call to ftok (with path
+ //!"path" and id "id"), and permissions "perm".
+ //!If the named mutex previously exists, it tries to open it.
+ //!Otherwise throws an error.
+ xsi_named_mutex(open_or_create_t, const char *path, boost::uint8_t id, int perm = 0666)
+ { this->priv_open_or_create(detail::DoOpenOrCreate, path, id, perm); }
+
+ //!Moves the ownership of "moved"'s named mutex to *this.
+ //!After the call, "moved" does not represent any named mutex
+ //!Does not throw
+ xsi_named_mutex(BOOST_INTERPROCESS_RV_REF(xsi_named_mutex) moved)
+ { this->swap(moved); }
+
+ //!Moves the ownership of "moved"'s named mutex to *this.
+ //!After the call, "moved" does not represent any named mutex.
+ //!Does not throw
+ xsi_named_mutex &operator=(BOOST_INTERPROCESS_RV_REF(xsi_named_mutex) moved)
+ {
+ xsi_named_mutex tmp(boost::interprocess::move(moved));
+ this->swap(tmp);
+ return *this;
+ }
+
+ //!Swaps two xsi_named_mutex. Does not throw
+ void swap(xsi_named_mutex &other);
+
+ //!Destroys *this. The named mutex is still valid after
+ //!destruction. use remove() to destroy the named mutex.
+ ~xsi_named_mutex();
+
+ //!Returns the path used to construct the
+ //!named mutex.
+ const char *get_path() const;
+
+ //!Returns access
+ //!permissions
+ int get_permissions() const;
+
+ //!Returns the mapping handle.
+ //!Never throws
+ mapping_handle_t get_mapping_handle() const;
+
+ //!Erases a XSI-based named mutex from the system.
+ //!Returns false on error. Never throws
+ bool remove();
+
+ void lock();
+
+ void unlock();
+
+ /// @cond
+ private:
+
+ //!Closes a previously opened file mapping. Never throws.
+ void priv_close();
+
+ //!Closes a previously opened file mapping. Never throws.
+ bool priv_open_or_create( detail::create_enum_t type
+ , const char *path
+ , boost::uint8_t id
+ , int perm);
+ int m_semid;
+ key_t m_key;
+ boost::uint8_t m_id;
+ int m_perm;
+ std::string m_path;
+ /// @endcond
+};
+
+/// @cond
+
+inline xsi_named_mutex::xsi_named_mutex()
+ : m_semid(-1), m_key(-1), m_id(0), m_perm(0), m_path()
+{}
+
+inline xsi_named_mutex::~xsi_named_mutex()
+{ this->priv_close(); }
+
+inline const char *xsi_named_mutex::get_path() const
+{ return m_path.c_str(); }
+
+inline void xsi_named_mutex::swap(xsi_named_mutex &other)
+{
+ std::swap(m_key, other.m_key);
+ std::swap(m_id, other.m_id);
+ std::swap(m_semid, other.m_semid);
+ std::swap(m_perm, other.m_perm);
+ m_path.swap(other.m_path);
+}
+
+inline mapping_handle_t xsi_named_mutex::get_mapping_handle() const
+{ mapping_handle_t mhnd = { m_semid, true}; return mhnd; }
+
+inline int xsi_named_mutex::get_permissions() const
+{ return m_perm; }
+
+inline bool xsi_named_mutex::priv_open_or_create
+ (detail::create_enum_t type, const char *path, boost::uint8_t id, int perm)
+{
+ key_t key;
+ if(path){
+ key = ::ftok(path, id);
+ if(((key_t)-1) == key){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+ }
+ else{
+ key = IPC_PRIVATE;
+ }
+
+ perm &= 0x01FF;
+
+ int semid;
+ if(!xsi::simple_sem_open_or_create(key, 1, semid, perm)){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+
+ m_perm = perm;
+ m_semid = semid;
+ m_path = path ? path : "";
+ m_id = id;
+ m_key = key;
+
+ return true;
+}
+
+inline void xsi_named_mutex::priv_close()
+{
+}
+
+inline void xsi_named_mutex::lock()
+{
+ if(!xsi::simple_sem_op(m_semid, -1)){
+ error_info err = system_error_code();
+ throw interprocess_exception(err);
+ }
+}
+
+inline void xsi_named_mutex::unlock()
+{
+ bool success = xsi::simple_sem_op(m_semid, 1);
+ (void)success;
+ assert(success);
+}
+
+inline bool xsi_named_mutex::remove()
+{
+ if(m_semid != -1){
+ int ret = ::semctl(m_semid, IPC_RMID, 0);
+ if(-1 == ret)
+ return false;
+ //Now put it in default-constructed state
+ m_semid = -1;
+ m_key = -1;
+ m_id = 0;
+ m_perm = 0;
+ m_path.clear();
+ }
+ return false;
+}
+
+///@endcond
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //BOOST_INTERPROCESS_XSI_XSI_NAMED_MUTEX_HPP

Modified: trunk/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- trunk/boost/interprocess/windows_shared_memory.hpp (original)
+++ trunk/boost/interprocess/windows_shared_memory.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -51,13 +51,10 @@
 {
    /// @cond
    //Non-copyable and non-assignable
- windows_shared_memory(windows_shared_memory &);
- windows_shared_memory &operator=(windows_shared_memory &);
+ BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(windows_shared_memory)
    /// @endcond
 
    public:
- BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(windows_shared_memory)
-
    //!Default constructor.
    //!Represents an empty windows_shared_memory.
    windows_shared_memory();

Modified: trunk/boost/intrusive/any_hook.hpp
==============================================================================
--- trunk/boost/intrusive/any_hook.hpp (original)
+++ trunk/boost/intrusive/any_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/avl_set.hpp
==============================================================================
--- trunk/boost/intrusive/avl_set.hpp (original)
+++ trunk/boost/intrusive/avl_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -489,6 +489,60 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_unique(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
@@ -1532,9 +1586,63 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_equal(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
- //! <b>Complexity</b>: Average complexity is constant time.
+ //! <b>Complexity</b>: Average complexity is constant time.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased element.
    //!

Modified: trunk/boost/intrusive/avl_set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/avl_set_hook.hpp (original)
+++ trunk/boost/intrusive/avl_set_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@
       ::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -221,6 +222,7 @@
       ::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: trunk/boost/intrusive/avltree.hpp
==============================================================================
--- trunk/boost/intrusive/avltree.hpp (original)
+++ trunk/boost/intrusive/avltree.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -704,6 +704,76 @@
       return iterator(to_insert, this);
    }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ return iterator(node_algorithms::insert_before
+ (node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
+ }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity for erase element is constant time.

Modified: trunk/boost/intrusive/avltree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/avltree_algorithms.hpp (original)
+++ trunk/boost/intrusive/avltree_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -531,6 +531,66 @@
    }
 
    //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node)
+ {
+ tree_algorithms::insert_before(header, pos, new_node);
+ rebalance_after_insertion(header, new_node);
+ return new_node;
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_back(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_back(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_front(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_front(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
    //! KeyNodePtrCompare is a function object that induces a strict weak
    //! ordering compatible with the strict weak ordering used to create the
    //! the tree. NodePtrCompare compares KeyType with a node_ptr.

Modified: trunk/boost/intrusive/bs_set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/bs_set_hook.hpp (original)
+++ trunk/boost/intrusive/bs_set_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@
 
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -220,6 +221,7 @@
       ::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: trunk/boost/intrusive/circular_list_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/circular_list_algorithms.hpp (original)
+++ trunk/boost/intrusive/circular_list_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -110,7 +110,7 @@
    //! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
    //! is empty, returns 1.
    //!
- //! <b>Complexity</b>: Constant
+ //! <b>Complexity</b>: Linear
    //!
    //! <b>Throws</b>: Nothing.
    static std::size_t count(const_node_ptr this_node)

Modified: trunk/boost/intrusive/circular_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/circular_slist_algorithms.hpp (original)
+++ trunk/boost/intrusive/circular_slist_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -199,7 +199,7 @@
    //! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
    //! is empty, returns 1.
    //!
- //! <b>Complexity</b>: Constant
+ //! <b>Complexity</b>: Linear
    //!
    //! <b>Throws</b>: Nothing.
    static std::size_t count(const_node_ptr this_node)

Modified: trunk/boost/intrusive/derivation_value_traits.hpp
==============================================================================
--- trunk/boost/intrusive/derivation_value_traits.hpp (original)
+++ trunk/boost/intrusive/derivation_value_traits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/any_node_and_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/detail/any_node_and_algorithms.hpp (original)
+++ trunk/boost/intrusive/detail/any_node_and_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/assert.hpp
==============================================================================
--- trunk/boost/intrusive/detail/assert.hpp (original)
+++ trunk/boost/intrusive/detail/assert.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/clear_on_destructor_base.hpp
==============================================================================
--- trunk/boost/intrusive/detail/clear_on_destructor_base.hpp (original)
+++ trunk/boost/intrusive/detail/clear_on_destructor_base.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////} // ///////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/intrusive/detail/common_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/detail/common_slist_algorithms.hpp (original)
+++ trunk/boost/intrusive/detail/common_slist_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -74,15 +74,22 @@
       NodeTraits::set_next(prev_node, this_node);
    }
 
- static void transfer_after(node_ptr p, node_ptr b, node_ptr e)
+ static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be)
    {
- if (p != b && p != e && b != e) {
- node_ptr next_b = NodeTraits::get_next(b);
- node_ptr next_e = NodeTraits::get_next(e);
- node_ptr next_p = NodeTraits::get_next(p);
- NodeTraits::set_next(b, next_e);
- NodeTraits::set_next(e, next_p);
- NodeTraits::set_next(p, next_b);
+ node_ptr p(NodeTraits::get_next(bp));
+ NodeTraits::set_next(bp, b);
+ NodeTraits::set_next(be, p);
+ }
+
+ static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be)
+ {
+ if (bp != bb && bp != be && bb != be) {
+ node_ptr next_b = NodeTraits::get_next(bb);
+ node_ptr next_e = NodeTraits::get_next(be);
+ node_ptr next_p = NodeTraits::get_next(bp);
+ NodeTraits::set_next(bb, next_e);
+ NodeTraits::set_next(be, next_p);
+ NodeTraits::set_next(bp, next_b);
       }
    }
 };

Modified: trunk/boost/intrusive/detail/config_begin.hpp
==============================================================================
--- trunk/boost/intrusive/detail/config_begin.hpp (original)
+++ trunk/boost/intrusive/detail/config_begin.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/config_end.hpp
==============================================================================
--- trunk/boost/intrusive/detail/config_end.hpp (original)
+++ trunk/boost/intrusive/detail/config_end.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/ebo_functor_holder.hpp
==============================================================================
--- trunk/boost/intrusive/detail/ebo_functor_holder.hpp (original)
+++ trunk/boost/intrusive/detail/ebo_functor_holder.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Joaquin M Lopez Munoz 2006-2008
+// (C) Copyright Joaquin M Lopez Munoz 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
 #ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
 #define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
 
+#include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 
 namespace boost {
@@ -89,4 +90,6 @@
 } //namespace intrusive {
 } //namespace boost {
 
+#include <boost/intrusive/detail/config_end.hpp>
+
 #endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP

Added: trunk/boost/intrusive/detail/function_detector.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/detail/function_detector.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,87 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2009.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+// This code was modified from the code posted by Alexandre Courpron in his
+// article "Interface Detection" in The Code Project:
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2007 Alexandre Courpron
+//
+// Permission to use, copy, modify, redistribute and sell this software,
+// provided that this copyright notice appears on all copies of the software.
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
+#define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+
+namespace boost {
+namespace intrusive {
+namespace function_detector {
+
+ typedef char NotFoundType;
+ struct StaticFunctionType { NotFoundType x [2]; };
+ struct NonStaticFunctionType { NotFoundType x [3]; };
+
+ enum
+ { NotFound = 0,
+ StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ),
+ NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
+ };
+
+} //namespace boost {
+} //namespace intrusive {
+} //namespace function_detector {
+
+#define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
+ namespace boost { \
+ namespace intrusive { \
+ namespace function_detector { \
+ template < class T, \
+ class NonStaticType, \
+ class NonStaticConstType, \
+ class StaticType > \
+ class DetectMember_##InstantiationKey_##Identifier { \
+ template < NonStaticType > \
+ struct TestNonStaticNonConst ; \
+ \
+ template < NonStaticConstType > \
+ struct TestNonStaticConst ; \
+ \
+ template < StaticType > \
+ struct TestStatic ; \
+ \
+ template <class U > \
+ static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
+ \
+ template <class U > \
+ static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
+ \
+ template <class U> \
+ static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
+ \
+ template <class U> \
+ static NotFoundType Test( ... ); \
+ public : \
+ static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
+ };\
+}}} //namespace boost::intrusive::function_detector {
+
+#define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
+ ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
+ ReturnType (Class::*)Params,\
+ ReturnType (Class::*)Params const,\
+ ReturnType (*)Params \
+ >::check
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP

Modified: trunk/boost/intrusive/detail/generic_hook.hpp
==============================================================================
--- trunk/boost/intrusive/detail/generic_hook.hpp (original)
+++ trunk/boost/intrusive/detail/generic_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/hashtable_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/hashtable_node.hpp (original)
+++ trunk/boost/intrusive/detail/hashtable_node.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -100,8 +100,12 @@
 class hashtable_iterator
    : public std::iterator
          < std::forward_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits<typename Container::value_type*>::difference_type
          , typename detail::add_const_if_c
- <typename Container::value_type, IsConst>::type
+ <typename Container::value_type, IsConst>::type *
+ , typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type &
>
 {
    typedef typename Container::real_value_traits real_value_traits;
@@ -116,8 +120,11 @@
    { return typename Container::node_ptr(&static_cast<typename Container::node&>(*p)); }
 
    public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type *pointer;
    typedef typename detail::add_const_if_c
- <typename Container::value_type, IsConst>::type value_type;
+ <typename Container::value_type, IsConst>::type &reference;
 
    hashtable_iterator ()
    {}
@@ -133,6 +140,9 @@
    const siterator &slist_it() const
    { return slist_it_; }
 
+ hashtable_iterator<Container, false> unconst() const
+ { return hashtable_iterator<Container, false>(this->slist_it(), this->get_container()); }
+
    public:
    hashtable_iterator& operator++()
    { this->increment(); return *this; }
@@ -150,10 +160,10 @@
    friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
    { return !(i == i2); }
 
- value_type& operator*() const
+ reference operator*() const
    { return *this->operator ->(); }
 
- value_type* operator->() const
+ pointer operator->() const
    { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); }
 
    const Container *get_container() const

Added: trunk/boost/intrusive/detail/is_stateful_value_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/intrusive/detail/is_stateful_value_traits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2009.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
+#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
+
+#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/intrusive/detail/function_detector.hpp>
+
+BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive)
+BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive)
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template<class ValueTraits>
+struct is_stateful_value_traits
+{
+ typedef typename ValueTraits::node_ptr node_ptr;
+ typedef typename ValueTraits::pointer pointer;
+ typedef typename ValueTraits::value_type value_type;
+ typedef typename ValueTraits::const_node_ptr const_node_ptr;
+ typedef typename ValueTraits::const_pointer const_pointer;
+
+ typedef ValueTraits value_traits;
+
+ static const bool value =
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, node_ptr, to_node_ptr, (value_type&) )))
+ ||
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, pointer, to_value_ptr, (node_ptr) )))
+ ||
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_node_ptr, to_node_ptr, (const value_type&) )))
+ ||
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_pointer, to_value_ptr, (const_node_ptr) )))
+ ;
+};
+
+}}}
+
+#include <boost/intrusive/detail/config_end.hpp>
+
+#endif //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP

Modified: trunk/boost/intrusive/detail/list_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/list_node.hpp (original)
+++ trunk/boost/intrusive/detail/list_node.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -63,8 +63,12 @@
 class list_iterator
    : public std::iterator
          < std::bidirectional_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits<typename Container::value_type*>::difference_type
          , typename detail::add_const_if_c
- <typename Container::value_type, IsConst>::type
+ <typename Container::value_type, IsConst>::type *
+ , typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type &
>
 {
    protected:
@@ -78,11 +82,11 @@
       detail::store_cont_ptr_on_it<Container>::value;
 
    public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type *pointer;
    typedef typename detail::add_const_if_c
- <typename Container::value_type, IsConst>
- ::type value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ <typename Container::value_type, IsConst>::type &reference;
 
    list_iterator()
       : members_ (node_ptr(0), 0)
@@ -135,7 +139,7 @@
    bool operator!= (const list_iterator& i) const
    { return !operator== (i); }
 
- value_type& operator*() const
+ reference operator*() const
    { return *operator->(); }
 
    pointer operator->() const

Modified: trunk/boost/intrusive/detail/mpl.hpp
==============================================================================
--- trunk/boost/intrusive/detail/mpl.hpp (original)
+++ trunk/boost/intrusive/detail/mpl.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
 #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
 #define BOOST_INTRUSIVE_DETAIL_MPL_HPP
 
+#include <boost/intrusive/detail/config_begin.hpp>
 #include <cstddef>
 
 namespace boost {
@@ -364,4 +365,6 @@
 } //namespace intrusive
 } //namespace boost
 
+#include <boost/intrusive/detail/config_end.hpp>
+
 #endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP

Modified: trunk/boost/intrusive/detail/parent_from_member.hpp
==============================================================================
--- trunk/boost/intrusive/detail/parent_from_member.hpp (original)
+++ trunk/boost/intrusive/detail/parent_from_member.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/rbtree_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/rbtree_node.hpp (original)
+++ trunk/boost/intrusive/detail/rbtree_node.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/slist_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/slist_node.hpp (original)
+++ trunk/boost/intrusive/detail/slist_node.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -55,8 +55,12 @@
 class slist_iterator
    : public std::iterator
          < std::forward_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits<typename Container::value_type*>::difference_type
          , typename detail::add_const_if_c
- <typename Container::value_type, IsConst>::type
+ <typename Container::value_type, IsConst>::type *
+ , typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type &
>
 {
    protected:
@@ -70,11 +74,11 @@
       detail::store_cont_ptr_on_it<Container>::value;
 
    public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type *pointer;
    typedef typename detail::add_const_if_c
- <typename Container::value_type, IsConst>
- ::type value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ <typename Container::value_type, IsConst>::type &reference;
 
    slist_iterator()
       : members_ (node_ptr(0), 0)
@@ -114,7 +118,7 @@
    bool operator!= (const slist_iterator& i) const
    { return !operator== (i); }
 
- value_type& operator*() const
+ reference operator*() const
    { return *operator->(); }
 
    pointer operator->() const

Modified: trunk/boost/intrusive/detail/transform_iterator.hpp
==============================================================================
--- trunk/boost/intrusive/detail/transform_iterator.hpp (original)
+++ trunk/boost/intrusive/detail/transform_iterator.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/detail/tree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/detail/tree_algorithms.hpp (original)
+++ trunk/boost/intrusive/detail/tree_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -160,7 +160,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    static bool unique(const_node_ptr node)
- { return NodeTraits::get_parent(node) == 0; }
+ { return !NodeTraits::get_parent(node); }
 
    static node_ptr get_header(const_node_ptr node)
    {
@@ -460,7 +460,8 @@
    static node_ptr prev_node(node_ptr p)
    {
       if(is_header(p)){
- return maximum(NodeTraits::get_parent(p));
+ return NodeTraits::get_right(p);
+ //return maximum(NodeTraits::get_parent(p));
       }
       else if(NodeTraits::get_left(p)){
          return maximum(NodeTraits::get_left(p));
@@ -721,21 +722,19 @@
 
    static bool is_header(const_node_ptr p)
    {
- bool is_header = false;
- if(NodeTraits::get_parent(p) == p){
- is_header = true;
- }
- else if(NodeTraits::get_parent(NodeTraits::get_parent(p)) == p){
- if(NodeTraits::get_left(p) != 0){
- if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){
- is_header = true;
- }
- if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){
- is_header = true;
- }
- }
+ node_ptr p_left (NodeTraits::get_left(p));
+ node_ptr p_right(NodeTraits::get_right(p));
+ if(!NodeTraits::get_parent(p) || //Header condition when empty tree
+ (p_left && p_right && //Header always has leftmost and rightmost
+ (p_left == p_right || //Header condition when only node
+ (NodeTraits::get_parent(p_left) != p ||
+ NodeTraits::get_parent(p_right) != p ))
+ //When tree size > 1 headers can't be leftmost's
+ //and rightmost's parent
+ )){
+ return true;
       }
- return is_header;
+ return false;
    }
 
    //! <b>Requires</b>: "header" must be the header node of a tree.
@@ -894,10 +893,32 @@
    //! erased between the "insert_check" and "insert_commit" calls.
    static void insert_unique_commit
       (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
+ { return insert_commit(header, new_value, commit_data); }
+
+ static void insert_commit
+ (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data)
    {
       //Check if commit_data has not been initialized by a insert_unique_check call.
       BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != 0);
- link(header, new_value, commit_data.node, commit_data.link_left);
+ node_ptr parent_node(commit_data.node);
+ if(parent_node == header){
+ NodeTraits::set_parent(header, new_node);
+ NodeTraits::set_right(header, new_node);
+ NodeTraits::set_left(header, new_node);
+ }
+ else if(commit_data.link_left){
+ NodeTraits::set_left(parent_node, new_node);
+ if(parent_node == NodeTraits::get_left(header))
+ NodeTraits::set_left(header, new_node);
+ }
+ else{
+ NodeTraits::set_right(parent_node, new_node);
+ if(parent_node == NodeTraits::get_right(header))
+ NodeTraits::set_right(header, new_node);
+ }
+ NodeTraits::set_parent(new_node, parent_node);
+ NodeTraits::set_right(new_node, node_ptr(0));
+ NodeTraits::set_left(new_node, node_ptr(0));
    }
 
    //! <b>Requires</b>: "header" must be the header node of a tree.
@@ -979,9 +1000,9 @@
    {
       //hint must be bigger than the key
       if(hint == header || comp(key, hint)){
- node_ptr prev = hint;
- //The previous value should be less than the key
- if(prev == NodeTraits::get_left(header) || comp((prev = prev_node(hint)), key)){
+ node_ptr prev(hint);
+ //Previous value should be less than the key
+ if(hint == begin_node(header)|| comp((prev = prev_node(hint)), key)){
             commit_data.link_left = unique(header) || !NodeTraits::get_left(hint);
             commit_data.node = commit_data.link_left ? hint : prev;
             if(pdepth){
@@ -989,14 +1010,9 @@
             }
             return std::pair<node_ptr, bool>(node_ptr(), true);
          }
- else{
- return insert_unique_check(header, key, comp, commit_data, pdepth);
- }
- }
- //The hint was wrong, use hintless insert
- else{
- return insert_unique_check(header, key, comp, commit_data, pdepth);
       }
+ //Hint was wrong, use hintless insertion
+ return insert_unique_check(header, key, comp, commit_data, pdepth);
    }
 
    template<class NodePtrCompare>
@@ -1040,7 +1056,7 @@
    {
       insert_commit_data commit_data;
       insert_equal_check(h, hint, new_node, comp, commit_data, pdepth);
- link(h, new_node, commit_data.node, commit_data.link_left);
+ insert_commit(h, new_node, commit_data);
       return new_node;
    }
 
@@ -1050,7 +1066,7 @@
    {
       insert_commit_data commit_data;
       insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth);
- link(h, new_node, commit_data.node, commit_data.link_left);
+ insert_commit(h, new_node, commit_data);
       return new_node;
    }
 
@@ -1060,10 +1076,72 @@
    {
       insert_commit_data commit_data;
       insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth);
- link(h, new_node, commit_data.node, commit_data.link_left);
+ insert_commit(h, new_node, commit_data);
+ return new_node;
+ }
+
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ insert_before_check(header, pos, commit_data, pdepth);
+ insert_commit(header, new_node, commit_data);
       return new_node;
    }
 
+ static void insert_before_check
+ ( node_ptr header, node_ptr pos
+ , insert_commit_data &commit_data, std::size_t *pdepth = 0)
+ {
+ node_ptr prev(pos);
+ if(pos != NodeTraits::get_left(header))
+ prev = prev_node(pos);
+ bool link_left = unique(header) || !NodeTraits::get_left(pos);
+ commit_data.link_left = link_left;
+ commit_data.node = link_left ? pos : prev;
+ if(pdepth){
+ *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1;
+ }
+ }
+
+ static void push_back
+ (node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ push_back_check(header, commit_data, pdepth);
+ insert_commit(header, new_node, commit_data);
+ }
+
+ static void push_back_check
+ (node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
+ {
+ node_ptr prev(NodeTraits::get_right(header));
+ if(pdepth){
+ *pdepth = prev == header ? 0 : depth(prev) + 1;
+ }
+ commit_data.link_left = false;
+ commit_data.node = prev;
+ }
+
+ static void push_front
+ (node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ push_front_check(header, commit_data, pdepth);
+ insert_commit(header, new_node, commit_data);
+ }
+
+ static void push_front_check
+ (node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
+ {
+ node_ptr pos(NodeTraits::get_left(header));
+ if(pdepth){
+ *pdepth = pos == header ? 0 : depth(pos) + 1;
+ }
+ commit_data.link_left = true;
+ commit_data.node = pos;
+ }
+
    //! <b>Requires</b>: p can't be a header node.
    //!
    //! <b>Effects</b>: Calculates the depth of a node: the depth of a
@@ -1303,32 +1381,10 @@
       replace_own_impl(p, x, header, p_old_parent, p_was_left);
    }
 
- static void link(node_ptr header, node_ptr z, node_ptr par, bool left)
- {
- if(par == header){
- NodeTraits::set_parent(header, z);
- NodeTraits::set_right(header, z);
- NodeTraits::set_left(header, z);
- }
- else if(left){
- NodeTraits::set_left(par, z);
- if(par == NodeTraits::get_left(header))
- NodeTraits::set_left(header, z);
- }
- else{
- NodeTraits::set_right(par, z);
- if(par == NodeTraits::get_right(header))
- NodeTraits::set_right(header, z);
- }
- NodeTraits::set_parent(z, par);
- NodeTraits::set_right(z, node_ptr(0));
- NodeTraits::set_left(z, node_ptr(0));
- }
-
    static void erase(node_ptr header, node_ptr z)
    {
       data_for_rebalance ignored;
- erase(header, z, nop_erase_fixup(), ignored);
+ erase_impl(header, z, ignored);
    }
 
    struct data_for_rebalance
@@ -1609,12 +1665,12 @@
             NodeTraits::set_parent(x, x_parent);
          tree_algorithms::replace_own (z, x, header);
          if(NodeTraits::get_left(header) == z){
- NodeTraits::set_left(header, NodeTraits::get_right(z) == 0 ? // z->get_left() must be null also
+ NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also
                NodeTraits::get_parent(z) : // makes leftmost == header if z == root
                tree_algorithms::minimum (x));
          }
          if(NodeTraits::get_right(header) == z){
- NodeTraits::set_right(header, NodeTraits::get_left(z) == 0 ? // z->get_right() must be null also
+ NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also
                               NodeTraits::get_parent(z) : // makes rightmost == header if z == root
                               tree_algorithms::maximum(x));
          }

Modified: trunk/boost/intrusive/detail/tree_node.hpp
==============================================================================
--- trunk/boost/intrusive/detail/tree_node.hpp (original)
+++ trunk/boost/intrusive/detail/tree_node.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -72,8 +72,12 @@
 class tree_iterator
    : public std::iterator
          < std::bidirectional_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits<typename Container::value_type*>::difference_type
          , typename detail::add_const_if_c
- <typename Container::value_type, IsConst>::type
+ <typename Container::value_type, IsConst>::type *
+ , typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type &
>
 {
    protected:
@@ -88,12 +92,11 @@
       detail::store_cont_ptr_on_it<Container>::value;
 
    public:
- public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ <typename Container::value_type, IsConst>::type *pointer;
    typedef typename detail::add_const_if_c
- <typename Container::value_type, IsConst>
- ::type value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ <typename Container::value_type, IsConst>::type &reference;
 
    tree_iterator()
       : members_ (0, 0)
@@ -146,27 +149,17 @@
    bool operator!= (const tree_iterator& i) const
    { return !operator== (i); }
 
- value_type& operator*() const
+ reference operator*() const
    { return *operator->(); }
 
    pointer operator->() const
    { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
 
    const Container *get_container() const
- {
- if(store_container_ptr)
- return static_cast<const Container*>(members_.get_ptr());
- else
- return 0;
- }
+ { return static_cast<const Container*>(members_.get_ptr()); }
 
    const real_value_traits *get_real_value_traits() const
- {
- if(store_container_ptr)
- return &this->get_container()->get_real_value_traits();
- else
- return 0;
- }
+ { return &this->get_container()->get_real_value_traits(); }
 
    tree_iterator end_iterator_from_it() const
    {

Modified: trunk/boost/intrusive/detail/utilities.hpp
==============================================================================
--- trunk/boost/intrusive/detail/utilities.hpp (original)
+++ trunk/boost/intrusive/detail/utilities.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,7 @@
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/detail/assert.hpp>
+#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
 #include <boost/cstdint.hpp>
 #include <cstddef>
 #include <climits>
@@ -45,8 +46,7 @@
    template<bool Add>
    struct two_or_three {one _[2 + Add];};
    template <class U> static one test(...);
- template <class U> static two_or_three<U::boost_intrusive_tags::is_base_hook>
- test (int);
+ template <class U> static two_or_three<U::boost_intrusive_tags::is_base_hook> test (int);
    static const std::size_t value = sizeof(test<T>(0));
 };
 
@@ -62,8 +62,7 @@
    template<bool Add>
    struct two_or_three {one _[2 + Add];};
    template <class U> static one test(...);
- template <class U> static two_or_three<U::is_any_hook>
- test (int);
+ template <class U> static two_or_three<U::is_any_hook> test (int);
    static const std::size_t value = sizeof(test<T>(0));
 };
 
@@ -80,8 +79,7 @@
    template<bool Add>
    struct two_or_three {one _[2 + Add];};
    template <class U> static one test(...);
- template <class U> static two_or_three<U::external_value_traits>
- test (int);
+ template <class U> static two_or_three<U::external_value_traits> test (int);
    static const std::size_t value = sizeof(test<T>(0));
 };
 
@@ -91,8 +89,7 @@
    template<bool Add>
    struct two_or_three {one _[2 + Add];};
    template <class U> static one test(...);
- template <class U> static two_or_three<U::external_bucket_traits>
- test (int);
+ template <class U> static two_or_three<U::external_bucket_traits> test (int);
    static const std::size_t value = sizeof(test<T>(0));
 };
 
@@ -337,16 +334,6 @@
>::type type;
 };
 
-template <class Container>
-struct store_cont_ptr_on_it
-{
- typedef typename Container::value_traits value_traits;
- static const bool value =
- !detail::is_empty_class<value_traits>::value
- || detail::external_value_traits_is_true<value_traits>::value
- ;
-};
-
 template<class T, bool Add>
 struct add_const_if_c
 {
@@ -357,58 +344,6 @@
>::type type;
 };
 
-template<class Container, bool IsConst>
-struct node_to_value
- : public detail::select_constptr
- < typename boost::pointer_to_other
- <typename Container::pointer, void>::type
- , detail::store_cont_ptr_on_it<Container>::value
- >::type
-{
- static const bool store_container_ptr =
- detail::store_cont_ptr_on_it<Container>::value;
-
- typedef typename Container::real_value_traits real_value_traits;
- typedef typename real_value_traits::value_type value_type;
- typedef typename detail::select_constptr
- < typename boost::pointer_to_other
- <typename Container::pointer, void>::type
- , store_container_ptr >::type Base;
- typedef typename real_value_traits::node_traits::node node;
- typedef typename detail::add_const_if_c
- <value_type, IsConst>::type vtype;
- typedef typename detail::add_const_if_c
- <node, IsConst>::type ntype;
- typedef typename boost::pointer_to_other
- <typename Container::pointer, ntype>::type npointer;
-
- node_to_value(const Container *cont)
- : Base(cont)
- {}
-
- typedef vtype & result_type;
- typedef ntype & first_argument_type;
-
- const Container *get_container() const
- {
- if(store_container_ptr)
- return static_cast<const Container*>(Base::get_ptr());
- else
- return 0;
- }
-
- const real_value_traits *get_real_value_traits() const
- {
- if(store_container_ptr)
- return &this->get_container()->get_real_value_traits();
- else
- return 0;
- }
-
- result_type operator()(first_argument_type arg) const
- { return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
-};
-
 template <link_mode_type LinkMode>
 struct link_dispatch
 {};
@@ -625,6 +560,79 @@
    }
 };
 
+template<class ValueTraits, bool ExternalValueTraits>
+struct store_cont_ptr_on_it_impl
+{
+ static const bool value = is_stateful_value_traits<ValueTraits>::value;
+};
+
+template<class ValueTraits>
+struct store_cont_ptr_on_it_impl<ValueTraits, true>
+{
+ static const bool value = false;
+};
+
+template <class Container>
+struct store_cont_ptr_on_it
+{
+ typedef typename Container::value_traits value_traits;
+ static const bool value = store_cont_ptr_on_it_impl
+ <value_traits, external_value_traits_is_true<value_traits>::value>::value;
+};
+
+template<class Container, bool IsConst>
+struct node_to_value
+ : public detail::select_constptr
+ < typename boost::pointer_to_other
+ <typename Container::pointer, void>::type
+ , detail::store_cont_ptr_on_it<Container>::value
+ >::type
+{
+ static const bool store_container_ptr =
+ detail::store_cont_ptr_on_it<Container>::value;
+
+ typedef typename Container::real_value_traits real_value_traits;
+ typedef typename real_value_traits::value_type value_type;
+ typedef typename detail::select_constptr
+ < typename boost::pointer_to_other
+ <typename Container::pointer, void>::type
+ , store_container_ptr >::type Base;
+ typedef typename real_value_traits::node_traits::node node;
+ typedef typename detail::add_const_if_c
+ <value_type, IsConst>::type vtype;
+ typedef typename detail::add_const_if_c
+ <node, IsConst>::type ntype;
+ typedef typename boost::pointer_to_other
+ <typename Container::pointer, ntype>::type npointer;
+
+ node_to_value(const Container *cont)
+ : Base(cont)
+ {}
+
+ typedef vtype & result_type;
+ typedef ntype & first_argument_type;
+
+ const Container *get_container() const
+ {
+ if(store_container_ptr)
+ return static_cast<const Container*>(Base::get_ptr());
+ else
+ return 0;
+ }
+
+ const real_value_traits *get_real_value_traits() const
+ {
+ if(store_container_ptr)
+ return &this->get_container()->get_real_value_traits();
+ else
+ return 0;
+ }
+
+ result_type operator()(first_argument_type arg) const
+ { return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
+};
+
+
 } //namespace detail
 } //namespace intrusive
 } //namespace boost

Modified: trunk/boost/intrusive/detail/workaround.hpp
==============================================================================
--- trunk/boost/intrusive/detail/workaround.hpp (original)
+++ trunk/boost/intrusive/detail/workaround.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

Modified: trunk/boost/intrusive/hashtable.hpp
==============================================================================
--- trunk/boost/intrusive/hashtable.hpp (original)
+++ trunk/boost/intrusive/hashtable.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -186,8 +186,7 @@
    template<bool Add>
    struct two_or_three {one _[2 + Add];};
    template <class U> static one test(...);
- template <class U> static two_or_three<U::store_hash>
- test (int);
+ template <class U> static two_or_three<U::store_hash> test (int);
    static const std::size_t value = sizeof(test<T>(0));
 };
 
@@ -203,8 +202,7 @@
    template<bool Add>
    struct two_or_three {one _[2 + Add];};
    template <class U> static one test(...);
- template <class U> static two_or_three<U::optimize_multikey>
- test (int);
+ template <class U> static two_or_three<U::optimize_multikey> test (int);
    static const std::size_t value = sizeof(test<T>(0));
 };
 
@@ -603,7 +601,7 @@
 
    typedef typename real_value_traits::pointer pointer;
    typedef typename real_value_traits::const_pointer const_pointer;
- typedef typename std::iterator_traits<pointer>::value_type value_type;
+ typedef typename real_value_traits::value_type value_type;
    typedef typename std::iterator_traits<pointer>::reference reference;
    typedef typename std::iterator_traits<const_pointer>::reference const_reference;
    typedef typename std::iterator_traits<pointer>::difference_type difference_type;
@@ -626,7 +624,7 @@
       <node_ptr, const node>::type const_node_ptr;
    typedef typename slist_impl::node_algorithms node_algorithms;
 
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<hashtable_impl>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
    static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
 
    static const bool unique_keys = 0 != (Config::bool_flags & detail::hash_bool_flags::unique_keys_pos);
@@ -1231,8 +1229,8 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { this->erase_and_dispose(i, detail::null_disposer()); }
+ iterator erase(const_iterator i)
+ { return this->erase_and_dispose(i, detail::null_disposer()); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
    //!
@@ -1243,8 +1241,8 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { this->erase_and_dispose(b, e, detail::null_disposer()); }
+ iterator erase(const_iterator b, const_iterator e)
+ { return this->erase_and_dispose(b, e, detail::null_disposer()); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
    //!
@@ -1297,19 +1295,20 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
+ iterator ret(i.unconst());
+ ++ret;
       priv_erase(i, disposer, optimize_multikey_t());
       this->priv_size_traits().decrement();
       priv_erasure_update_cache();
+ return ret;
    }
 
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
- { return this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
-
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1323,31 +1322,32 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+ iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
    {
- if(b == e) return;
-
- //Get the bucket number and local iterator for both iterators
- siterator first_local_it(b.slist_it());
- size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
-
- siterator before_first_local_it
- = priv_get_previous(priv_buckets()[first_bucket_num], first_local_it);
- size_type last_bucket_num;
- siterator last_local_it;
-
- //For the end iterator, we will assign the end iterator
- //of the last bucket
- if(e == this->end()){
- last_bucket_num = this->bucket_count() - 1;
- last_local_it = priv_buckets()[last_bucket_num].end();
- }
- else{
- last_local_it = e.slist_it();
- last_bucket_num = this->priv_get_bucket_num(last_local_it);
+ if(b != e){
+ //Get the bucket number and local iterator for both iterators
+ siterator first_local_it(b.slist_it());
+ size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
+
+ siterator before_first_local_it
+ = priv_get_previous(priv_buckets()[first_bucket_num], first_local_it);
+ size_type last_bucket_num;
+ siterator last_local_it;
+
+ //For the end iterator, we will assign the end iterator
+ //of the last bucket
+ if(e == this->end()){
+ last_bucket_num = this->bucket_count() - 1;
+ last_local_it = priv_buckets()[last_bucket_num].end();
+ }
+ else{
+ last_local_it = e.slist_it();
+ last_bucket_num = this->priv_get_bucket_num(last_local_it);
+ }
+ priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
+ priv_erasure_update_cache(first_bucket_num, last_bucket_num);
       }
- priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
- priv_erasure_update_cache(first_bucket_num, last_bucket_num);
+ return e.unconst();
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.

Modified: trunk/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- trunk/boost/intrusive/intrusive_fwd.hpp (original)
+++ trunk/boost/intrusive/intrusive_fwd.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/linear_slist_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/linear_slist_algorithms.hpp (original)
+++ trunk/boost/intrusive/linear_slist_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -156,7 +156,7 @@
    //! <b>Effects</b>: Returns the number of nodes in a linear list. If the linear list
    //! is empty, returns 1.
    //!
- //! <b>Complexity</b>: Constant
+ //! <b>Complexity</b>: Linear
    //!
    //! <b>Throws</b>: Nothing.
    static std::size_t count(const_node_ptr this_node)

Modified: trunk/boost/intrusive/link_mode.hpp
==============================================================================
--- trunk/boost/intrusive/link_mode.hpp (original)
+++ trunk/boost/intrusive/link_mode.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/list.hpp
==============================================================================
--- trunk/boost/intrusive/list.hpp (original)
+++ trunk/boost/intrusive/list.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -106,7 +106,8 @@
    typedef circular_list_algorithms<node_traits> node_algorithms;
 
    static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<list_impl>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
+ BOOST_STATIC_ASSERT(( stateful_value_traits == false ));
 
    /// @cond
 

Modified: trunk/boost/intrusive/list_hook.hpp
==============================================================================
--- trunk/boost/intrusive/list_hook.hpp (original)
+++ trunk/boost/intrusive/list_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -93,6 +93,7 @@
       ::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -214,6 +215,7 @@
       ::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: trunk/boost/intrusive/member_value_traits.hpp
==============================================================================
--- trunk/boost/intrusive/member_value_traits.hpp (original)
+++ trunk/boost/intrusive/member_value_traits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/options.hpp
==============================================================================
--- trunk/boost/intrusive/options.hpp (original)
+++ trunk/boost/intrusive/options.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/pointer_plus_bits.hpp
==============================================================================
--- trunk/boost/intrusive/pointer_plus_bits.hpp (original)
+++ trunk/boost/intrusive/pointer_plus_bits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -50,7 +50,7 @@
 struct pointer_plus_bits;
 
 //!This is the specialization to embed extra bits of information
-//!in a raw pointer. The extra bits are stored in the lower bit of the pointer.
+//!in a raw pointer. The extra bits are stored in the lower bits of the pointer.
 template<class T, std::size_t NumBits>
 struct pointer_plus_bits<T*, NumBits>
 {

Modified: trunk/boost/intrusive/priority_compare.hpp
==============================================================================
--- trunk/boost/intrusive/priority_compare.hpp (original)
+++ trunk/boost/intrusive/priority_compare.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -23,7 +23,7 @@
 
 template <class T>
 struct priority_compare
- : public std::binary_function<T, T, bool>
+ : public std::binary_function<T, T, bool>
 {
    bool operator()(const T &val, const T &val2) const
    {

Modified: trunk/boost/intrusive/rbtree.hpp
==============================================================================
--- trunk/boost/intrusive/rbtree.hpp (original)
+++ trunk/boost/intrusive/rbtree.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,7 @@
 #include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/detail/clear_on_destructor_base.hpp>
+#include <boost/intrusive/detail/function_detector.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/rbtree_algorithms.hpp>
 #include <boost/intrusive/link_mode.hpp>
@@ -116,8 +117,7 @@
    typedef rbtree_algorithms<node_traits> node_algorithms;
 
    static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<rbtree_impl>::value;
-
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
    /// @cond
    private:
    typedef detail::size_holder<constant_time_size, size_type> size_traits;
@@ -704,6 +704,76 @@
       return iterator(to_insert, this);
    }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ return iterator(node_algorithms::insert_before
+ (node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
+ }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity for erase element is constant time.

Modified: trunk/boost/intrusive/rbtree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/rbtree_algorithms.hpp (original)
+++ trunk/boost/intrusive/rbtree_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -586,6 +586,66 @@
    }
 
    //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node)
+ {
+ tree_algorithms::insert_before(header, pos, new_node);
+ rebalance_after_insertion(header, new_node);
+ return new_node;
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_back(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_back(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_front(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_front(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
    //! KeyNodePtrCompare is a function object that induces a strict weak
    //! ordering compatible with the strict weak ordering used to create the
    //! the tree. NodePtrCompare compares KeyType with a node_ptr.

Modified: trunk/boost/intrusive/set.hpp
==============================================================================
--- trunk/boost/intrusive/set.hpp (original)
+++ trunk/boost/intrusive/set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -490,6 +490,60 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_unique(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
@@ -1533,6 +1587,57 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_equal(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.

Modified: trunk/boost/intrusive/set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/set_hook.hpp (original)
+++ trunk/boost/intrusive/set_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -98,6 +98,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -224,6 +225,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: trunk/boost/intrusive/sg_set.hpp
==============================================================================
--- trunk/boost/intrusive/sg_set.hpp (original)
+++ trunk/boost/intrusive/sg_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -381,7 +381,7 @@
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
    //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! key_value_comp compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the sg_set, using
    //! a user provided key instead of the value itself.
@@ -416,7 +416,7 @@
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
    //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! key_value_comp compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the sg_set, using
    //! a user provided key instead of the value itself, using "hint"
@@ -489,6 +489,60 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_unique(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
@@ -1572,6 +1626,57 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_equal(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.

Modified: trunk/boost/intrusive/sgtree.hpp
==============================================================================
--- trunk/boost/intrusive/sgtree.hpp (original)
+++ trunk/boost/intrusive/sgtree.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -244,7 +244,7 @@
 
    static const bool floating_point = Config::floating_point;
    static const bool constant_time_size = true;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<sgtree_impl>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
 
    /// @cond
    private:
@@ -871,6 +871,88 @@
       return iterator(to_insert, this);
    }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
+ node_ptr p = node_algorithms::insert_before
+ ( node_ptr(&priv_header()), pos.pointed_node(), to_insert
+ , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
+ data_.max_tree_size_ = (size_type)max_tree_size;
+ return iterator(p, this);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
+ node_algorithms::push_back
+ ( node_ptr(&priv_header()), to_insert
+ , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
+ data_.max_tree_size_ = (size_type)max_tree_size;
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
+ node_algorithms::push_front
+ ( node_ptr(&priv_header()), to_insert
+ , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
+ data_.max_tree_size_ = (size_type)max_tree_size;
+ }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity for erase element is constant time.
@@ -1071,7 +1153,6 @@
    {
       node_algorithms::clear_and_dispose(node_ptr(&priv_header())
          , detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
- node_algorithms::init_header(&priv_header());
       this->priv_size_traits().set_size(0);
    }
 

Modified: trunk/boost/intrusive/sgtree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/sgtree_algorithms.hpp (original)
+++ trunk/boost/intrusive/sgtree_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -539,6 +539,76 @@
       return ret;
    }
 
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ template<class H_Alpha>
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node
+ ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
+ {
+ std::size_t depth;
+ tree_algorithms::insert_before(header, pos, new_node, &depth);
+ rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
+ return new_node;
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template<class H_Alpha>
+ static void push_back(node_ptr header, node_ptr new_node
+ ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
+ {
+ std::size_t depth;
+ tree_algorithms::push_back(header, new_node, &depth);
+ rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template<class H_Alpha>
+ static void push_front(node_ptr header, node_ptr new_node
+ ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
+ {
+ std::size_t depth;
+ tree_algorithms::push_front(header, new_node, &depth);
+ rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
+ }
+
    //! <b>Requires</b>: "header" must be the header node of a tree.
    //! KeyNodePtrCompare is a function object that induces a strict weak
    //! ordering compatible with the strict weak ordering used to create the

Modified: trunk/boost/intrusive/slist.hpp
==============================================================================
--- trunk/boost/intrusive/slist.hpp (original)
+++ trunk/boost/intrusive/slist.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -140,7 +140,7 @@
>::type node_algorithms;
 
    static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<slist_impl>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
    static const bool linear = Config::linear;
    static const bool cache_last = Config::cache_last;
 
@@ -539,6 +539,36 @@
    const_iterator cbefore_begin() const
    { return this->before_begin(); }
 
+ //! <b>Effects</b>: Returns an iterator to the last element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: This function is present only if cached_last<> option is true.
+ iterator last()
+ { return iterator (this->get_last_node(), this); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: This function is present only if cached_last<> option is true.
+ const_iterator last() const
+ { return const_iterator (this->get_last_node(), this); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: This function is present only if cached_last<> option is true.
+ const_iterator clast() const
+ { return const_iterator(this->get_last_node(), this); }
+
    //! <b>Precondition</b>: end_iterator must be a valid end iterator
    //! of slist.
    //!
@@ -1058,20 +1088,31 @@
    //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
    //! the element pointed by prev. No destructors or copy constructors are called.
    //!
- //! <b>Returns</b>: The last element inserted of x or prev if x is empty.
- //! This iterator can be used as new "prev" iterator for a new splice_after call.
- //! that will splice new values after the previously spliced values.
+ //! <b>Returns</b>: Nothing.
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Linear to the elements contained in x.
- //! Constant-time if cache_last<> option is true.
+ //! <b>Complexity</b>: In general, linear to the elements contained in x.
+ //! Constant-time if cache_last<> option is true and also constant-time if
+ //! linear<> option is true "this" is empty and "last" is not used.
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- iterator splice_after(const_iterator prev, slist_impl &x)
+ //!
+ //! <b>Additional note</b>: If the optional parameter "last" is provided, it will be
+ //! assigned to the last spliced element or prev if x is empty.
+ //! This iterator can be used as new "prev" iterator for a new splice_after call.
+ //! that will splice new values after the previously spliced values.
+ void splice_after(const_iterator prev, slist_impl &x, const_iterator *last = 0)
    {
- if (!x.empty()){
+ if(x.empty()){
+ if(last) *last = prev;
+ }
+ else if(linear && this->empty()){
+ this->swap(x);
+ if(last) *last = this->previous(this->cend());
+ }
+ else{
          const_iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active
          node_ptr prev_n(prev.pointed_node());
          node_ptr last_x_n(last_x.pointed_node());
@@ -1084,10 +1125,7 @@
          node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n);
          this->priv_size_traits().set_size(this->priv_size_traits().get_size() + x.priv_size_traits().get_size());
          x.priv_size_traits().set_size(size_type(0));
- return last_x.unconst();
- }
- else{
- return prev.unconst();
+ if(last) *last = last_x;
       }
    }
 
@@ -1166,10 +1204,7 @@
    //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
    //! the element pointed by it. No destructors or copy constructors are called.
    //!
- //! <b>Returns</b>: The last element inserted of x or the previous element
- //! of it if x is empty.
- //! This iterator can be used as new "prev" iterator for a new splice call.
- //! that will splice new values after the previously spliced values.
+ //! <b>Returns</b>: Nothing.
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -1180,8 +1215,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
- iterator splice(const_iterator it, slist_impl &x)
- { return this->splice_after(this->previous(it), x); }
+ //!
+ //! <b>Additional note</b>: If the optional parameter "last" is provided, it will be
+ //! assigned to the last spliced element or prev if x is empty.
+ //! This iterator can be used as new "prev" iterator for a new splice_after call.
+ //! that will splice new values after the previously spliced values.
+ void splice(const_iterator it, slist_impl &x, iterator *last = 0)
+ { this->splice_after(this->previous(it), x, last); }
 
    //! <b>Requires</b>: it p must be a valid iterator of *this.
    //! elem must point to an element contained in list
@@ -1254,7 +1294,7 @@
    void sort(Predicate p)
    {
       if (node_traits::get_next(node_traits::get_next(this->get_root_node()))
- != this->get_root_node()) {
+ != this->get_root_node()) {
          slist_impl carry;
          slist_impl counter[64];
          int fill = 0;
@@ -1265,33 +1305,28 @@
             int i = 0;
             while(i < fill && !counter[i].empty()) {
                carry.swap(counter[i]);
- last_inserted = carry.merge(counter[i++], p);
+ carry.merge(counter[i++], p, &last_inserted);
             }
             BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
+ const_iterator last_element(carry.previous(last_inserted, carry.end()));
 
- node_ptr p = node_algorithms::get_previous_node
- (last_inserted.pointed_node(), carry.cend().pointed_node());
- const_iterator last_element(p, this);
             if(constant_time_size){
                counter[i].splice_after( counter[i].cbefore_begin(), carry
- , carry.cbefore_begin(), last_element
- , carry.size());
+ , carry.cbefore_begin(), last_element
+ , carry.size());
             }
             else{
                counter[i].splice_after( counter[i].cbefore_begin(), carry
- , carry.cbefore_begin(), last_element);
+ , carry.cbefore_begin(), last_element);
             }
             if(i == fill)
                ++fill;
          }
 
          for (int i = 1; i < fill; ++i)
- last_inserted = counter[i].merge(counter[i-1], p);
- BOOST_INTRUSIVE_INVARIANT_ASSERT(this->empty());
-
- node_ptr p = node_algorithms::get_previous_node
- (last_inserted.pointed_node(), counter[--fill].end().pointed_node());
- const_iterator last_element(p, this);
+ counter[i].merge(counter[i-1], p, &last_inserted);
+ --fill;
+ const_iterator last_element(counter[fill].previous(last_inserted, counter[fill].end()));
          if(constant_time_size){
             this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
                               , last_element, counter[fill].size());
@@ -1330,7 +1365,7 @@
    //! in order into *this. The merge is stable; that is, if an element from *this is
    //! equivalent to one from x, then the element from *this will precede the one from x.
    //!
- //! <b>Returns</b>: An iterator to the last transferred value, end() is x is empty.
+ //! <b>Returns</b>: Nothing.
    //!
    //! <b>Throws</b>: If the predicate throws. Basic guarantee.
    //!
@@ -1338,11 +1373,15 @@
    //! size() + x.size() - 1 comparisons.
    //!
    //! <b>Note</b>: Iterators and references are not invalidated.
+ //!
+ //! <b>Additional note</b>: If optional "last" argument is passed, it is assigned
+ //! to an iterator to the last transferred value or end() is x is empty.
    template<class Predicate>
- iterator merge(slist_impl& x, Predicate p)
+ void merge(slist_impl& x, Predicate p, const_iterator *last = 0)
    {
       const_iterator e(this->cend()), ex(x.cend()), bb(this->cbefore_begin()),
- bb_next, last_inserted(e);
+ bb_next;
+ if(last) *last = e.unconst();
       while(!x.empty()){
          const_iterator ibx_next(x.cbefore_begin()), ibx(ibx_next++);
          while (++(bb_next = bb) != e && !p(*ibx_next, *bb_next)){
@@ -1350,7 +1389,7 @@
          }
          if(bb_next == e){
             //Now transfer the rest to the end of the container
- last_inserted = this->splice_after(bb, x);
+ this->splice_after(bb, x, last);
             break;
          }
          else{
@@ -1359,10 +1398,9 @@
                ibx = ibx_next; ++n;
             } while(++(ibx_next = ibx) != ex && p(*ibx_next, *bb_next));
             this->splice_after(bb, x, x.before_begin(), ibx, n);
- last_inserted = ibx;
+ if(last) *last = ibx;
          }
       }
- return last_inserted.unconst();
    }
 
    //! <b>Effects</b>: This function removes all of x's elements and inserts them
@@ -1618,14 +1656,7 @@
    //! <b>Complexity</b>: Linear to the number of elements before i.
    //! Constant if cache_last<> is true and i == end().
    iterator previous(iterator i)
- {
- if(cache_last && (i.pointed_node() == this->get_end_node())){
- return iterator(this->get_last_node(), this);
- }
- return iterator
- (node_algorithms::get_previous_node
- (this->before_begin().pointed_node(), i.pointed_node()), this);
- }
+ { return this->previous(this->cbefore_begin(), i); }
 
    //! <b>Returns</b>: The const_iterator to the element before i in the list.
    //! Returns the end-const_iterator, if either i is the begin-const_iterator or
@@ -1636,13 +1667,86 @@
    //! <b>Complexity</b>: Linear to the number of elements before i.
    //! Constant if cache_last<> is true and i == end().
    const_iterator previous(const_iterator i) const
+ { return this->previous(this->cbefore_begin(), i); }
+
+ //! <b>Returns</b>: The iterator to the element before i in the list,
+ //! starting the search on element after prev_from.
+ //! Returns the end-iterator, if either i is the begin-iterator or the
+ //! list is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ //! Constant if cache_last<> is true and i == end().
+ iterator previous(const_iterator prev_from, iterator i)
+ { return this->previous(prev_from, const_iterator(i)).unconst(); }
+
+ //! <b>Returns</b>: The const_iterator to the element before i in the list,
+ //! starting the search on element after prev_from.
+ //! Returns the end-const_iterator, if either i is the begin-const_iterator or
+ //! the list is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ //! Constant if cache_last<> is true and i == end().
+ const_iterator previous(const_iterator prev_from, const_iterator i) const
    {
       if(cache_last && (i.pointed_node() == this->get_end_node())){
          return const_iterator(uncast(this->get_last_node()), this);
       }
       return const_iterator
          (node_algorithms::get_previous_node
- (this->before_begin().pointed_node(), i.pointed_node()), this);
+ (prev_from.pointed_node(), i.pointed_node()), this);
+ }
+
+ //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
+ //! before_begin(), and before_first and before_last belong to x and
+ //! ++before_first != x.end() && before_last != x.end().
+ //!
+ //! <b>Effects</b>: Transfers the range (before_first, before_last] to this
+ //! list, after the element pointed by prev_pos.
+ //! No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements transferred
+ //! if constant_time_size is true. Constant-time otherwise.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void incorporate_after(const_iterator prev_from, node_ptr first, node_ptr before_last)
+ {
+ if(constant_time_size)
+ this->incorporate_after(prev_from, first, before_last, std::distance(first, before_last)+1);
+ else
+ this->priv_incorporate_after
+ (prev_from.pointed_node(), first, before_last);
+ }
+
+ //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
+ //! before_begin(), and before_first and before_last belong to x and
+ //! ++before_first != x.end() && before_last != x.end() and
+ //! n == std::distance(first, before_last) + 1.
+ //!
+ //! <b>Effects</b>: Transfers the range (before_first, before_last] from list x to this
+ //! list, after the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void incorporate_after(const_iterator prev_pos, node_ptr first, node_ptr before_last, difference_type n)
+ {
+ if(n){
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(iterator(first, this), iterator(before_last, this))+1 == n);
+ this->priv_incorporate_after(prev_pos.pointed_node(), first, before_last);
+ if(constant_time_size){
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n);
+ }
+ }
    }
 
    private:
@@ -1662,6 +1766,16 @@
       }
    }
 
+ void priv_incorporate_after(node_ptr prev_pos_n, node_ptr first_n, node_ptr before_last_n)
+ {
+ if(cache_last){
+ if(node_traits::get_next(prev_pos_n) == this->get_end_node()){
+ this->set_last_node(before_last_n);
+ }
+ }
+ node_algorithms::incorporate_after(prev_pos_n, first_n, before_last_n);
+ }
+
    void priv_reverse(detail::bool_<false>)
    { node_algorithms::reverse(this->get_root_node()); }
 

Modified: trunk/boost/intrusive/slist_hook.hpp
==============================================================================
--- trunk/boost/intrusive/slist_hook.hpp (original)
+++ trunk/boost/intrusive/slist_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -218,6 +219,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: trunk/boost/intrusive/splay_set.hpp
==============================================================================
--- trunk/boost/intrusive/splay_set.hpp (original)
+++ trunk/boost/intrusive/splay_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -624,7 +624,7 @@
                   /// @cond
                   , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
                   /// @endcond
-)
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.

Modified: trunk/boost/intrusive/splay_set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/splay_set_hook.hpp (original)
+++ trunk/boost/intrusive/splay_set_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -93,6 +93,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -216,6 +217,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: trunk/boost/intrusive/splaytree.hpp
==============================================================================
--- trunk/boost/intrusive/splaytree.hpp (original)
+++ trunk/boost/intrusive/splaytree.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -115,7 +115,7 @@
    typedef splaytree_algorithms<node_traits> node_algorithms;
 
    static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<splaytree_impl>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
 
    /// @cond
    private:
@@ -895,7 +895,6 @@
    {
       node_algorithms::clear_and_dispose(node_ptr(&priv_header())
          , detail::node_disposer<Disposer, splaytree_impl>(disposer, this));
- node_algorithms::init_header(&priv_header());
       this->priv_size_traits().set_size(0);
    }
 

Modified: trunk/boost/intrusive/splaytree_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/splaytree_algorithms.hpp (original)
+++ trunk/boost/intrusive/splaytree_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -543,6 +543,79 @@
       return tree_algorithms::insert_equal(header, hint, new_node, comp);
    }
 
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node)
+ {
+ tree_algorithms::insert_before(header, pos, new_node);
+ splay_up(new_node, header);
+ return new_node;
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_back(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_back(header, new_node);
+ splay_up(new_node, header);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_front(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_front(header, new_node);
+ splay_up(new_node, header);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! NodePtrCompare is a function object that induces a strict weak
+ //! ordering compatible with the strict weak ordering used to create the
+ //! the tree. NodePtrCompare compares two node_ptrs.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
+ //! according to "comp".
+ //!
+ //! <b>Complexity</b>: Average complexity for insert element is at
+ //! most logarithmic.
+ //!
+ //! <b>Throws</b>: If "comp" throws.
    template<class NodePtrCompare>
    static node_ptr insert_equal_upper_bound
       (node_ptr header, node_ptr new_node, NodePtrCompare comp)
@@ -551,6 +624,18 @@
       return tree_algorithms::insert_equal_upper_bound(header, new_node, comp);
    }
 
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! NodePtrCompare is a function object that induces a strict weak
+ //! ordering compatible with the strict weak ordering used to create the
+ //! the tree. NodePtrCompare compares two node_ptrs.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before the lower bound
+ //! according to "comp".
+ //!
+ //! <b>Complexity</b>: Average complexity for insert element is at
+ //! most logarithmic.
+ //!
+ //! <b>Throws</b>: If "comp" throws.
    template<class NodePtrCompare>
    static node_ptr insert_equal_lower_bound
       (node_ptr header, node_ptr new_node, NodePtrCompare comp)
@@ -605,9 +690,8 @@
 // if( data_->parent == t )
 // data_->parent = find_leftmost();
          //posibility 1
- if(splay && NodeTraits::get_left(z) != 0 ){
- node_ptr l = prev_node(z);
- splay_up(l, header);
+ if(splay && NodeTraits::get_left(z)){
+ splay_up(prev_node(z), header);
       }
       /*
       //possibility 2
@@ -644,8 +728,8 @@
       if( n == t ) return;
       
       for( ;; ){
- node_ptr p = NodeTraits::get_parent(n);
- node_ptr g = NodeTraits::get_parent(p);
+ node_ptr p(NodeTraits::get_parent(n));
+ node_ptr g(NodeTraits::get_parent(p));
 
          if( p == t ) break;
          
@@ -688,9 +772,8 @@
       if(!NodeTraits::get_left(t) && !NodeTraits::get_right(t))
          return t;
       //Backup leftmost/rightmost
- node_ptr leftmost = NodeTraits::get_left(header);
- node_ptr rightmost = NodeTraits::get_right(header);
-
+ node_ptr leftmost (NodeTraits::get_left(header));
+ node_ptr rightmost(NodeTraits::get_right(header));
       {
          detail::splaydown_rollback<NodeTraits> rollback(&t, header, leftmost, rightmost);
          node_ptr null = header;

Modified: trunk/boost/intrusive/treap.hpp
==============================================================================
--- trunk/boost/intrusive/treap.hpp (original)
+++ trunk/boost/intrusive/treap.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -119,7 +119,7 @@
    typedef treap_algorithms<node_traits> node_algorithms;
 
    static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it<treap_impl>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
 
    /// @cond
    private:
@@ -217,7 +217,7 @@
 
    typedef typename node_algorithms::insert_commit_data insert_commit_data;
 
- //! <b>Effects</b>: Constructs an empty tree.
+ //! <b>Effects</b>: Constructs an empty treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -236,7 +236,7 @@
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
    //! cmp must be a comparison function that induces a strict weak ordering.
    //!
- //! <b>Effects</b>: Constructs an empty tree and inserts elements from
+ //! <b>Effects</b>: Constructs an empty treap and inserts elements from
    //! [b, e).
    //!
    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
@@ -272,7 +272,7 @@
    ~treap_impl()
    {}
 
- //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
+ //! <b>Effects</b>: Returns an iterator pointing to the beginning of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -280,7 +280,7 @@
    iterator begin()
    { return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
 
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
+ //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -288,7 +288,7 @@
    const_iterator begin() const
    { return this->cbegin(); }
 
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
+ //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -296,7 +296,7 @@
    const_iterator cbegin() const
    { return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
 
- //! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
+ //! <b>Effects</b>: Returns an iterator pointing to the end of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -304,7 +304,7 @@
    iterator end()
    { return iterator (node_ptr(&priv_header()), this); }
 
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
+ //! <b>Effects</b>: Returns a const_iterator pointing to the end of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -312,7 +312,7 @@
    const_iterator end() const
    { return this->cend(); }
 
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
+ //! <b>Effects</b>: Returns a const_iterator pointing to the end of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -321,7 +321,7 @@
    { return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
 
 
- //! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the tree.
+ //! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -329,7 +329,7 @@
    iterator top()
    { return this->empty() ? this->end() : iterator (node_traits::get_parent(node_ptr(&priv_header())), this); }
 
- //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the tree..
+ //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -337,7 +337,7 @@
    const_iterator top() const
    { return this->ctop(); }
 
- //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the tree..
+ //! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -346,7 +346,7 @@
    { return this->empty() ? this->cend() : const_iterator (node_traits::get_parent(const_node_ptr(&priv_header())), this); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
- //! reversed tree.
+ //! reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -355,7 +355,7 @@
    { return reverse_iterator(this->end()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -364,7 +364,7 @@
    { return const_reverse_iterator(this->end()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -373,7 +373,7 @@
    { return const_reverse_iterator(this->end()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -382,7 +382,7 @@
    { return reverse_iterator(this->begin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -391,7 +391,7 @@
    { return const_reverse_iterator(this->begin()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -400,7 +400,7 @@
    { return const_reverse_iterator(this->begin()); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the highest priority object of the
- //! reversed tree.
+ //! reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -409,7 +409,7 @@
    { return reverse_iterator(this->top()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority objec
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -418,7 +418,7 @@
    { return const_reverse_iterator(this->top()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the highest priority object
- //! of the reversed tree.
+ //! of the reversed treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -451,7 +451,7 @@
    //! <b>Precondition</b>: it must be a valid iterator
    //! of treap.
    //!
- //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //! <b>Effects</b>: Returns a const reference to the treap associated to the iterator
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -462,7 +462,7 @@
    //! <b>Precondition</b>: it must be a valid end const_iterator
    //! of treap.
    //!
- //! <b>Effects</b>: Returns a const reference to the tree associated to the end iterator
+ //! <b>Effects</b>: Returns a const reference to the treap associated to the end iterator
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -470,7 +470,7 @@
    static const treap_impl &container_from_iterator(const_iterator it)
    { return priv_container_from_iterator(it); }
 
- //! <b>Effects</b>: Returns the value_compare object used by the tree.
+ //! <b>Effects</b>: Returns the value_compare object used by the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -478,7 +478,7 @@
    value_compare value_comp() const
    { return this->priv_comp(); }
 
- //! <b>Effects</b>: Returns the priority_compare object used by the tree.
+ //! <b>Effects</b>: Returns the priority_compare object used by the treap.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -494,7 +494,7 @@
    bool empty() const
    { return node_algorithms::unique(const_node_ptr(&priv_header())); }
 
- //! <b>Effects</b>: Returns the number of elements stored in the tree.
+ //! <b>Effects</b>: Returns the number of elements stored in the treap.
    //!
    //! <b>Complexity</b>: Linear to elements contained in *this
    //! if constant-time size option is disabled. Constant time otherwise.
@@ -531,12 +531,12 @@
 
    //! <b>Requires</b>: value must be an lvalue
    //!
- //! <b>Effects</b>: Inserts value into the tree before the upper bound.
+ //! <b>Effects</b>: Inserts value into the treap before the upper bound.
    //!
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -557,14 +557,14 @@
    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
    //! a valid iterator.
    //!
- //! <b>Effects</b>: Inserts x into the tree, using "hint" as a hint to
+ //! <b>Effects</b>: Inserts x into the treap, using "hint" as a hint to
    //! where it will be inserted. If "hint" is the upper_bound
    //! the insertion takes constant time (two comparisons in the worst case)
    //!
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -585,14 +585,14 @@
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
    //! of type value_type.
    //!
- //! <b>Effects</b>: Inserts a each element of a range into the tree
+ //! <b>Effects</b>: Inserts a each element of a range into the treap
    //! before the upper bound of the key of each element.
    //!
    //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
    //! size of the range. However, it is linear in N if the range is already sorted
    //! by value_comp().
    //!
- //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
    //! Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -607,13 +607,13 @@
 
    //! <b>Requires</b>: value must be an lvalue
    //!
- //! <b>Effects</b>: Inserts value into the tree if the value
+ //! <b>Effects</b>: Inserts value into the treap if the value
    //! is not already present.
    //!
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
    //! Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -630,14 +630,14 @@
    //! <b>Requires</b>: value must be an lvalue, and "hint" must be
    //! a valid iterator
    //!
- //! <b>Effects</b>: Tries to insert x into the tree, using "hint" as a hint
+ //! <b>Effects</b>: Tries to insert x into the treap, using "hint" as a hint
    //! to where it will be inserted.
    //!
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //! constant time (two comparisons in the worst case)
    //! if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
    //! Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -654,13 +654,13 @@
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
    //! of type value_type.
    //!
- //! <b>Effects</b>: Tries to insert each element of a range into the tree.
+ //! <b>Effects</b>: Tries to insert each element of a range into the treap.
    //!
    //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
    //! size of the range. However, it is linear in N if the range is already sorted
    //! by value_comp().
    //!
- //! <b>Throws</b>: If the internal value_compare or priority_compare funcstions throw.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
    //! Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -680,8 +680,10 @@
    }
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
    //! a user provided key instead of the value itself.
@@ -694,7 +696,8 @@
    //!
    //! <b>Complexity</b>: Average complexity is at most logarithmic.
    //!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the key_value_comp or key_value_pcomp
+ //! ordering functions throw. Strong guarantee.
    //!
    //! <b>Notes</b>: This function is used to improve performance when constructing
    //! a value_type is expensive: if there is an equivalent value
@@ -725,8 +728,10 @@
    }
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the container, using
    //! a user provided key instead of the value itself, using "hint"
@@ -741,7 +746,8 @@
    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the key_value_comp or key_value_pcomp
+ //! ordering functions throw. Strong guarantee.
    //!
    //! <b>Notes</b>: This function is used to improve performance when constructing
    //! a value_type is expensive: if there is an equivalent value
@@ -800,6 +806,82 @@
       return iterator(to_insert, this);
    }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the treap before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" treap ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ detail::key_nodeptr_comp<priority_compare, treap_impl>
+ pcomp(priv_pcomp(), this);
+ return iterator(node_algorithms::insert_before
+ (node_ptr(&priv_header()), pos.pointed_node(), to_insert, pcomp), this);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the treap in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ detail::key_nodeptr_comp<priority_compare, treap_impl>
+ pcomp(priv_pcomp(), this);
+ node_algorithms::push_back(node_ptr(&priv_header()), to_insert, pcomp);
+ }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the treap in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ detail::key_nodeptr_comp<priority_compare, treap_impl>
+ pcomp(priv_pcomp(), this);
+ node_algorithms::push_front(node_ptr(&priv_header()), to_insert, pcomp);
+ }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity for erase element is constant time.
@@ -817,7 +899,7 @@
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
       detail::key_nodeptr_comp<priority_compare, treap_impl>
          key_node_pcomp(priv_pcomp(), this);
- node_algorithms::erase(&priv_header(), to_erase,key_node_pcomp);
+ node_algorithms::erase(&priv_header(), to_erase, key_node_pcomp);
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
@@ -856,7 +938,8 @@
    //!
    //! <b>Complexity</b>: O(log(size() + N).
    //!
- //! <b>Throws</b>: if the internal priority_compare function throws. Strong guarantee.
+ //! <b>Throws</b>: if the internal priority_compare function throws.
+ //! Equivalent guarantee to <i>while(beg != end) erase(beg++);</i>
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -1260,16 +1343,16 @@
       }
    }
 
- //! <b>Effects</b>: Unlinks the leftmost node from the tree.
+ //! <b>Effects</b>: Unlinks the leftmost node from the treap.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Notes</b>: This function breaks the tree and the tree can
+ //! <b>Notes</b>: This function breaks the treap and the treap can
    //! only be used for more unlink_leftmost_without_rebalance calls.
    //! This function is normally used to achieve a step by step
- //! controlled destruction of the tree.
+ //! controlled destruction of the treap.
    pointer unlink_leftmost_without_rebalance()
    {
       node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
@@ -1283,10 +1366,10 @@
    }
 
    //! <b>Requires</b>: replace_this must be a valid iterator of *this
- //! and with_this must not be inserted in any tree.
+ //! and with_this must not be inserted in any treap.
    //!
    //! <b>Effects</b>: Replaces replace_this in its position in the
- //! tree with with_this. The tree does not need to be rebalanced.
+ //! treap with with_this. The treap does not need to be rebalanced.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1363,7 +1446,7 @@
    const_iterator iterator_to(const_reference value) const
    { return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this); }
 
- //! <b>Requires</b>: value shall not be in a tree.
+ //! <b>Requires</b>: value shall not be in a treap.
    //!
    //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
    //! state.

Modified: trunk/boost/intrusive/treap_algorithms.hpp
==============================================================================
--- trunk/boost/intrusive/treap_algorithms.hpp (original)
+++ trunk/boost/intrusive/treap_algorithms.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,8 +10,8 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
-#define BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
+#ifndef BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
+#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
 
 #include <boost/intrusive/detail/config_begin.hpp>
 
@@ -270,15 +270,15 @@
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
    //!
- //! <b>Throws</b>: Nothing.
- template<class NodePriorityCompare>
- static void unlink(node_ptr node, NodePriorityCompare prio)
+ //! <b>Throws</b>: If "pcomp" throws, strong guarantee
+ template<class NodePtrPriorityCompare>
+ static void unlink(node_ptr node, NodePtrPriorityCompare pcomp)
    {
       node_ptr x = NodeTraits::get_parent(node);
       if(x){
          while(!is_header(x))
             x = NodeTraits::get_parent(x);
- erase(x, node, prio);
+ erase(x, node, pcomp);
       }
    }
 
@@ -383,9 +383,9 @@
    //!
    //! <b>Complexity</b>: Amortized constant time.
    //!
- //! <b>Throws</b>: Nothing.
- template<class NodePriorityCompare>
- static node_ptr erase(node_ptr header, node_ptr z, NodePriorityCompare pcomp)
+ //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
+ template<class NodePtrPriorityCompare>
+ static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
    {
       rebalance_for_erasure(header, z, pcomp);
       tree_algorithms::erase(header, z);
@@ -503,23 +503,24 @@
    //! NodePtrCompare is a function object that induces a strict weak
    //! ordering compatible with the strict weak ordering used to create the
    //! the tree. NodePtrCompare compares two node_ptrs.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
    //!
    //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
- //! according to "comp".
+ //! according to "comp" and rotates the tree according to "pcomp".
    //!
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: If "comp" throws.
- template<class NodePtrCompare, class PriorityNodeCompare>
+ //! <b>Throws</b>: If "comp" throw or "pcomp" throw.
+ template<class NodePtrCompare, class NodePtrPriorityCompare>
    static node_ptr insert_equal_upper_bound
- (node_ptr h, node_ptr new_node, NodePtrCompare comp, PriorityNodeCompare pcomp)
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
    {
       insert_commit_data commit_data;
       tree_algorithms::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
- rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
- tree_algorithms::insert_unique_commit(h, new_node, commit_data);
- rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ rebalance_check_and_commit(h, new_node, pcomp, commit_data);
       return new_node;
    }
 
@@ -527,23 +528,24 @@
    //! NodePtrCompare is a function object that induces a strict weak
    //! ordering compatible with the strict weak ordering used to create the
    //! the tree. NodePtrCompare compares two node_ptrs.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
    //!
- //! <b>Effects</b>: Inserts new_node into the tree before the lower bound
- //! according to "comp".
+ //! <b>Effects</b>: Inserts new_node into the tree before the upper bound
+ //! according to "comp" and rotates the tree according to "pcomp".
    //!
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
    //! <b>Throws</b>: If "comp" throws.
- template<class NodePtrCompare, class NodePriorityCompare>
+ template<class NodePtrCompare, class NodePtrPriorityCompare>
    static node_ptr insert_equal_lower_bound
- (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePriorityCompare pcomp)
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
    {
       insert_commit_data commit_data;
       tree_algorithms::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
- rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
- tree_algorithms::insert_unique_commit(h, new_node, commit_data);
- rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ rebalance_check_and_commit(h, new_node, pcomp, commit_data);
       return new_node;
    }
 
@@ -552,28 +554,108 @@
    //! ordering compatible with the strict weak ordering used to create the
    //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
    //! the "header"'s tree.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
    //!
    //! <b>Effects</b>: Inserts new_node into the tree, using "hint" as a hint to
    //! where it will be inserted. If "hint" is the upper_bound
    //! the insertion takes constant time (two comparisons in the worst case).
+ //! Rotates the tree according to "pcomp".
    //!
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //! constant time if new_node is inserted immediately before "hint".
    //!
- //! <b>Throws</b>: If "comp" throws.
- template<class NodePtrCompare, class NodePriorityCompare>
+ //! <b>Throws</b>: If "comp" throw or "pcomp" throw.
+ template<class NodePtrCompare, class NodePtrPriorityCompare>
    static node_ptr insert_equal
- (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePriorityCompare pcomp)
+ (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
    {
       insert_commit_data commit_data;
       tree_algorithms::insert_equal_check(h, hint, new_node, comp, commit_data);
- rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
- tree_algorithms::insert_unique_commit(h, new_node, commit_data);
- rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ rebalance_check_and_commit(h, new_node, pcomp, commit_data);
+ return new_node;
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "pos" must be a valid node of the tree (including header end) node.
+ //! "pos" must be a node pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
+ //!
+ //! <b>Effects</b>: Inserts new_node into the tree before "pos"
+ //! and rotates the tree according to "pcomp".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
+ //!
+ //! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ template<class NodePtrPriorityCompare>
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node, NodePtrPriorityCompare pcomp)
+ {
+ insert_commit_data commit_data;
+ tree_algorithms::insert_before_check(header, pos, commit_data);
+ rebalance_check_and_commit(header, new_node, pcomp, commit_data);
       return new_node;
    }
 
    //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the last position
+ //! and rotates the tree according to "pcomp".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
+ //!
+ //! <b>Note</b>: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template<class NodePtrPriorityCompare>
+ static void push_back(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
+ {
+ insert_commit_data commit_data;
+ tree_algorithms::push_back_check(header, commit_data);
+ rebalance_check_and_commit(header, new_node, pcomp, commit_data);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
+ //!
+ //! <b>Effects</b>: Inserts x into the tree in the first position
+ //! and rotates the tree according to "pcomp".
+ //!
+ //! <b>Complexity</b>: Constant-time.
+ //!
+ //! <b>Throws</b>: If "pcomp" throws, strong guarantee.
+ //!
+ //! <b>Note</b>: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template<class NodePtrPriorityCompare>
+ static void push_front(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
+ {
+ insert_commit_data commit_data;
+ tree_algorithms::push_front_check(header, commit_data);
+ rebalance_check_and_commit(header, new_node, pcomp, commit_data);
+ }
+
+ //! <b>Requires</b>: "header" must be the header node of a tree.
    //! KeyNodePtrCompare is a function object that induces a strict weak
    //! ordering compatible with the strict weak ordering used to create the
    //! the tree. NodePtrCompare compares KeyType with a node_ptr.
@@ -720,8 +802,8 @@
       return tree_algorithms::is_header(p);
    }
 
- template<class NodePriorityCompare>
- static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePriorityCompare pcomp)
+ template<class NodePtrPriorityCompare>
+ static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
    {
       std::size_t n = 0;
       rerotate_on_destroy rb(header, z, n);
@@ -742,6 +824,17 @@
       rb.release();
    }
 
+ template<class NodePtrPriorityCompare>
+ static void rebalance_check_and_commit
+ (node_ptr h, node_ptr new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
+ {
+ rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
+ //No-throw
+ tree_algorithms::insert_unique_commit(h, new_node, commit_data);
+ rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ }
+
+
    template<class Key, class KeyNodePriorityCompare>
    static void rebalance_after_insertion_check
       ( const_node_ptr header, const_node_ptr upnode, const Key &k
@@ -759,7 +852,7 @@
 
    static void rebalance_after_insertion_commit(node_ptr header, node_ptr p, std::size_t n)
    {
- // Now to n rotations
+ // Now execute n rotations
       for( node_ptr p_parent = NodeTraits::get_parent(p)
          ; n--
          ; p_parent = NodeTraits::get_parent(p)){
@@ -773,8 +866,8 @@
       }
    }
 
- template<class NodePriorityCompare>
- static bool check_invariant(const_node_ptr header, NodePriorityCompare pcomp)
+ template<class NodePtrPriorityCompare>
+ static bool check_invariant(const_node_ptr header, NodePtrPriorityCompare pcomp)
    {
       node_ptr beg = begin_node(header);
       node_ptr end = end_node(header);
@@ -798,4 +891,4 @@
 
 #include <boost/intrusive/detail/config_end.hpp>
 
-#endif //BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
+#endif //BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP

Modified: trunk/boost/intrusive/treap_set.hpp
==============================================================================
--- trunk/boost/intrusive/treap_set.hpp (original)
+++ trunk/boost/intrusive/treap_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -351,6 +351,14 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
+ //! <b>Effects</b>: Returns the priority_compare object used by the treap_set.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Throws</b>: If priority_compare copy-constructor throws.
+ priority_compare priority_comp() const
+ { return tree_.priority_comp(); }
+
    //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
@@ -408,7 +416,8 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare ordering function throw.
+ //! Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -426,7 +435,8 @@
    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare ordering
+ //! functions throw. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -434,8 +444,10 @@
    { return tree_.insert_unique(hint, value); }
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the treap_set, using
    //! a user provided key instead of the value itself.
@@ -448,7 +460,8 @@
    //!
    //! <b>Complexity</b>: Average complexity is at most logarithmic.
    //!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If key_value_comp or key_value_pcomp ordering function throw.
+ //! Strong guarantee.
    //!
    //! <b>Notes</b>: This function is used to improve performance when constructing
    //! a value_type is expensive: if there is an equivalent value
@@ -463,14 +476,17 @@
    //!
    //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
    //! objects are inserted or erased from the treap_set.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyValueCompare, class KeyValuePriorityCompare>
    std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_.insert_unique_check(key, key_value_comp, commit_data); }
+ ( const KeyType &key, KeyValueCompare key_value_comp, KeyValuePriorityCompare key_value_pcomp
+ , insert_commit_data &commit_data)
+ { return tree_.insert_unique_check(key, key_value_comp, key_value_pcomp, commit_data); }
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the treap_set, using
    //! a user provided key instead of the value itself, using "hint"
@@ -485,7 +501,8 @@
    //! <b>Complexity</b>: Logarithmic in general, but it's amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If key_value_comp or key_value_pcomp ordering function throw.
+ //! Strong guarantee.
    //!
    //! <b>Notes</b>: This function is used to improve performance when constructing
    //! a value_type is expensive: if there is an equivalent value
@@ -500,11 +517,12 @@
    //!
    //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
    //! objects are inserted or erased from the treap_set.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyValueCompare, class KeyValuePriorityCompare>
    std::pair<iterator, bool> insert_check
- (const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ( const_iterator hint, const KeyType &key
+ , KeyValueCompare key_value_comp, KeyValuePriorityCompare key_value_pcomp
+ , insert_commit_data &commit_data)
+ { return tree_.insert_unique_check(hint, key, key_value_comp, key_value_pcomp, commit_data); }
 
    //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
    //! must have been obtained from a previous call to "insert_check".
@@ -535,7 +553,8 @@
    //! size of the range. However, it is linear in N if the range is already sorted
    //! by value_comp().
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare ordering function
+ //! throw. Basic guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -543,13 +562,65 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_unique(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the treap before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" treap ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the treap in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! <b>Effects</b>: Inserts x into the treap in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased element.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -563,7 +634,7 @@
    //!
    //! <b>Returns</b>: An iterator to the element after the erased elements.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -576,7 +647,8 @@
    //!
    //! <b>Complexity</b>: O(log(size()) + this->count(value)).
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If internal value_compare or priority_compare
+ //! ordering functions throw. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -590,7 +662,8 @@
    //!
    //! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
    //!
- //! <b>Throws</b>: If the comp ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If comp or internal priority_compare
+ //! ordering functions throw. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -611,7 +684,7 @@
    //!
    //! <b>Returns</b>: An iterator to the element after the erased element.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
@@ -635,7 +708,7 @@
    //!
    //! <b>Returns</b>: An iterator to the element after the erased elements.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
@@ -652,7 +725,7 @@
    //!
    //! <b>Complexity</b>: O(log(size() + this->count(value)). Basic guarantee.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -670,7 +743,8 @@
    //!
    //! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
    //!
- //! <b>Throws</b>: If comp ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If comp or internal priority_compare ordering functions throw.
+ //! Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
@@ -1584,6 +1658,14 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
+ //! <b>Effects</b>: Returns the priority_compare object used by the treap_multiset.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Throws</b>: If priority_compare copy-constructor throws.
+ priority_compare priority_comp() const
+ { return tree_.priority_comp(); }
+
    //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1638,7 +1720,8 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare ordering
+ //! function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -1656,7 +1739,8 @@
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If internal value_compare or priority_compare ordering functions throw.
+ //! Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -1675,7 +1759,8 @@
    //! size of the range. However, it is linear in N if the range is already sorted
    //! by value_comp().
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If internal value_compare or priority_compare ordering functions throw.
+ //! Basic guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -1683,13 +1768,64 @@
    void insert(Iterator b, Iterator e)
    { tree_.insert_equal(b, e); }
 
+ //! <b>Requires</b>: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! <b>Effects</b>: Inserts x into the treap before "pos".
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" treap ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key.
+ //!
+ //! <b>Effects</b>: Inserts x into the treap in the last position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! less than the greatest inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! <b>Requires</b>: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! <b>Effects</b>: Inserts x into the treap in the first position.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
    //! <b>Effects</b>: Erases the element pointed to by pos.
    //!
    //! <b>Complexity</b>: Average complexity is constant time.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased element.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -1703,7 +1839,7 @@
    //! <b>Complexity</b>: Average complexity for erase range is at most
    //! O(log(size() + N)), where N is the number of elements in the range.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -1716,7 +1852,8 @@
    //!
    //! <b>Complexity</b>: O(log(size() + this->count(value)).
    //!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If the internal value_compare or priority_compare ordering
+ //! functiona throw. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -1730,7 +1867,7 @@
    //!
    //! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
    //!
- //! <b>Throws</b>: If comp ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If comp or internal priority_compare ordering functions throw. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
@@ -1751,7 +1888,7 @@
    //!
    //! <b>Complexity</b>: Average complexity for erase element is constant time.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
@@ -1775,7 +1912,7 @@
    //! <b>Complexity</b>: Average complexity for erase range is at most
    //! O(log(size() + N)), where N is the number of elements in the range.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal priority_compare function throws. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
@@ -1810,7 +1947,7 @@
    //!
    //! <b>Complexity</b>: O(log(size() + this->count(key, comp)).
    //!
- //! <b>Throws</b>: If comp ordering function throws. Basic guarantee.
+ //! <b>Throws</b>: If comp or internal priority_compare ordering functions throw. Basic guarantee.
    //!
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.

Modified: trunk/boost/intrusive/trivial_value_traits.hpp
==============================================================================
--- trunk/boost/intrusive/trivial_value_traits.hpp (original)
+++ trunk/boost/intrusive/trivial_value_traits.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: trunk/boost/intrusive/unordered_set.hpp
==============================================================================
--- trunk/boost/intrusive/unordered_set.hpp (original)
+++ trunk/boost/intrusive/unordered_set.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -395,8 +395,8 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_.erase(i); }
+ iterator erase(const_iterator i)
+ { return table_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
    //!
@@ -407,8 +407,8 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_.erase(b, e); }
+ iterator erase(const_iterator b, const_iterator e)
+ { return table_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
    //!
@@ -460,15 +460,13 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(const_iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return table_.erase_and_dispose(i, disposer); }
 
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
- { return this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
-
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1370,9 +1368,8 @@
    //!
    //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
    //!
- //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
- //! size of the range. However, it is linear in N if the range is already sorted
- //! by value_comp().
+ //! <b>Complexity</b>: Average case is O(N), where N is the
+ //! size of the range.
    //!
    //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
    //!
@@ -1390,8 +1387,8 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_.erase(i); }
+ iterator erase(const_iterator i)
+ { return table_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
    //!
@@ -1402,8 +1399,8 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_.erase(b, e); }
+ iterator erase(const_iterator b, const_iterator e)
+ { return table_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
    //!
@@ -1456,12 +1453,16 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer)
- { table_.erase_and_dispose(i, disposer); }
+ iterator erase_and_dispose(const_iterator i, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
+ { return table_.erase_and_dispose(i, disposer); }
 
    #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return this->erase_and_dispose(const_iterator(i), disposer); }
    #endif
 
@@ -1478,8 +1479,8 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
- { table_.erase_and_dispose(b, e, disposer); }
+ iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+ { return table_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!

Modified: trunk/boost/intrusive/unordered_set_hook.hpp
==============================================================================
--- trunk/boost/intrusive/unordered_set_hook.hpp (original)
+++ trunk/boost/intrusive/unordered_set_hook.hpp 2009-10-14 07:59:32 EDT (Wed, 14 Oct 2009)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -222,6 +222,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -351,6 +352,7 @@
>::type
 {
    #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!


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