Boost logo

Boost-Commit :

From: igaztanaga_at_[hidden]
Date: 2008-01-27 17:22:36


Author: igaztanaga
Date: 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
New Revision: 42994
URL: http://svn.boost.org/trac/boost/changeset/42994

Log:
Merged Interprocess + Intrusive revision 42982 from trunk to release branch
Added:
   branches/release/boost/interprocess/allocators/detail/allocator_common.hpp
      - copied unchanged from r42982, /trunk/boost/interprocess/allocators/detail/allocator_common.hpp
   branches/release/boost/intrusive/detail/common_slist_algorithms.hpp
      - copied unchanged from r42982, /trunk/boost/intrusive/detail/common_slist_algorithms.hpp
   branches/release/boost/intrusive/linear_slist_algorithms.hpp
      - copied unchanged from r42982, /trunk/boost/intrusive/linear_slist_algorithms.hpp
   branches/release/libs/interprocess/test/vector_test.hpp
      - copied unchanged from r42982, /trunk/libs/interprocess/test/vector_test.hpp
Removed:
   branches/release/libs/interprocess/proj/to-do.txt
   branches/release/libs/intrusive/proj/vc7ide/to-do.txt
   branches/release/libs/intrusive/test/test_templates.hpp
Properties modified:
   branches/release/libs/interprocess/proj/conceptgcc/MakeAll (contents, props changed)
   branches/release/libs/interprocess/proj/cygwin/MakeAll (contents, props changed)
   branches/release/libs/interprocess/proj/linux/MakeAll (contents, props changed)
   branches/release/libs/interprocess/proj/mingw/MakeAll (contents, props changed)
   branches/release/libs/interprocess/proj/qnx/MakeAll (contents, props changed)
   branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln (contents, props changed)
   branches/release/libs/intrusive/proj/vc7ide/Intrusive.sln (contents, props changed)
Text files modified:
   branches/release/boost/interprocess/allocators/adaptive_pool.hpp | 476 +++++++---
   branches/release/boost/interprocess/allocators/allocation_type.hpp | 2
   branches/release/boost/interprocess/allocators/allocator.hpp | 97 +-
   branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp | 515 +++++------
   branches/release/boost/interprocess/allocators/cached_node_allocator.hpp | 474 ++++------
   branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 742 +++++++++--------
   branches/release/boost/interprocess/allocators/detail/node_pool.hpp | 369 +++-----
   branches/release/boost/interprocess/allocators/detail/node_tools.hpp | 5
   branches/release/boost/interprocess/allocators/node_allocator.hpp | 481 +++++++----
   branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp | 417 +++++++--
   branches/release/boost/interprocess/allocators/private_node_allocator.hpp | 456 ++++++++++
   branches/release/boost/interprocess/containers/deque.hpp | 5
   branches/release/boost/interprocess/containers/detail/flat_tree.hpp | 2
   branches/release/boost/interprocess/containers/detail/node_alloc_holder.hpp | 51
   branches/release/boost/interprocess/containers/detail/tree.hpp | 8
   branches/release/boost/interprocess/containers/flat_map.hpp | 2
   branches/release/boost/interprocess/containers/flat_set.hpp | 2
   branches/release/boost/interprocess/containers/list.hpp | 9
   branches/release/boost/interprocess/containers/map.hpp | 2
   branches/release/boost/interprocess/containers/set.hpp | 2
   branches/release/boost/interprocess/containers/slist.hpp | 26
   branches/release/boost/interprocess/containers/string.hpp | 6
   branches/release/boost/interprocess/containers/vector.hpp | 31
   branches/release/boost/interprocess/creation_tags.hpp | 2
   branches/release/boost/interprocess/detail/algorithms.hpp | 4
   branches/release/boost/interprocess/detail/atomic.hpp | 2
   branches/release/boost/interprocess/detail/cast_tags.hpp | 2
   branches/release/boost/interprocess/detail/config_begin.hpp | 1
   branches/release/boost/interprocess/detail/in_place_interface.hpp | 2
   branches/release/boost/interprocess/detail/interprocess_tester.hpp | 2
   branches/release/boost/interprocess/detail/iterators.hpp | 8
   branches/release/boost/interprocess/detail/managed_memory_impl.hpp | 2
   branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp | 3
   branches/release/boost/interprocess/detail/math_functions.hpp | 2
   branches/release/boost/interprocess/detail/min_max.hpp | 2
   branches/release/boost/interprocess/detail/mpl.hpp | 2
   branches/release/boost/interprocess/detail/named_proxy.hpp | 2
   branches/release/boost/interprocess/detail/os_file_functions.hpp | 2
   branches/release/boost/interprocess/detail/os_thread_functions.hpp | 2
   branches/release/boost/interprocess/detail/pointer_type.hpp | 2
   branches/release/boost/interprocess/detail/posix_time_types_wrk.hpp | 2
   branches/release/boost/interprocess/detail/segment_manager_helper.hpp | 4
   branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp | 2
   branches/release/boost/interprocess/detail/type_traits.hpp | 2
   branches/release/boost/interprocess/detail/utilities.hpp | 191 +++
   branches/release/boost/interprocess/detail/version_type.hpp | 2
   branches/release/boost/interprocess/detail/win32_api.hpp | 2
   branches/release/boost/interprocess/detail/workaround.hpp | 14
   branches/release/boost/interprocess/errors.hpp | 2
   branches/release/boost/interprocess/exceptions.hpp | 2
   branches/release/boost/interprocess/file_mapping.hpp | 2
   branches/release/boost/interprocess/indexes/flat_map_index.hpp | 2
   branches/release/boost/interprocess/indexes/iset_index.hpp | 2
   branches/release/boost/interprocess/indexes/iunordered_set_index.hpp | 7
   branches/release/boost/interprocess/indexes/map_index.hpp | 2
   branches/release/boost/interprocess/indexes/null_index.hpp | 2
   branches/release/boost/interprocess/indexes/unordered_map_index.hpp | 2
   branches/release/boost/interprocess/interprocess_fwd.hpp | 18
   branches/release/boost/interprocess/ipc/message_queue.hpp | 2
   branches/release/boost/interprocess/managed_external_buffer.hpp | 7
   branches/release/boost/interprocess/managed_heap_memory.hpp | 2
   branches/release/boost/interprocess/managed_mapped_file.hpp | 2
   branches/release/boost/interprocess/managed_shared_memory.hpp | 2
   branches/release/boost/interprocess/managed_windows_shared_memory.hpp | 2
   branches/release/boost/interprocess/mapped_region.hpp | 2
   branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp | 185 +++
   branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 61 +
   branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 615 ++++++++-----
   branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp | 2
   branches/release/boost/interprocess/offset_ptr.hpp | 6
   branches/release/boost/interprocess/segment_manager.hpp | 40
   branches/release/boost/interprocess/shared_memory_object.hpp | 2
   branches/release/boost/interprocess/smart_ptr/deleter.hpp | 2
   branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp | 4
   branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp | 2
   branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp | 2
   branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp | 2
   branches/release/boost/interprocess/streams/bufferstream.hpp | 2
   branches/release/boost/interprocess/streams/vectorstream.hpp | 2
   branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp | 2
   branches/release/boost/interprocess/sync/emulation/interprocess_mutex.hpp | 6
   branches/release/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp | 2
   branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp | 2
   branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp | 2
   branches/release/boost/interprocess/sync/file_lock.hpp | 2
   branches/release/boost/interprocess/sync/interprocess_barrier.hpp | 2
   branches/release/boost/interprocess/sync/interprocess_condition.hpp | 2
   branches/release/boost/interprocess/sync/interprocess_mutex.hpp | 10
   branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 14
   branches/release/boost/interprocess/sync/interprocess_semaphore.hpp | 2
   branches/release/boost/interprocess/sync/interprocess_upgradable_mutex.hpp | 2
   branches/release/boost/interprocess/sync/lock_options.hpp | 2
   branches/release/boost/interprocess/sync/mutex_family.hpp | 2
   branches/release/boost/interprocess/sync/named_condition.hpp | 2
   branches/release/boost/interprocess/sync/named_mutex.hpp | 2
   branches/release/boost/interprocess/sync/named_recursive_mutex.hpp | 2
   branches/release/boost/interprocess/sync/named_semaphore.hpp | 2
   branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp | 2
   branches/release/boost/interprocess/sync/null_mutex.hpp | 2
   branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp | 2
   branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp | 148 --
   branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp | 175 ---
   branches/release/boost/interprocess/sync/posix/interprocess_semaphore.hpp | 2
   branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp | 2
   branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp | 2
   branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 2
   branches/release/boost/interprocess/sync/scoped_lock.hpp | 2
   branches/release/boost/interprocess/sync/sharable_lock.hpp | 2
   branches/release/boost/interprocess/sync/upgradable_lock.hpp | 2
   branches/release/boost/interprocess/windows_shared_memory.hpp | 2
   branches/release/boost/intrusive/circular_list_algorithms.hpp | 116 ++
   branches/release/boost/intrusive/circular_slist_algorithms.hpp | 316 +++++--
   branches/release/boost/intrusive/detail/tree_algorithms.hpp | 4
   branches/release/boost/intrusive/detail/utilities.hpp | 3
   branches/release/boost/intrusive/hashtable.hpp | 2
   branches/release/boost/intrusive/intrusive_fwd.hpp | 2
   branches/release/boost/intrusive/list.hpp | 220 ++---
   branches/release/boost/intrusive/options.hpp | 41
   branches/release/boost/intrusive/slist.hpp | 669 +++++++++-----
   branches/release/boost/intrusive/slist_hook.hpp | 2
   branches/release/libs/interprocess/doc/Jamfile.v2 | 1
   branches/release/libs/interprocess/doc/html/reference.css | 8
   branches/release/libs/interprocess/doc/interprocess.qbk | 2
   branches/release/libs/interprocess/proj/conceptgcc/MakeAll | 70
   branches/release/libs/interprocess/proj/cygwin/MakeAll | 66
   branches/release/libs/interprocess/proj/linux/MakeAll | 64
   branches/release/libs/interprocess/proj/mingw/MakeAll | 70
   branches/release/libs/interprocess/proj/qnx/MakeAll | 66
   branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln | 1694 ++++++++++++++++++++--------------------
   branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj | 10
   branches/release/libs/interprocess/test/Jamfile.v2 | 2
   branches/release/libs/interprocess/test/adaptive_node_pool_test.cpp | 2
   branches/release/libs/interprocess/test/adaptive_pool_test.cpp | 24
   branches/release/libs/interprocess/test/cached_adaptive_pool_test.cpp | 24
   branches/release/libs/interprocess/test/cached_node_allocator_test.cpp | 23
   branches/release/libs/interprocess/test/condition_test_template.hpp | 6
   branches/release/libs/interprocess/test/expand_bwd_test_template.hpp | 4
   branches/release/libs/interprocess/test/file_mapping_test.cpp | 10
   branches/release/libs/interprocess/test/get_process_id_name.hpp | 5
   branches/release/libs/interprocess/test/list_test.hpp | 30
   branches/release/libs/interprocess/test/map_test.hpp | 2
   branches/release/libs/interprocess/test/memory_algorithm_test.cpp | 98 +
   branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp | 110 ++
   branches/release/libs/interprocess/test/mutex_test_template.hpp | 28
   branches/release/libs/interprocess/test/named_creation_template.hpp | 9
   branches/release/libs/interprocess/test/node_allocator_test.cpp | 19
   branches/release/libs/interprocess/test/node_pool_test.hpp | 8
   branches/release/libs/interprocess/test/private_adaptive_pool_test.cpp | 19
   branches/release/libs/interprocess/test/private_node_allocator_test.cpp | 21
   branches/release/libs/interprocess/test/semaphore_test_template.hpp | 4
   branches/release/libs/interprocess/test/set_test.hpp | 2
   branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp | 2
   branches/release/libs/interprocess/test/vector_test.cpp | 235 -----
   branches/release/libs/intrusive/doc/html/reference.css | 8
   branches/release/libs/intrusive/example/doc_list_algorithms.cpp | 2
   branches/release/libs/intrusive/example/doc_slist_algorithms.cpp | 2
   branches/release/libs/intrusive/example/doc_splay_algorithms.cpp | 3
   branches/release/libs/intrusive/proj/vc7ide/Intrusive.sln | 350 ++++----
   branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj | 6
   branches/release/libs/intrusive/test/itestvalue.hpp | 12
   branches/release/libs/intrusive/test/list_test.cpp | 125 ++
   branches/release/libs/intrusive/test/slist_test.cpp | 354 +++++++-
   162 files changed, 6377 insertions(+), 4431 deletions(-)

Modified: branches/release/boost/interprocess/allocators/adaptive_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/adaptive_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/adaptive_pool.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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/type_traits.hpp>
 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
 #include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <memory>
 #include <algorithm>
 #include <cstddef>
@@ -35,35 +36,38 @@
 namespace boost {
 namespace interprocess {
 
-//!An STL node allocator that uses a segment manager as memory
-//!source. The internal pointer type will of the same type (raw, smart) as
-//!"typename SegmentManager::void_pointer" type. This allows
-//!placing the allocator in shared memory, memory mapped-files, etc...
-//!This node allocator shares a segregated storage between all instances
-//!of adaptive_pool with equal sizeof(T) placed in the same segment
-//!group. NodesPerChunk is the number of nodes allocated at once when the allocator
-//!needs runs out of nodes. MaxFreeChunks is the number of free nodes
-//!in the adaptive node pool that will trigger the deallocation of
-template<class T, class SegmentManager, std::size_t NodesPerChunk, std::size_t MaxFreeChunks>
-class adaptive_pool
+/// @cond
+
+namespace detail{
+
+template < unsigned int Version
+ , class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
+ >
+class adaptive_pool_base
+ : public node_pool_allocation_impl
+ < adaptive_pool_base
+ < Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent>
+ , Version
+ , T
+ , SegmentManager
+ >
 {
    public:
    typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const void>::type cvoid_pointer;
    typedef SegmentManager segment_manager;
- typedef typename detail::
- pointer_to_other<void_pointer, char>::type char_pointer;
- typedef typename SegmentManager::
- mutex_family::mutex_type mutex_type;
- typedef adaptive_pool
- <T, SegmentManager, NodesPerChunk, MaxFreeChunks> self_t;
+ typedef adaptive_pool_base
+ <Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> self_t;
    typedef detail::shared_adaptive_node_pool
- < SegmentManager, mutex_type
- , sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
+ < SegmentManager, sizeof(T), NodesPerChunk, MaxFreeChunks, OverheadPercent> node_pool_t;
    typedef typename detail::
       pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
 
+ BOOST_STATIC_ASSERT((Version <=2));
+
    public:
    //-------
    typedef typename detail::
@@ -78,52 +82,60 @@
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
 
- //!Obtains adaptive_pool from
- //!adaptive_pool
+ typedef detail::version_type<adaptive_pool_base, Version> version;
+ typedef transform_iterator
+ < typename SegmentManager::
+ multiallocation_iterator
+ , detail::cast_functor <T> > multiallocation_iterator;
+ typedef typename SegmentManager::
+ multiallocation_chain multiallocation_chain;
+
+ //!Obtains adaptive_pool_base from
+ //!adaptive_pool_base
    template<class T2>
    struct rebind
    {
- typedef adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks> other;
+ typedef adaptive_pool_base<Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
    };
 
    /// @cond
    private:
- //!Not assignable from related adaptive_pool
- template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2>
- adaptive_pool& operator=
- (const adaptive_pool<T2, SegmentManager2, N2, F2>&);
+ //!Not assignable from related adaptive_pool_base
+ template<unsigned int Version2, class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char O2>
+ adaptive_pool_base& operator=
+ (const adaptive_pool_base<Version2, T2, SegmentManager2, N2, F2, O2>&);
 
- //!Not assignable from other adaptive_pool
- adaptive_pool& operator=(const adaptive_pool&);
+ //!Not assignable from other adaptive_pool_base
+ adaptive_pool_base& operator=(const adaptive_pool_base&);
    /// @endcond
 
    public:
    //!Constructor from a segment manager. If not present, constructs a node
    //!pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
- adaptive_pool(segment_manager *segment_mngr)
- : mp_node_pool(priv_get_or_create(segment_mngr)) { }
+ adaptive_pool_base(segment_manager *segment_mngr)
+ : mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(segment_mngr)) { }
 
- //!Copy constructor from other adaptive_pool. Increments the reference
+ //!Copy constructor from other adaptive_pool_base. Increments the reference
    //!count of the associated node pool. Never throws
- adaptive_pool(const adaptive_pool &other)
+ adaptive_pool_base(const adaptive_pool_base &other)
       : mp_node_pool(other.get_node_pool())
    {
       mp_node_pool->inc_ref_count();
    }
 
- //!Copy constructor from related adaptive_pool. If not present, constructs
+ //!Copy constructor from related adaptive_pool_base. If not present, constructs
    //!a node pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
    template<class T2>
- adaptive_pool
- (const adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks> &other)
- : mp_node_pool(priv_get_or_create(other.get_segment_manager())) { }
+ adaptive_pool_base
+ (const adaptive_pool_base<Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(other.get_segment_manager())) { }
 
    //!Destructor, removes node_pool_t from memory
    //!if its reference count reaches to zero. Never throws
- ~adaptive_pool()
- { priv_destroy_if_last_link(); }
+ ~adaptive_pool_base()
+ { detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); }
 
    //!Returns a pointer to the node pool.
    //!Never throws
@@ -135,156 +147,300 @@
    segment_manager* get_segment_manager()const
    { return mp_node_pool->get_segment_manager(); }
 
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2)
+ { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
+
+ /// @cond
+ private:
+ node_pool_ptr mp_node_pool;
+ /// @endcond
+};
+
+//!Equality test for same type
+//!of adaptive_pool_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator==(const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
+ const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
+ { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
+
+//!Inequality test for same type
+//!of adaptive_pool_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
+ const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
+ { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk = 64
+ , std::size_t MaxFreeChunks = 2
+ , unsigned char OverheadPercent = 5
+ >
+class adaptive_pool_v1
+ : public adaptive_pool_base
+ < 1
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+{
+ public:
+ typedef detail::adaptive_pool_base
+ < 1, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef adaptive_pool_v1<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ adaptive_pool_v1(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ adaptive_pool_v1
+ (const adaptive_pool_v1<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : base_t(other)
+ {}
+};
+
+} //namespace detail{
+
+/// @endcond
+
+//!An STL node allocator that uses a segment manager as memory
+//!source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
+//!
+//!This node allocator shares a segregated storage between all instances
+//!of adaptive_pool with equal sizeof(T) placed in the same segment
+//!group. NodesPerChunk is the number of nodes allocated at once when the allocator
+//!needs runs out of nodes. MaxFreeChunks is the maximum number of totally free chunks
+//!that the adaptive node pool will hold. The rest of the totally free chunks will be
+//!deallocated with the segment manager.
+//!
+//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
+//!(memory usable for nodes / total memory allocated from the segment manager)
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
+ >
+class adaptive_pool
+ /// @cond
+ : public detail::adaptive_pool_base
+ < 2
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+ /// @endcond
+{
+
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ typedef detail::adaptive_pool_base
+ < 2, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t;
+ public:
+ typedef detail::version_type<adaptive_pool, 2> version;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ adaptive_pool(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ adaptive_pool
+ (const adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : base_t(other)
+ {}
+
+ #else //BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+ typedef implementation_defined::segment_manager segment_manager;
+ typedef segment_manager::void_pointer void_pointer;
+ typedef implementation_defined::pointer pointer;
+ typedef implementation_defined::const_pointer const_pointer;
+ typedef T value_type;
+ typedef typename detail::add_reference
+ <value_type>::type reference;
+ typedef typename detail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ //!Obtains adaptive_pool from
+ //!adaptive_pool
+ template<class T2>
+ struct rebind
+ {
+ typedef adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ private:
+ //!Not assignable from
+ //!related adaptive_pool
+ template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char OP2>
+ adaptive_pool& operator=
+ (const adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
+
+ //!Not assignable from
+ //!other adaptive_pool
+ adaptive_pool& operator=(const adaptive_pool&);
+
+ public:
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ adaptive_pool(segment_manager *segment_mngr);
+
+ //!Copy constructor from other adaptive_pool. Increments the reference
+ //!count of the associated node pool. Never throws
+ adaptive_pool(const adaptive_pool &other);
+
+ //!Copy constructor from related adaptive_pool. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ template<class T2>
+ adaptive_pool
+ (const adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other);
+
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
+ ~adaptive_pool();
+
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ node_pool_t* get_node_pool() const;
+
+ //!Returns the segment manager.
+ //!Never throws
+ segment_manager* get_segment_manager()const;
+
    //!Returns the number of elements that could be allocated.
    //!Never throws
- size_type max_size() const
- { return this->get_segment_manager()->get_size()/sizeof(value_type); }
+ size_type max_size() const;
 
    //!Allocate memory for an array of count elements.
- //!Throws boost::interprocess::bad_alloc if there is no enough memory*/
- pointer allocate(size_type count, cvoid_pointer = 0)
- {
- if(count > ((size_type)-1)/sizeof(value_type))
- throw bad_alloc();
- return pointer(static_cast<T*>(mp_node_pool->allocate(count)));
- }
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate(size_type count, cvoid_pointer hint = 0);
 
    //!Deallocate allocated memory.
    //!Never throws
- void deallocate(const pointer &ptr, size_type count)
- { mp_node_pool->deallocate(detail::get_pointer(ptr), count); }
+ void deallocate(const pointer &ptr, size_type count);
 
- //!Deallocates all free chunks of the pool
- void deallocate_free_chunks()
- { mp_node_pool->deallocate_free_chunks(); }
+ //!Deallocates all free chunks
+ //!of the pool
+ void deallocate_free_chunks();
 
    //!Swaps allocators. Does not throw. If each allocator is placed in a
    //!different memory segment, the result is undefined.
- friend void swap(self_t &alloc1, self_t &alloc2)
- { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
-
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
+ friend void swap(self_t &alloc1, self_t &alloc2);
 
    //!Returns address of mutable object.
    //!Never throws
- pointer address(reference value) const
- { return pointer(boost::addressof(value)); }
+ pointer address(reference value) const;
 
    //!Returns address of non mutable object.
    //!Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(boost::addressof(value)); }
+ const_pointer address(const_reference value) const;
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
- void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ //!Throws if T's default constructor throws
+ void construct(const pointer &ptr);
 
    //!Destroys object. Throws if object's
    //!destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-
- /// @cond
- private:
- //!Object function that creates the node allocator if it is not created and
- //!increments reference count if it is already created
- struct get_or_create_func
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
-
- //!This connects or constructs the unique instance of node_pool_t
- //!Can throw boost::interprocess::bad_alloc
- void operator()()
- {
- //Find or create the node_pool_t
- mp_node_pool = mp_named_alloc->template find_or_construct
- <node_pool_t>(unique_instance)(mp_named_alloc);
- //If valid, increment link count
- if(mp_node_pool != 0)
- mp_node_pool->inc_ref_count();
- }
-
- //!Constructor. Initializes function
- //!object parameters
- get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
-
- node_pool_t *mp_node_pool;
- segment_manager *mp_named_alloc;
- };
-
- //!Initialization function, creates an executes atomically the
- //!initialization object functions. Can throw boost::interprocess::bad_alloc
- node_pool_t *priv_get_or_create(segment_manager *named_alloc)
- {
- get_or_create_func func(named_alloc);
- named_alloc->atomic_func(func);
- return func.mp_node_pool;
- }
-
- //!Object function that decrements the reference count. If the count
- //!reaches to zero destroys the node allocator from memory.
- //!Never throws
- struct destroy_if_last_link_func
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
-
- //!Decrements reference count and destroys the object if there is no
- //!more attached allocators. Never throws
- void operator()()
- {
- //If not the last link return
- if(mp_node_pool->dec_ref_count() != 0) return;
-
- //Last link, let's destroy the segment_manager
- mp_named_alloc->template destroy<node_pool_t>(unique_instance);
- }
-
- //!Constructor. Initializes function
- //!object parameters
- destroy_if_last_link_func(segment_manager *nhdr,
- node_pool_t *phdr)
- : mp_named_alloc(nhdr), mp_node_pool(phdr){}
-
- segment_manager *mp_named_alloc;
- node_pool_t *mp_node_pool;
- };
+ void destroy(const pointer &ptr);
 
- //!Destruction function, initializes and executes destruction function
- //!object. Never throws
- void priv_destroy_if_last_link()
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
- //Get segment manager
- segment_manager *named_segment_mngr = this->get_segment_manager();
- //Execute destruction functor atomically
- destroy_if_last_link_func func(named_segment_mngr, detail::get_pointer(mp_node_pool));
- named_segment_mngr->atomic_func(func);
- }
-
- private:
- node_pool_ptr mp_node_pool;
- /// @endcond
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it);
+
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one();
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ multiallocation_iterator allocate_individual(std::size_t num_elements);
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p);
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it);
+ #endif
 };
 
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
 //!Equality test for same type
 //!of adaptive_pool
-template<class T, class S, std::size_t NodesPerChunk, std::size_t F> inline
-bool operator==(const adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
- const adaptive_pool<T, S, NodesPerChunk, F> &alloc2)
- { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator==(const adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc1,
+ const adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc2);
 
 //!Inequality test for same type
 //!of adaptive_pool
-template<class T, class S, std::size_t NodesPerChunk, std::size_t F> inline
-bool operator!=(const adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
- const adaptive_pool<T, S, NodesPerChunk, F> &alloc2)
- { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc1,
+ const adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc2);
 
+#endif
 
 } //namespace interprocess {
 } //namespace boost {

Modified: branches/release/boost/interprocess/allocators/allocation_type.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/allocation_type.hpp (original)
+++ branches/release/boost/interprocess/allocators/allocation_type.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/allocator.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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,6 @@
    /// @cond
    private:
 
- 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)); }
- };
-
    //Self type
    typedef allocator<T, SegmentManager> self_t;
 
@@ -108,7 +101,13 @@
    typedef transform_iterator
       < typename SegmentManager::
          multiallocation_iterator
- , cast_functor> multiallocation_iterator;
+ , detail::cast_functor <T> > multiallocation_iterator;
+ typedef detail::multiallocation_chain_adaptor
+ <typename SegmentManager::
+ multiallocation_chain
+ , T> multiallocation_chain;
+// typedef typename SegmentManager::
+// multiallocation_chain multiallocation_chain;
 
    /// @endcond
 
@@ -146,7 +145,7 @@
    pointer allocate(size_type count, cvoid_ptr hint = 0)
    {
       (void)hint;
- if(count > ((size_type)-1)/sizeof(T))
+ if(count > this->max_size())
          throw bad_alloc();
       return pointer((value_type*)mp_mngr->allocate(count*sizeof(T)));
    }
@@ -166,7 +165,13 @@
    friend void swap(self_t &alloc1, self_t &alloc2)
    { detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
 
- //Experimental version 2 allocator functions
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const
+ {
+ return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T);
+ }
 
    std::pair<pointer, bool>
       allocation_command(allocation_type command,
@@ -178,23 +183,42 @@
          (command, limit_size, preferred_size, received_size, detail::get_pointer(reuse));
    }
 
- //!Returns maximum the number of objects the previously allocated memory
- //!pointed by p can hold.
- size_type size(const pointer &p) const
- {
- return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T);
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements)
+ {
+ return multiallocation_iterator
+ (mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
    }
 
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements)
+ {
+ return multiallocation_iterator
+ (mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T)));
+ }
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it)
+ { return mp_mngr->deallocate_many(it.base()); }
+
    //!Allocates just one object. Memory allocated with this function
    //!must be deallocated only with deallocate_one().
    //!Throws boost::interprocess::bad_alloc if there is no enough memory
    pointer allocate_one()
    { return this->allocate(1); }
 
- /// @cond
-
- //Experimental. Don't use.
-
    //!Allocates many elements of size == 1 in a contiguous chunk
    //!of memory. The minimum number to be allocated is min_elements,
    //!the preferred and maximum number is
@@ -204,41 +228,20 @@
    multiallocation_iterator allocate_individual(std::size_t num_elements)
    { return this->allocate_many(1, num_elements); }
 
- /// @endcond
-
    //!Deallocates memory previously allocated with allocate_one().
    //!You should never use deallocate_one to deallocate memory allocated
    //!with other functions different from allocate_one(). Never throws
    void deallocate_one(const pointer &p)
    { return this->deallocate(p, 1); }
 
- /// @cond
-
- //!Allocates many elements of size elem_size in a contiguous chunk
+ //!Allocates many elements of size == 1 in a contiguous chunk
    //!of memory. The minimum number to be allocated is min_elements,
    //!the preferred and maximum number is
    //!preferred_elements. The number of actually allocated elements is
- //!will be assigned to received_size. The elements must be deallocated
- //!with deallocate(...)
- multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements)
- {
- return multiallocation_iterator
- (mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
- }
-
- //!Allocates n_elements elements, each one of size elem_sizes[i]in a
- //!contiguous chunk
- //!of memory. The elements must be deallocated
- multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements)
- {
- return multiallocation_iterator
- (mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T)));
- }
-
- /// @endcond
-
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it)
+ { return this->deallocate_many(it); }
 
    //!Returns address of mutable object.
    //!Never throws
@@ -251,7 +254,7 @@
    { return const_pointer(boost::addressof(value)); }
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
+ //!Throws if T's default constructor throws
    void construct(const pointer &ptr)
    { new(detail::get_pointer(ptr)) value_type; }
 

Modified: branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/cached_adaptive_pool.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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,56 +19,155 @@
 #include <boost/interprocess/detail/workaround.hpp>
 
 #include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/assert.hpp>
-#include <boost/utility/addressof.hpp>
 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
+#include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/version_type.hpp>
 #include <boost/interprocess/allocators/detail/node_tools.hpp>
-#include <memory>
-#include <algorithm>
 #include <cstddef>
 
 //!\file
-//!Describes cached_cached_node_allocator pooled shared memory STL compatible allocator
+//!Describes cached_adaptive_pool pooled shared memory STL compatible allocator
 
 namespace boost {
 namespace interprocess {
 
+/// @cond
+
+namespace detail {
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk = 64
+ , std::size_t MaxFreeChunks = 2
+ , unsigned char OverheadPercent = 5
+ >
+class cached_adaptive_pool_v1
+ : public detail::cached_allocator_impl
+ < T
+ , detail::shared_adaptive_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+ , 1>
+{
+ public:
+ typedef detail::cached_allocator_impl
+ < T
+ , detail::shared_adaptive_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+ , 1> base_t;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef cached_adaptive_pool_v1
+ <T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ cached_adaptive_pool_v1(SegmentManager *segment_mngr,
+ std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ : base_t(segment_mngr, max_cached_nodes)
+ {}
+
+ template<class T2>
+ cached_adaptive_pool_v1
+ (const cached_adaptive_pool_v1
+ <T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : base_t(other)
+ {}
+};
+
+} //namespace detail{
+
+/// @endcond
+
 //!An STL node allocator that uses a segment manager as memory
 //!source. The internal pointer type will of the same type (raw, smart) as
 //!"typename SegmentManager::void_pointer" type. This allows
 //!placing the allocator in shared memory, memory mapped-files, etc...
+//!
 //!This node allocator shares a segregated storage between all instances of
-//!cached_adaptive_pool with equal sizeof(T) placed in the same fixed size
+//!cached_adaptive_pool with equal sizeof(T) placed in the same
 //!memory segment. But also caches some nodes privately to
 //!avoid some synchronization overhead.
-template<class T, class SegmentManager, std::size_t NodesPerChunk, std::size_t MaxFreeChunks>
+//!
+//!NodesPerChunk is the minimum number of nodes of nodes allocated at once when
+//!the allocator needs runs out of nodes. MaxFreeChunks is the maximum number of totally free chunks
+//!that the adaptive node pool will hold. The rest of the totally free chunks will be
+//!deallocated with the segment manager.
+//!
+//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
+//!(memory usable for nodes / total memory allocated from the segment manager)
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
+ >
 class cached_adaptive_pool
-{
    /// @cond
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const void>::type cvoid_pointer;
- typedef SegmentManager segment_manager;
- typedef typename detail::
- pointer_to_other<void_pointer, char>::type char_pointer;
- typedef typename SegmentManager::mutex_family::mutex_type mutex_type;
- typedef cached_adaptive_pool
- <T, SegmentManager, NodesPerChunk, MaxFreeChunks> self_t;
- enum { DEFAULT_MAX_CACHED_NODES = 64 };
-
- typedef typename detail::node_slist<void_pointer>::node_t node_t;
- typedef typename detail::node_slist<void_pointer>::node_slist_t cached_list_t;
+ : public detail::cached_allocator_impl
+ < T
+ , detail::shared_adaptive_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+ , 2>
    /// @endcond
+{
+
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+ typedef detail::cached_allocator_impl
+ < T
+ , detail::shared_adaptive_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+ , 2> base_t;
 
    public:
- //-------
- typedef typename detail::
- pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const T>::type const_pointer;
+ typedef detail::version_type<cached_adaptive_pool, 2> version;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef cached_adaptive_pool
+ <T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ cached_adaptive_pool(SegmentManager *segment_mngr,
+ std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ : base_t(segment_mngr, max_cached_nodes)
+ {}
+
+ template<class T2>
+ cached_adaptive_pool
+ (const cached_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : base_t(other)
+ {}
+
+ #else
+ public:
+ typedef implementation_defined::segment_manager segment_manager;
+ typedef segment_manager::void_pointer void_pointer;
+ typedef implementation_defined::pointer pointer;
+ typedef implementation_defined::const_pointer const_pointer;
    typedef T value_type;
    typedef typename detail::add_reference
                      <value_type>::type reference;
@@ -76,312 +175,178 @@
                      <const value_type>::type const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
- typedef detail::shared_adaptive_node_pool
- < SegmentManager, mutex_type
- , sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
- typedef typename detail::
- pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
 
- //!Obtains cached_adaptive_pool from other
+ //!Obtains cached_adaptive_pool from
    //!cached_adaptive_pool
    template<class T2>
    struct rebind
    {
- typedef cached_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks> other;
+ typedef cached_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
    };
 
- /// @cond
    private:
-
- //!Not assignable from related cached_adaptive_pool
- template<class T2, class SegmentManager2, std::size_t N2, std::size_t MaxFreeChunks2>
+ //!Not assignable from
+ //!related cached_adaptive_pool
+ template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char OP2>
    cached_adaptive_pool& operator=
- (const cached_adaptive_pool<T2, SegmentManager2, N2, MaxFreeChunks2>&);
+ (const cached_adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
 
- //!Not assignable from other cached_adaptive_pool
+ //!Not assignable from
+ //!other cached_adaptive_pool
    cached_adaptive_pool& operator=(const cached_adaptive_pool&);
- /// @endcond
-
+
    public:
- //!Constructor from a segment manager. If not present, constructs
- //!a node pool. Increments the reference count of the node pool.
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
- cached_adaptive_pool(segment_manager *segment_mngr,
- std::size_t max_cached_nodes = DEFAULT_MAX_CACHED_NODES)
- : mp_node_pool(priv_get_or_create(segment_mngr)),
- m_max_cached_nodes(max_cached_nodes)
- {}
+ cached_adaptive_pool(segment_manager *segment_mngr);
 
- //!Copy constructor from other cached_adaptive_pool. Increments the
- //!reference count of the associated node pool. Never throws
- cached_adaptive_pool(const cached_adaptive_pool &other)
- : mp_node_pool(other.get_node_pool()),
- m_max_cached_nodes(other.get_max_cached_nodes())
- { mp_node_pool->inc_ref_count(); }
+ //!Copy constructor from other cached_adaptive_pool. Increments the reference
+ //!count of the associated node pool. Never throws
+ cached_adaptive_pool(const cached_adaptive_pool &other);
 
    //!Copy constructor from related cached_adaptive_pool. If not present, constructs
    //!a node pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
    template<class T2>
    cached_adaptive_pool
- (const cached_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks> &other)
- : mp_node_pool(priv_get_or_create(other.get_segment_manager())),
- m_max_cached_nodes(other.get_max_cached_nodes())
- { }
+ (const cached_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other);
 
    //!Destructor, removes node_pool_t from memory
    //!if its reference count reaches to zero. Never throws
- ~cached_adaptive_pool()
- {
- priv_deallocate_all_cached_nodes();
- priv_destroy_if_last_link();
- }
+ ~cached_adaptive_pool();
 
    //!Returns a pointer to the node pool.
    //!Never throws
- node_pool_t* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ node_pool_t* get_node_pool() const;
 
    //!Returns the segment manager.
    //!Never throws
- segment_manager* get_segment_manager()const
- { return mp_node_pool->get_segment_manager(); }
-
- //!Sets the new max cached nodes value. This can provoke deallocations
- //!if "newmax" is less than current cached nodes. Never throws
- void set_max_cached_nodes(std::size_t newmax)
- {
- m_max_cached_nodes = newmax;
- priv_deallocate_remaining_nodes();
- }
+ segment_manager* get_segment_manager()const;
 
- //!Returns the max cached nodes parameter.
+ //!Returns the number of elements that could be allocated.
    //!Never throws
- std::size_t get_max_cached_nodes() const
- { return m_max_cached_nodes; }
-
- //!Returns the number of elements that could be
- //!allocated. Never throws
- size_type max_size() const
- { return this->get_segment_manager()->get_size()/sizeof(value_type); }
+ size_type max_size() const;
 
    //!Allocate memory for an array of count elements.
    //!Throws boost::interprocess::bad_alloc if there is no enough memory
- pointer allocate(size_type count, cvoid_pointer hint = 0)
- {
- (void)hint;
- if(count > ((size_type)-1)/sizeof(value_type))
- throw bad_alloc();
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
-
- void * ret;
-
- if(count == 1){
- //If don't have any cached node, we have to get a new list of free nodes from the pool
- if(m_cached_nodes.empty()){
- mp_node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes);
- }
- ret = &m_cached_nodes.front();
- m_cached_nodes.pop_front();
- }
- else{
- ret = mp_node_pool->allocate(count);
- }
- return pointer(static_cast<T*>(ret));
- }
-
- //!Deallocate allocated memory. Never throws
- void deallocate(const pointer &ptr, size_type count)
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
-
- if(count == 1){
- //Check if cache is full
- if(m_cached_nodes.size() >= m_max_cached_nodes){
- //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.
- priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2);
- }
- m_cached_nodes.push_front(*(node_t*)detail::char_ptr_cast(detail::get_pointer(ptr)));
- }
- else{
- mp_node_pool->deallocate(detail::get_pointer(ptr), count);
- }
- }
-
- //!Deallocates all free chunks of the pool
- void deallocate_free_chunks()
- { mp_node_pool->deallocate_free_chunks(); }
+ pointer allocate(size_type count, cvoid_pointer hint = 0);
 
- //!Swaps allocators. Does not throw. If each allocator is placed in a
- //!different shared memory segments, the result is undefined.
- friend void swap(self_t &alloc1, self_t &alloc2)
- {
- detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool);
- alloc1.m_cached_nodes.swap(alloc2.m_cached_nodes);
- detail::do_swap(alloc1.m_max_cached_nodes, alloc2.m_max_cached_nodes);
- }
+ //!Deallocate allocated memory.
+ //!Never throws
+ void deallocate(const pointer &ptr, size_type count);
 
- void deallocate_cache()
- { this->priv_deallocate_all_cached_nodes(); }
+ //!Deallocates all free chunks
+ //!of the pool
+ void deallocate_free_chunks();
 
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2);
 
    //!Returns address of mutable object.
    //!Never throws
- pointer address(reference value) const
- { return pointer(boost::addressof(value)); }
+ pointer address(reference value) const;
 
    //!Returns address of non mutable object.
    //!Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(boost::addressof(value)); }
+ const_pointer address(const_reference value) const;
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
- void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ //!Throws if T's default constructor throws
+ void construct(const pointer &ptr);
 
    //!Destroys object. Throws if object's
    //!destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-
- /// @cond
- private:
+ void destroy(const pointer &ptr);
 
- //!Object function that creates the node allocator if it is not created and
- //!increments reference count if it is already created
- struct get_or_create_func
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
-
- //!This connects or constructs the unique instance of node_pool_t
- //!Can throw boost::interprocess::bad_alloc
- void operator()()
- {
- //Find or create the node_pool_t
- mp_node_pool = mp_named_alloc->template find_or_construct
- <node_pool_t>(unique_instance)(mp_named_alloc);
- //If valid, increment link count
- if(mp_node_pool != 0)
- mp_node_pool->inc_ref_count();
- }
-
- //!Constructor. Initializes function
- //!object parameters
- get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
-
- node_pool_t *mp_node_pool;
- segment_manager *mp_named_alloc;
- };
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it);
 
- //!Frees all cached nodes.
- //!Never throws
- void priv_deallocate_all_cached_nodes()
- {
- if(m_cached_nodes.empty()) return;
- mp_node_pool->deallocate_nodes(m_cached_nodes);
- }
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one();
 
- //!Frees all cached nodes at once.
- //!Never throws
- void priv_deallocate_remaining_nodes()
- {
- if(m_cached_nodes.size() > m_max_cached_nodes){
- priv_deallocate_n_nodes(m_cached_nodes.size()-m_max_cached_nodes);
- }
- }
-
- //!Frees n cached nodes at once. Never throws
- void priv_deallocate_n_nodes(std::size_t n)
- {
- //Deallocate all new linked list at once
- mp_node_pool->deallocate_nodes(m_cached_nodes, n);
- }
-
- //!Initialization function, creates an executes atomically the
- //!initialization object functions. Can throw boost::interprocess::bad_alloc
- node_pool_t *priv_get_or_create(segment_manager *named_alloc)
- {
- get_or_create_func func(named_alloc);
- named_alloc->atomic_func(func);
- return func.mp_node_pool;
- }
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ multiallocation_iterator allocate_individual(std::size_t num_elements);
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p);
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it);
+ //!Sets the new max cached nodes value. This can provoke deallocations
+ //!if "newmax" is less than current cached nodes. Never throws
+ void set_max_cached_nodes(std::size_t newmax);
 
- //!Object function that decrements the reference count. If the count
- //!reaches to zero destroys the node allocator from memory.
+ //!Returns the max cached nodes parameter.
    //!Never throws
- struct destroy_if_last_link_func
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
-
- //!Decrements reference count and destroys the object if there is no
- //!more attached allocators. Never throws
- void operator()()
- {
- //If not the last link return
- if(mp_node_pool->dec_ref_count() != 0) return;
-
- //Last link, let's destroy the segment_manager
- mp_named_alloc->template destroy<node_pool_t>(unique_instance);
- }
-
- //!Constructor. Initializes function
- //!object parameters
- destroy_if_last_link_func(segment_manager *nhdr,
- node_pool_t *phdr)
- : mp_named_alloc(nhdr), mp_node_pool(phdr){}
-
- segment_manager *mp_named_alloc;
- node_pool_t *mp_node_pool;
- };
+ std::size_t get_max_cached_nodes() const;
+ #endif
+};
 
- //!Destruction function, initializes and executes destruction function
- //!object. Never throws
- void priv_destroy_if_last_link()
- {
- typedef detail::shared_adaptive_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk, MaxFreeChunks> node_pool_t;
- //Get segment manager
- segment_manager *segment_mngr = this->get_segment_manager();
- //Execute destruction functor atomically
- destroy_if_last_link_func func(segment_mngr, detail::get_pointer(mp_node_pool));
- segment_mngr->atomic_func(func);
- }
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
 
- private:
- node_pool_ptr mp_node_pool;
- cached_list_t m_cached_nodes;
- std::size_t m_max_cached_nodes;
- /// @endcond
-};
+//!Equality test for same type
+//!of cached_adaptive_pool
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, std::size_t OP> inline
+bool operator==(const cached_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc1,
+ const cached_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc2);
+
+//!Inequality test for same type
+//!of cached_adaptive_pool
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, std::size_t OP> inline
+bool operator!=(const cached_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc1,
+ const cached_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc2);
 
-//!Equality test for same type of
-//!cached_adaptive_pool
-template<class T, class S, std::size_t NodesPerChunk, std::size_t M> inline
-bool operator==(const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc1,
- const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc2)
- { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
-
-//!Inequality test for same type of
-//!cached_adaptive_pool
-template<class T, class S, std::size_t NodesPerChunk, std::size_t M> inline
-bool operator!=(const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc1,
- const cached_adaptive_pool<T, S, NodesPerChunk, M> &alloc2)
- { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
+#endif
 
 } //namespace interprocess {
-
 } //namespace boost {
 
+
 #include <boost/interprocess/detail/config_end.hpp>
 
 #endif //#ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP

Modified: branches/release/boost/interprocess/allocators/cached_node_allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/cached_node_allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/cached_node_allocator.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -19,14 +19,11 @@
 #include <boost/interprocess/detail/workaround.hpp>
 
 #include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/assert.hpp>
-#include <boost/utility/addressof.hpp>
 #include <boost/interprocess/allocators/detail/node_pool.hpp>
+#include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <memory>
-#include <algorithm>
+#include <boost/interprocess/detail/version_type.hpp>
+#include <boost/interprocess/allocators/detail/node_tools.hpp>
 #include <cstddef>
 
 //!\file
@@ -35,37 +32,113 @@
 namespace boost {
 namespace interprocess {
 
-//!An STL node allocator that uses a segment manager as memory
-//!source. The internal pointer type will of the same type (raw, smart) as
-//!"typename SegmentManager::void_pointer" type. This allows
-//!placing the allocator in shared memory, memory mapped-files, etc...
-//!This node allocator shares a segregated storage between all instances of
-//!cached_node_allocator with equal sizeof(T) placed in the same fixed size
-//!memory segment. But also caches some nodes privately to
-//!avoid some synchronization overhead.
-template<class T, class SegmentManager, std::size_t NodesPerChunk>
-class cached_node_allocator
+
+/// @cond
+
+namespace detail {
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk = 64
+ >
+class cached_node_allocator_v1
+ : public detail::cached_allocator_impl
+ < T
+ , detail::shared_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ >
+ , 1>
 {
+ public:
+ typedef detail::cached_allocator_impl
+ < T
+ , detail::shared_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ >
+ , 1> base_t;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef cached_node_allocator_v1
+ <T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ cached_node_allocator_v1(SegmentManager *segment_mngr,
+ std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ : base_t(segment_mngr, max_cached_nodes)
+ {}
+
+ template<class T2>
+ cached_node_allocator_v1
+ (const cached_node_allocator_v1
+ <T2, SegmentManager, NodesPerChunk> &other)
+ : base_t(other)
+ {}
+};
+
+} //namespace detail{
+
+/// @endcond
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ >
+class cached_node_allocator
    /// @cond
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const void>::type cvoid_pointer;
- typedef SegmentManager segment_manager;
- typedef typename detail::
- pointer_to_other<void_pointer, char>::type char_pointer;
- typedef typename SegmentManager::mutex_family::mutex_type mutex_type;
- typedef cached_node_allocator<T, SegmentManager, NodesPerChunk> self_t;
- enum { DEFAULT_MAX_CACHED_NODES = 64 };
- typedef typename detail::node_slist<void_pointer>::node_t node_t;
- typedef typename detail::node_slist<void_pointer>::node_slist_t cached_list_t;
+ : public detail::cached_allocator_impl
+ < T
+ , detail::shared_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ >
+ , 2>
    /// @endcond
+{
+
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ public:
+ typedef detail::cached_allocator_impl
+ < T
+ , detail::shared_node_pool
+ < SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ >
+ , 2> base_t;
 
    public:
- //-------
- typedef typename detail::
- pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const T>::type const_pointer;
+ typedef detail::version_type<cached_node_allocator, 2> version;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef cached_node_allocator<T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ cached_node_allocator(SegmentManager *segment_mngr,
+ std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
+ : base_t(segment_mngr, max_cached_nodes)
+ {}
+
+ template<class T2>
+ cached_node_allocator
+ (const cached_node_allocator<T2, SegmentManager, NodesPerChunk> &other)
+ : base_t(other)
+ {}
+
+ #else
+ public:
+ typedef implementation_defined::segment_manager segment_manager;
+ typedef segment_manager::void_pointer void_pointer;
+ typedef implementation_defined::pointer pointer;
+ typedef implementation_defined::const_pointer const_pointer;
    typedef T value_type;
    typedef typename detail::add_reference
                      <value_type>::type reference;
@@ -73,302 +146,173 @@
                      <const value_type>::type const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
- typedef detail::shared_node_pool
- < SegmentManager, mutex_type
- , sizeof(T), NodesPerChunk> node_pool_t;
- typedef typename detail::
- pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
 
- //!Obtains cached_node_allocator from other cached_node_allocator
+ //!Obtains cached_node_allocator from
+ //!cached_node_allocator
    template<class T2>
    struct rebind
    {
- typedef cached_node_allocator<T2, SegmentManager, NodesPerChunk> other;
+ typedef cached_node_allocator<T2, SegmentManager> other;
    };
 
- /// @cond
    private:
-
- //!Not assignable from related cached_node_allocator
+ //!Not assignable from
+ //!related cached_node_allocator
    template<class T2, class SegmentManager2, std::size_t N2>
    cached_node_allocator& operator=
       (const cached_node_allocator<T2, SegmentManager2, N2>&);
 
- //!Not assignable from other cached_node_allocator
+ //!Not assignable from
+ //!other cached_node_allocator
    cached_node_allocator& operator=(const cached_node_allocator&);
- /// @endcond
 
    public:
- //!Constructor from a segment manager. If not present, constructs
- //!a node pool. Increments the reference count of the node pool.
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
- cached_node_allocator(segment_manager *segment_mngr,
- std::size_t max_cached_nodes = DEFAULT_MAX_CACHED_NODES)
- : mp_node_pool(priv_get_or_create(segment_mngr)),
- m_max_cached_nodes(max_cached_nodes)
- {}
+ cached_node_allocator(segment_manager *segment_mngr);
 
- //!Copy constructor from other cached_node_allocator. Increments the
- //!reference count of the associated node pool. Never throws
- cached_node_allocator(const cached_node_allocator &other)
- : mp_node_pool(other.get_node_pool()),
- m_max_cached_nodes(other.get_max_cached_nodes())
- { mp_node_pool->inc_ref_count(); }
+ //!Copy constructor from other cached_node_allocator. Increments the reference
+ //!count of the associated node pool. Never throws
+ cached_node_allocator(const cached_node_allocator &other);
 
    //!Copy constructor from related cached_node_allocator. If not present, constructs
    //!a node pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
    template<class T2>
    cached_node_allocator
- (const cached_node_allocator<T2, SegmentManager, NodesPerChunk> &other)
- : mp_node_pool(priv_get_or_create(other.get_segment_manager())),
- m_max_cached_nodes(other.get_max_cached_nodes())
- { }
+ (const cached_node_allocator<T2, SegmentManager, NodesPerChunk> &other);
 
    //!Destructor, removes node_pool_t from memory
    //!if its reference count reaches to zero. Never throws
- ~cached_node_allocator()
- {
- priv_deallocate_all_cached_nodes();
- priv_destroy_if_last_link();
- }
+ ~cached_node_allocator();
 
    //!Returns a pointer to the node pool.
    //!Never throws
- node_pool_t* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ node_pool_t* get_node_pool() const;
 
    //!Returns the segment manager.
    //!Never throws
- segment_manager* get_segment_manager()const
- { return mp_node_pool->get_segment_manager(); }
-
- //!Sets the new max cached nodes value. This can provoke deallocations
- //!if "newmax" is less than current cached nodes. Never throws
- void set_max_cached_nodes(std::size_t newmax)
- {
- m_max_cached_nodes = newmax;
- priv_deallocate_remaining_nodes();
- }
+ segment_manager* get_segment_manager()const;
 
- //!Returns the max cached nodes parameter.
+ //!Returns the number of elements that could be allocated.
    //!Never throws
- std::size_t get_max_cached_nodes() const
- { return m_max_cached_nodes; }
-
- //!Returns the number of elements that could be allocated. Never throws
- size_type max_size() const
- { return this->get_segment_manager()->get_size()/sizeof(value_type); }
+ size_type max_size() const;
 
    //!Allocate memory for an array of count elements.
    //!Throws boost::interprocess::bad_alloc if there is no enough memory
- pointer allocate(size_type count, cvoid_pointer hint = 0)
- {
- (void)hint;
- if(count > ((size_type)-1)/sizeof(value_type))
- throw bad_alloc();
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk> node_pool_t;
-
- void * ret;
-
- if(count == 1){
- //If don't have any cached node, we have to get a new list of free nodes from the pool
- if(m_cached_nodes.empty()){
- mp_node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes);
- }
- ret = &m_cached_nodes.front();
- m_cached_nodes.pop_front();
- }
- else{
- ret = mp_node_pool->allocate(count);
- }
- return pointer(static_cast<T*>(ret));
- }
+ pointer allocate(size_type count, cvoid_pointer hint = 0);
 
    //!Deallocate allocated memory.
    //!Never throws
- void deallocate(const pointer &ptr, size_type count)
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk> node_pool_t;
-
- if(count == 1){
- //Check if cache is full
- if(m_cached_nodes.size() >= m_max_cached_nodes){
- //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.
- priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2);
- }
- m_cached_nodes.push_front(*(node_t*)detail::char_ptr_cast(detail::get_pointer(ptr)));
- }
- else{
- mp_node_pool->deallocate(detail::get_pointer(ptr), count);
- }
- }
+ void deallocate(const pointer &ptr, size_type count);
 
- //!Swaps allocators. Does not throw. If each allocator is placed in a
- //!different shared memory segments, the result is undefined.
- friend void swap(self_t &alloc1, self_t &alloc2)
- {
- detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool);
- alloc1.m_cached_nodes.swap(alloc2.m_cached_nodes);
- detail::do_swap(alloc1.m_max_cached_nodes, alloc2.m_max_cached_nodes);
- }
-
- //!Returns the cached nodes to the shared pool
- void deallocate_cache()
- { this->priv_deallocate_all_cached_nodes(); }
-
- //!Deallocates all free chunks of the pool
- void deallocate_free_chunks()
- { mp_node_pool->deallocate_free_chunks(); }
+ //!Deallocates all free chunks
+ //!of the pool
+ void deallocate_free_chunks();
 
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2);
 
    //!Returns address of mutable object.
    //!Never throws
- pointer address(reference value) const
- { return pointer(boost::addressof(value)); }
+ pointer address(reference value) const;
 
    //!Returns address of non mutable object.
    //!Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(boost::addressof(value)); }
+ const_pointer address(const_reference value) const;
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
- void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ //!Throws if T's default constructor throws
+ void construct(const pointer &ptr);
 
    //!Destroys object. Throws if object's
    //!destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
+ void destroy(const pointer &ptr);
 
- /// @cond
- private:
-
- //!Object function that creates the node allocator if it is not created and
- //!increments reference count if it is already created
- struct get_or_create_func
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk> node_pool_t;
-
- //!This connects or constructs the unique instance of node_pool_t
- //!Can throw boost::interprocess::bad_alloc
- void operator()()
- {
- //Find or create the node_pool_t
- mp_node_pool = mp_named_alloc->template find_or_construct
- <node_pool_t>(unique_instance)(mp_named_alloc);
- //If valid, increment link count
- if(mp_node_pool != 0)
- mp_node_pool->inc_ref_count();
- }
-
- //!Constructor. Initializes function
- //!object parameters
- get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
-
- node_pool_t *mp_node_pool;
- segment_manager *mp_named_alloc;
- };
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it);
 
- //!Frees all cached nodes.
- //!Never throws
- void priv_deallocate_all_cached_nodes()
- { mp_node_pool->deallocate_nodes(m_cached_nodes); }
-
- //!Frees all cached nodes at once.
- //!Never throws
- void priv_deallocate_remaining_nodes()
- {
- if(m_cached_nodes.size() > m_max_cached_nodes){
- priv_deallocate_n_nodes(m_cached_nodes.size()-m_max_cached_nodes);
- }
- }
-
- //!Frees n cached nodes at once.
- //!Never throws
- void priv_deallocate_n_nodes(std::size_t n)
- { mp_node_pool->deallocate_nodes(m_cached_nodes, n); }
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one();
 
- //!Initialization function, creates an executes atomically the
- //!initialization object functions. Can throw boost::interprocess::bad_alloc
- node_pool_t *priv_get_or_create(segment_manager *named_alloc)
- {
- get_or_create_func func(named_alloc);
- named_alloc->atomic_func(func);
- return func.mp_node_pool;
- }
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ multiallocation_iterator allocate_individual(std::size_t num_elements);
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p);
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it);
+ //!Sets the new max cached nodes value. This can provoke deallocations
+ //!if "newmax" is less than current cached nodes. Never throws
+ void set_max_cached_nodes(std::size_t newmax);
 
- //!Object function that decrements the reference count. If the count
- //!reaches to zero destroys the node allocator from memory.
+ //!Returns the max cached nodes parameter.
    //!Never throws
- struct destroy_if_last_link_func
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk> node_pool_t;
-
- //!Decrements reference count and destroys the object if there is no
- //!more attached allocators. Never throws
- void operator()()
- {
- //If not the last link return
- if(mp_node_pool->dec_ref_count() != 0) return;
-
- //Last link, let's destroy the segment_manager
- mp_named_alloc->template destroy<node_pool_t>(unique_instance);
- }
-
- //!Constructor. Initializes function object
- //!parameters
- destroy_if_last_link_func(segment_manager *nhdr,
- node_pool_t *phdr)
- : mp_named_alloc(nhdr), mp_node_pool(phdr){}
-
- segment_manager *mp_named_alloc;
- node_pool_t *mp_node_pool;
- };
-
- //!Destruction function, initializes and executes destruction function
- //!object. Never throws
- void priv_destroy_if_last_link()
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk> node_pool_t;
- //Get segment manager
- segment_manager *segment_mngr = this->get_segment_manager();
- //Execute destruction functor atomically
- destroy_if_last_link_func func(segment_mngr, detail::get_pointer(mp_node_pool));
- segment_mngr->atomic_func(func);
- }
-
- private:
- node_pool_ptr mp_node_pool;
- cached_list_t m_cached_nodes;
- std::size_t m_max_cached_nodes;
- /// @endcond
+ std::size_t get_max_cached_nodes() const;
+ #endif
 };
 
-//!Equality test for same type of
-//!cached_node_allocator
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+//!Equality test for same type
+//!of cached_node_allocator
 template<class T, class S, std::size_t NodesPerChunk> inline
 bool operator==(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
- const cached_node_allocator<T, S, NodesPerChunk> &alloc2)
- { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
+ const cached_node_allocator<T, S, NodesPerChunk> &alloc2);
 
-//!Inequality test for same type of
-//!cached_node_allocator
+//!Inequality test for same type
+//!of cached_node_allocator
 template<class T, class S, std::size_t NodesPerChunk> inline
 bool operator!=(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
- const cached_node_allocator<T, S, NodesPerChunk> &alloc2)
- { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
+ const cached_node_allocator<T, S, NodesPerChunk> &alloc2);
+
+#endif
 
 } //namespace interprocess {
 } //namespace boost {

Modified: branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -17,20 +17,21 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.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/list.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/allocators/detail/node_tools.hpp>
+#include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <cstddef>
 #include <cmath>
 #include <cassert>
-#include <cassert>
 
 //!\file
 //!Describes the real adaptive pool shared by many Interprocess pool allocators
@@ -39,10 +40,6 @@
 namespace interprocess {
 namespace detail {
 
-//!Pooled shared memory allocator using an smart adaptive pool. Includes
-//!a reference count but the class does not delete itself, this is
-//!responsibility of user classes. Node size (NodeSize) and the number of
-//!nodes allocated per chunk (NodesPerChunk) are known at compile time.
 template<class SegmentManagerBase>
 class private_adaptive_node_pool_impl
 {
@@ -56,19 +53,85 @@
    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_iterator multiallocation_iterator;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
 
    private:
- //This hook will be used to chain the memory chunks
- typedef typename bi::make_list_base_hook
- <bi::void_pointer<void_pointer>, bi::link_mode<bi::normal_link> >::type list_hook_t;
+ 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 chunk_info_t
- : public list_hook_t
+ :
+ public hdr_offset_holder,
+ public multiset_hook_t
    {
       //An intrusive list of free node from this chunk
       free_nodes_t free_nodes;
+ friend bool operator <(const chunk_info_t &l, const chunk_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 chunks 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_list<chunk_info_t, bi::base_hook<list_hook_t> >::type chunk_list_t;
+ typedef typename bi::make_multiset
+ <chunk_info_t, bi::base_hook<multiset_hook_t> >::type chunk_multiset_t;
+ typedef typename chunk_multiset_t::iterator chunk_iterator;
+
+ static const std::size_t MaxAlign = alignment_of<node_t>::value;
+ static const std::size_t HdrSize = ((sizeof(chunk_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_subchunk = (dividend - 1)/divisor + 1;
+ std::size_t candidate_power_of_2 =
+ upper_power_of_2(elements_per_subchunk*real_node_size + HdrOffsetSize);
+ bool overhead_satisfied = false;
+ while(!overhead_satisfied){
+ elements_per_subchunk = (candidate_power_of_2 - HdrOffsetSize)/real_node_size;
+ std::size_t overhead_size = candidate_power_of_2 - elements_per_subchunk*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_subchunks
+ (std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_chunk
+ ,std::size_t &num_subchunks, std::size_t &real_num_node)
+ {
+ std::size_t elements_per_subchunk = (alignment - HdrOffsetSize)/real_node_size;
+ std::size_t possible_num_subchunk = (elements_per_chunk - 1)/elements_per_subchunk + 1;
+ std::size_t hdr_subchunk_elements = (alignment - HdrSize - SegmentManagerBase::PayloadPerAllocation)/real_node_size;
+ while(((possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements) < elements_per_chunk){
+ ++possible_num_subchunk;
+ }
+ num_subchunks = possible_num_subchunk;
+ real_num_node = (possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements;
+ }
 
    public:
    //!Segment manager typedef
@@ -77,26 +140,25 @@
    //!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_chunk, std::size_t max_free_chunks)
- : m_node_size(node_size)
- , m_max_free_chunks(max_free_chunks)
- , m_real_node_size(lcm(m_node_size, sizeof(node_t)))
- , m_header_size(min_value(get_rounded_size(sizeof(chunk_info_t), alignment_of<max_align>::value)
- ,get_rounded_size(sizeof(chunk_info_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
- , m_real_chunk_alignment(upper_power_of_2(m_header_size + m_real_node_size*nodes_per_chunk))
+ , std::size_t nodes_per_chunk, std::size_t max_free_chunks
+ , unsigned char overhead_percent
+ )
+ : m_max_free_chunks(max_free_chunks)
+ , 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_chunk_alignment(calculate_alignment(overhead_percent, m_real_node_size))
       //This is the real number of nodes per chunk
- , m_real_num_node((m_real_chunk_alignment - SegmentManagerBase::PayloadPerAllocation - m_header_size)/m_real_node_size)
+ , m_num_subchunks(0)
+ , m_real_num_node(0)
       //General purpose allocator
    , mp_segment_mngr_base(segment_mngr_base)
- , m_chunklist()
- , m_first_free_chunk(m_chunklist.end())
- //Debug node count
- , m_allocated(0)
- , m_free_chunks(0)
- {}
+ , m_chunk_multiset()
+ , m_totally_free_chunks(0)
+ {
+ calculate_num_subchunks(m_real_chunk_alignment, m_real_node_size, nodes_per_chunk, m_num_subchunks, m_real_num_node);
+ }
 
    //!Destructor. Deallocates all allocated chunks. Never throws
    ~private_adaptive_node_pool_impl()
@@ -110,60 +172,93 @@
    { return detail::get_pointer(mp_segment_mngr_base); }
 
    //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
- void *allocate(std::size_t count)
+ void *allocate_node()
    {
- std::size_t bytes = count*m_node_size;
- if(bytes > m_real_node_size){//Normal allocation, no pooling used
- void *addr = mp_segment_mngr_base->allocate(bytes);
- if(!addr) throw bad_alloc();
- return addr;
+ priv_invariants();
+ //If there are no free nodes we allocate a new block
+ if (m_chunk_multiset.empty()){
+ priv_alloc_chunk(1);
       }
- else //Node allocation, pooling used
- return priv_alloc_node();
+ //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(void *ptr, std::size_t count)
+ void deallocate_node(void *pElem)
    {
- std::size_t bytes = count*m_node_size;
- if(bytes > m_real_node_size)//Normal allocation was used
- mp_segment_mngr_base->deallocate(ptr);
- else //Node allocation was used
- priv_dealloc_node(ptr);
+ this->priv_reinsert_nodes_in_chunk
+ (multiallocation_iterator::create_simple_range(pElem));
+ //Update free chunk count
+ if(m_totally_free_chunks > m_max_free_chunks){
+ this->priv_deallocate_free_chunks(m_max_free_chunks);
+ }
+ priv_invariants();
    }
 
    //!Allocates a singly linked list of n nodes ending in null pointer.
    //!can throw boost::interprocess::bad_alloc
- void allocate_nodes(const std::size_t n, free_nodes_t &nodes)
+ void allocate_nodes(multiallocation_chain &nodes, const std::size_t n)
    {
- std::size_t i = 0;
       try{
- for(; i < n; ++i){
- nodes.push_front(*priv_alloc_node());
+ priv_invariants();
+ for(std::size_t i = 0; i != n; ++i){
+ //If there are no free nodes we allocate all needed chunks
+ if (m_chunk_multiset.empty()){
+ priv_alloc_chunk(((n - i) - 1)/m_real_num_node + 1);
+ }
+ nodes.push_front(priv_take_first_node());
          }
       }
       catch(...){
- priv_deallocate_nodes(nodes, i);
+ this->deallocate_nodes(nodes, nodes.size());
+ this->priv_deallocate_free_chunks(m_max_free_chunks);
          throw;
       }
+ priv_invariants();
+ }
+
+ //!Allocates n nodes, pointed by the multiallocation_iterator.
+ //!Can throw boost::interprocess::bad_alloc
+ multiallocation_iterator allocate_nodes(const std::size_t n)
+ {
+ multiallocation_chain chain;
+ this->allocate_nodes(chain, n);
+ return chain.get_it();
    }
 
    //!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(free_nodes_t &nodes)
- { priv_deallocate_nodes(nodes, nodes.size()); }
+ void deallocate_nodes(multiallocation_chain &nodes)
+ {
+ this->deallocate_nodes(nodes.get_it());
+ nodes.reset();
+ }
 
    //!Deallocates the first n nodes of a linked list of nodes. Never throws
- void deallocate_nodes(free_nodes_t &nodes, std::size_t n)
- { priv_deallocate_nodes(nodes, n); }
+ void deallocate_nodes(multiallocation_chain &nodes, std::size_t n)
+ {
+ assert(nodes.size() >= n);
+ for(std::size_t i = 0; i < n; ++i){
+ this->deallocate_node(nodes.pop_front());
+ }
+ }
+
+ //!Deallocates the nodes pointed by the multiallocation iterator. Never throws
+ void deallocate_nodes(multiallocation_iterator it)
+ {
+ this->priv_reinsert_nodes_in_chunk(it);
+ if(m_totally_free_chunks > m_max_free_chunks){
+ this->priv_deallocate_free_chunks(m_max_free_chunks);
+ }
+ }
 
    void deallocate_free_chunks()
- { priv_deallocate_free_chunks(0); }
+ { this->priv_deallocate_free_chunks(0); }
 
    std::size_t num_free_nodes()
    {
- typedef typename chunk_list_t::const_iterator citerator;
+ typedef typename chunk_multiset_t::const_iterator citerator;
       std::size_t count = 0;
- citerator it (m_first_free_chunk), itend(m_chunklist.end());
+ citerator it (m_chunk_multiset.begin()), itend(m_chunk_multiset.end());
       for(; it != itend; ++it){
          count += it->free_nodes.size();
       }
@@ -172,23 +267,98 @@
 
    void swap(private_adaptive_node_pool_impl &other)
    {
+ assert(m_max_free_chunks == other.m_max_free_chunks);
+ assert(m_real_node_size == other.m_real_node_size);
+ assert(m_real_chunk_alignment == other.m_real_chunk_alignment);
+ assert(m_real_num_node == other.m_real_num_node);
       std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
- m_chunklist.swap(other.m_chunklist);
- std::swap(m_first_free_chunk, other.m_first_free_chunk);
- std::swap(m_allocated, other.m_allocated);
- std::swap(m_free_chunks, other.m_allocated);
+ std::swap(m_totally_free_chunks, other.m_totally_free_chunks);
+ m_chunk_multiset.swap(other.m_chunk_multiset);
    }
 
    private:
+ void priv_deallocate_free_chunks(std::size_t max_free_chunks)
+ {
+ priv_invariants();
+ //Now check if we've reached the free nodes limit
+ //and check if we have free chunks. If so, deallocate as much
+ //as we can to stay below the limit
+ for( chunk_iterator itend = m_chunk_multiset.end()
+ ; m_totally_free_chunks > max_free_chunks
+ ; --m_totally_free_chunks
+ ){
+ assert(!m_chunk_multiset.empty());
+ chunk_iterator it = itend;
+ --it;
+ std::size_t num_nodes = it->free_nodes.size();
+ assert(num_nodes == m_real_num_node);
+ (void)num_nodes;
+ m_chunk_multiset.erase_and_dispose
+ (it, chunk_destroyer(this));
+ }
+ }
 
- void priv_deallocate_nodes(free_nodes_t &nodes, const std::size_t num)
+ void priv_reinsert_nodes_in_chunk(multiallocation_iterator it)
+ {
+ multiallocation_iterator itend;
+ chunk_iterator chunk_it(m_chunk_multiset.end());
+ while(it != itend){
+ void *pElem = &*it;
+ ++it;
+ priv_invariants();
+ chunk_info_t *chunk_info = this->priv_chunk_from_node(pElem);
+ assert(chunk_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);
+ chunk_info->free_nodes.push_front(*to_deallocate);
+
+ chunk_iterator this_chunk(chunk_multiset_t::s_iterator_to(*chunk_info));
+ chunk_iterator next_chunk(this_chunk);
+ ++next_chunk;
+
+ //Cache the free nodes from the chunk
+ std::size_t this_chunk_free_nodes = this_chunk->free_nodes.size();
+
+ if(this_chunk_free_nodes == 1){
+ m_chunk_multiset.insert(m_chunk_multiset.begin(), *chunk_info);
+ }
+ else{
+ chunk_iterator next_chunk(this_chunk);
+ ++next_chunk;
+ if(next_chunk != chunk_it){
+ std::size_t next_free_nodes = next_chunk->free_nodes.size();
+ if(this_chunk_free_nodes > next_free_nodes){
+ //Now move the chunk to the new position
+ m_chunk_multiset.erase(this_chunk);
+ m_chunk_multiset.insert(*chunk_info);
+ }
+ }
+ }
+ //Update free chunk count
+ if(this_chunk_free_nodes == m_real_num_node){
+ ++m_totally_free_chunks;
+ }
+ priv_invariants();
+ }
+ }
+
+ node_t *priv_take_first_node()
    {
- assert(nodes.size() >= num);
- for(std::size_t i = 0; i < num; ++i){
- node_t *to_deallocate = &nodes.front();
- nodes.pop_front();
- deallocate(to_deallocate, 1);
+ assert(m_chunk_multiset.begin() != m_chunk_multiset.end());
+ //We take the first free node the multiset can't be empty
+ free_nodes_t &free_nodes = m_chunk_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_chunk_multiset.erase(m_chunk_multiset.begin());
+ }
+ else if(free_nodes_count == m_real_num_node){
+ --m_totally_free_chunks;
       }
+ priv_invariants();
+ return first_node;
    }
 
    class chunk_destroyer;
@@ -197,71 +367,75 @@
    class chunk_destroyer
    {
       public:
- chunk_destroyer(segment_manager_base_type *mngr, std::size_t real_num_node)
- : mngr_(mngr), m_real_num_node(real_num_node)
+ chunk_destroyer(const private_adaptive_node_pool_impl *impl)
+ : mp_impl(impl)
       {}
 
- void operator()(typename chunk_list_t::pointer to_deallocate)
+ void operator()(typename chunk_multiset_t::pointer to_deallocate)
       {
          std::size_t free_nodes = to_deallocate->free_nodes.size();
          (void)free_nodes;
- assert(free_nodes == m_real_num_node);
- mngr_->deallocate(detail::get_pointer(to_deallocate));
+ 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_subchunk_from_chunk((chunk_info_t*)detail::get_pointer(to_deallocate));
+ mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
       }
- segment_manager_base_type *mngr_;
- const std::size_t m_real_num_node;
+ 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
+ #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
    {
- typedef typename chunk_list_t::iterator chunk_iterator;
- //We iterate though the chunk list to free the memory
- chunk_iterator it(m_chunklist.begin()),
- itend(m_chunklist.end()), to_deallocate;
- for(++it; it != itend; ++it){
- chunk_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_chunklist.begin();
- itend = m_chunklist.end();
- std::size_t total_free = 0;
- for(; it != itend; ++it){
- total_free += it->free_nodes.size();
+ //We iterate through the chunk list to free the memory
+ chunk_iterator it(m_chunk_multiset.begin()),
+ itend(m_chunk_multiset.end()), to_deallocate;
+ if(it != itend){
+ for(++it; it != itend; ++it){
+ chunk_iterator prev(it);
+ --prev;
+ std::size_t sp = prev->free_nodes.size(),
+ si = it->free_nodes.size();
+ assert(sp <= si);
+ (void)sp; (void)si;
+ }
       }
- assert(total_free >= m_free_chunks*m_real_num_node);
 
- //Check that the total totally free chunks are correct
- it = m_chunklist.begin();
- itend = m_chunklist.end();
- total_free = 0;
- for(; it != itend; ++it){
- total_free += it->free_nodes.size() == m_real_num_node;
- }
- assert(total_free >= m_free_chunks);
-
- //The chunk pointed by m_first_free_chunk should point
- //to end or to a non-empty chunk
- if(m_first_free_chunk != m_chunklist.end()){
- std::size_t s = m_first_free_chunk->free_nodes.size();
- assert(s != 0);
+ {
+ //Check that the total free nodes are correct
+ it = m_chunk_multiset.begin();
+ itend = m_chunk_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_chunks*m_real_num_node);
       }
 
- //All previous nodes of m_first_free_chunk should be 0
- it = m_chunklist.begin();
- itend = m_first_free_chunk;
+ {
+ //Check that the total totally free chunks are correct
+ it = m_chunk_multiset.begin();
+ itend = m_chunk_multiset.end();
+ std::size_t total_free_chunks = 0;
+ for(; it != itend; ++it){
+ total_free_chunks += (it->free_nodes.size() == m_real_num_node);
+ }
+ assert(total_free_chunks == m_totally_free_chunks);
+ }
+ {
+ //Check that header offsets are correct
+ it = m_chunk_multiset.begin();
       for(; it != itend; ++it){
- std::size_t s = it->free_nodes.size();
- assert(s == 0);
+ hdr_offset_holder *hdr_off_holder = priv_first_subchunk_from_chunk(&*it);
+ for(std::size_t i = 0, max = m_num_subchunks; i < max; ++i){
+ assert(hdr_off_holder->hdr_offset == std::size_t((char*)&*it- (char*)hdr_off_holder));
+ assert(0 == ((std::size_t)hdr_off_holder & (m_real_chunk_alignment - 1)));
+ assert(0 == (hdr_off_holder->hdr_offset & (m_real_chunk_alignment - 1)));
+ hdr_off_holder = (hdr_offset_holder *)((char*)hdr_off_holder + m_real_chunk_alignment);
+ }
+ }
       }
    }
    #else
@@ -271,165 +445,115 @@
    //!Deallocates all used memory. Never throws
    void priv_clear()
    {
- //Check for memory leaks
- assert(m_allocated==0);
- priv_invariants();
- m_first_free_chunk = m_chunklist.end();
- m_chunklist.clear_and_dispose
- (chunk_destroyer(detail::get_pointer(mp_segment_mngr_base), m_real_num_node));
- m_free_chunks = 0;
- }
-
- chunk_info_t *priv_chunk_from_node(void *node)
- {
- return (chunk_info_t *)((std::size_t)node & std::size_t(~(m_real_chunk_alignment - 1)));
- }
-
- //!Allocates one node, using the adaptive pool algorithm.
- //!Never throws
- node_t *priv_alloc_node()
- {
- priv_invariants();
- //If there are no free nodes we allocate a new block
- if (m_first_free_chunk == m_chunklist.end()){
- priv_alloc_chunk();
- --m_first_free_chunk;
- }
- //We take the first free node since m_first_free_chunk can't be end()
- chunk_info_t &chunk_info = *m_first_free_chunk;
- assert(!chunk_info.free_nodes.empty());
- node_t *first_node = &chunk_info.free_nodes.front();
- if(chunk_info.free_nodes.size() == 1){
- ++m_first_free_chunk;
- }
- else if(chunk_info.free_nodes.size() == m_real_num_node){
- --m_free_chunks;
- }
- chunk_info.free_nodes.pop_front();
- ++m_allocated;
- priv_invariants();
- return detail::get_pointer(first_node);
- }
-
- //!Deallocates one node, using the adaptive pool algorithm.
- //!Never throws
- void priv_dealloc_node(void *pElem)
- {
- typedef typename chunk_list_t::iterator chunk_iterator;
- priv_invariants();
- chunk_info_t *chunk_info = priv_chunk_from_node(pElem);
- assert(chunk_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);
- chunk_info->free_nodes.push_front(*to_deallocate);
- chunk_iterator this_chunk(chunk_list_t::s_iterator_to(*chunk_info));
- chunk_iterator next_chunk(this_chunk);
- ++next_chunk;
-
- //If this chunk has more free nodes than the next ones,
- //we have to move the chunk in the list to maintain it ordered.
- //Check if we have to move it
- while(next_chunk != m_chunklist.end() &&
- this_chunk->free_nodes.size() > next_chunk->free_nodes.size()){
- ++next_chunk;
- }
- //Check if the chunk must be moved
- if(++chunk_iterator(this_chunk) != next_chunk){
- //Update m_first_free_chunk iterator if it was pointing to this_chunk
- if(m_first_free_chunk == this_chunk){
- ++m_first_free_chunk;
- }
- //Update m_first_free_chunk if the moved chunk crosses the empty boundary
- else if(this_chunk->free_nodes.size() == 1){
- m_first_free_chunk = chunk_list_t::s_iterator_to(*chunk_info);
- }
- //Now move the chunk to the new position
- m_chunklist.erase(this_chunk);
- m_chunklist.insert(next_chunk, *chunk_info);
- }
- //Update m_first_free_chunk if the chunk crosses the empty boundary
- else if(this_chunk->free_nodes.size() == 1){
- --m_first_free_chunk;
- }
-
- if(this_chunk->free_nodes.size() == m_real_num_node){
- ++m_free_chunks;
+ #ifndef NDEBUG
+ chunk_iterator it = m_chunk_multiset.begin();
+ chunk_iterator itend = m_chunk_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(m_allocated>0);
- --m_allocated;
+ assert(num_free_nodes == m_totally_free_chunks);
+ #endif
       priv_invariants();
- priv_deallocate_free_chunks(m_max_free_chunks);
- priv_invariants();
- }
-
- void priv_deallocate_free_chunks(std::size_t max_free_chunks)
- {
- typedef typename chunk_list_t::iterator chunk_iterator;
- //Now check if we've reached the free nodes limit
- //and check if we have free chunks. If so, deallocate as much
- //as we can to stay below the limit
- while(m_free_chunks > max_free_chunks &&
- m_chunklist.back().free_nodes.size() == m_real_num_node){
- chunk_iterator it(--m_chunklist.end());
- if(it == m_first_free_chunk)
- ++m_first_free_chunk; //m_first_free_chunk is now equal to end()
- m_chunklist.erase_and_dispose(it, chunk_destroyer(detail::get_pointer(mp_segment_mngr_base),m_real_num_node));
- --m_free_chunks;
- }
- }
-
- //!Allocates a chunk of nodes. Can throw boost::interprocess::bad_alloc
- void priv_alloc_chunk()
- {
- //We allocate a new NodeBlock and put it as first
- //element in the free Node list
- std::size_t real_chunk_size = m_real_chunk_alignment - SegmentManagerBase::PayloadPerAllocation;
- char *pNode = detail::char_ptr_cast
- (mp_segment_mngr_base->allocate_aligned(real_chunk_size, m_real_chunk_alignment));
- if(!pNode) throw bad_alloc();
- chunk_info_t *c_info = new(pNode)chunk_info_t;
- m_chunklist.push_back(*c_info);
-
- pNode += m_header_size;
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- for(std::size_t i = 0; i < m_real_num_node; ++i){
- c_info->free_nodes.push_front(*new (pNode) node_t);
- pNode += m_real_node_size;
+ m_chunk_multiset.clear_and_dispose
+ (chunk_destroyer(this));
+ m_totally_free_chunks = 0;
+ }
+
+ chunk_info_t *priv_chunk_from_node(void *node) const
+ {
+ hdr_offset_holder *hdr_off_holder =
+ (hdr_offset_holder*)((std::size_t)node & std::size_t(~(m_real_chunk_alignment - 1)));
+ assert(0 == ((std::size_t)hdr_off_holder & (m_real_chunk_alignment - 1)));
+ assert(0 == (hdr_off_holder->hdr_offset & (m_real_chunk_alignment - 1)));
+ chunk_info_t *chunk = (chunk_info_t *)(((char*)hdr_off_holder) + hdr_off_holder->hdr_offset);
+ assert(chunk->hdr_offset == 0);
+ return chunk;
+ }
+
+ hdr_offset_holder *priv_first_subchunk_from_chunk(chunk_info_t *chunk) const
+ {
+ hdr_offset_holder *hdr_off_holder = (hdr_offset_holder*)
+ (((char*)chunk) - (m_num_subchunks-1)*m_real_chunk_alignment);
+ assert(hdr_off_holder->hdr_offset == std::size_t((char*)chunk - (char*)hdr_off_holder));
+ assert(0 == ((std::size_t)hdr_off_holder & (m_real_chunk_alignment - 1)));
+ assert(0 == (hdr_off_holder->hdr_offset & (m_real_chunk_alignment - 1)));
+ return hdr_off_holder;
+ }
+
+ //!Allocates a several chunks of nodes. Can throw boost::interprocess::bad_alloc
+ void priv_alloc_chunk(std::size_t n)
+ {
+ std::size_t real_chunk_size = m_real_chunk_alignment*m_num_subchunks - SegmentManagerBase::PayloadPerAllocation;
+ std::size_t elements_per_subchunk = (m_real_chunk_alignment - HdrOffsetSize)/m_real_node_size;
+ std::size_t hdr_subchunk_elements = (m_real_chunk_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 = detail::char_ptr_cast
+ (mp_segment_mngr_base->allocate_aligned(real_chunk_size, m_real_chunk_alignment));
+ if(!mem_address) throw std::bad_alloc();
+ ++m_totally_free_chunks;
+
+ //First initialize header information on the last subchunk
+ char *hdr_addr = mem_address + m_real_chunk_alignment*(m_num_subchunks-1);
+ chunk_info_t *c_info = new(hdr_addr)chunk_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 subchunk = 0, maxsubchunk = m_num_subchunks - 1
+ ; subchunk < maxsubchunk
+ ; ++subchunk, mem_address += m_real_chunk_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_subchunk; ++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_subchunk_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 chunk after the free node list is full
+ m_chunk_multiset.insert(m_chunk_multiset.end(), *c_info);
       }
- ++m_free_chunks;
    }
 
    private:
    typedef typename pointer_to_other
       <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
 
- const std::size_t m_node_size;
    const std::size_t m_max_free_chunks;
    const std::size_t m_real_node_size;
- const std::size_t m_header_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_chunk_alignment;
+ std::size_t m_num_subchunks;
    //This is the real number of nodes per chunk
- const std::size_t m_real_num_node;
+ //const
+ std::size_t m_real_num_node;
    segment_mngr_base_ptr_t mp_segment_mngr_base;//Segment manager
- chunk_list_t m_chunklist; //Intrusive chunk list
- typename chunk_list_t::iterator m_first_free_chunk; //Iterator to the active chunk
- std::size_t m_allocated; //Used nodes for debugging
- std::size_t m_free_chunks; //Free chunks
+ chunk_multiset_t m_chunk_multiset; //Intrusive chunk list
+ std::size_t m_totally_free_chunks; //Free chunks
 };
 
-//!Pooled shared memory allocator using an smart adaptive pool. Includes
-//!a reference count but the class does not delete itself, this is
-//!responsibility of user classes. Node size (NodeSize) and the number of
-//!nodes allocated per chunk (NodesPerChunk) are known at compile time.
 template< class SegmentManager
         , std::size_t NodeSize
         , std::size_t NodesPerChunk
         , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
>
 class private_adaptive_node_pool
    : public private_adaptive_node_pool_impl
@@ -448,8 +572,8 @@
    static const std::size_t nodes_per_chunk = NodesPerChunk;
 
    //!Constructor from a segment manager. Never throws
- private_adaptive_node_pool(segment_manager *segmeng_mngr)
- : base_t(segmeng_mngr, NodeSize, NodesPerChunk, MaxFreeChunks)
+ private_adaptive_node_pool(segment_manager *segment_mngr)
+ : base_t(segment_mngr, NodeSize, NodesPerChunk, MaxFreeChunks, OverheadPercent)
    {}
 
    //!Returns the segment manager. Never throws
@@ -462,117 +586,25 @@
 //!responsibility of user classes. Node size (NodeSize) and the number of
 //!nodes allocated per chunk (NodesPerChunk) are known at compile time
 template< class SegmentManager
- , class Mutex
         , std::size_t NodeSize
         , std::size_t NodesPerChunk
         , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
>
 class shared_adaptive_node_pool
- : public private_adaptive_node_pool
- <SegmentManager, NodeSize, NodesPerChunk, MaxFreeChunks>
+ : public detail::shared_pool_impl
+ < private_adaptive_node_pool
+ <SegmentManager, NodeSize, NodesPerChunk, MaxFreeChunks, OverheadPercent>
+ >
 {
- private:
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef private_adaptive_node_pool
- <SegmentManager,
- NodeSize, NodesPerChunk, MaxFreeChunks> private_node_allocator_t;
- public:
- //!Segment manager typedef
- typedef SegmentManager segment_manager;
- typedef typename private_node_allocator_t::free_nodes_t free_nodes_t;
-
- //!Constructor from a segment manager. Never throws
- shared_adaptive_node_pool(segment_manager *segment_mgnr)
- : private_node_allocator_t(segment_mgnr){}
-
- //!Destructor. Deallocates all allocated chunks. Never throws
- ~shared_adaptive_node_pool()
+ typedef detail::shared_pool_impl
+ < private_adaptive_node_pool
+ <SegmentManager, NodeSize, NodesPerChunk, MaxFreeChunks, OverheadPercent>
+ > base_t;
+ public:
+ shared_adaptive_node_pool(SegmentManager *segment_mgnr)
+ : base_t(segment_mgnr)
    {}
-
- //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
- void *allocate(std::size_t count)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- return private_node_allocator_t::allocate(count);
- }
-
- //!Deallocates an array pointed by ptr. Never throws
- void deallocate(void *ptr, std::size_t count)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate(ptr, count);
- }
-
- //!Allocates a singly linked list of n nodes ending in null pointer.
- //!can throw boost::interprocess::bad_alloc
- void allocate_nodes(std::size_t n, free_nodes_t &nodes)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- return private_node_allocator_t::allocate_nodes(n, nodes);
- }
-
- //!Deallocates a linked list of nodes ending in null pointer. Never throws
- void deallocate_nodes(free_nodes_t &nodes, std::size_t num)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_nodes(nodes, num);
- }
-
- //!Deallocates a linked list of nodes ending in null pointer. Never throws
- void deallocate_nodes(free_nodes_t &nodes)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_nodes(nodes);
- }
-
- //!Deallocates all the free chunks of memory. Never throws
- void deallocate_free_chunks()
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_free_chunks();
- }
-
- //!Increments internal reference count and returns new count. Never throws
- std::size_t inc_ref_count()
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- return ++m_header.m_usecount;
- }
-
- //!Decrements internal reference count and returns new count. Never throws
- std::size_t dec_ref_count()
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- assert(m_header.m_usecount > 0);
- return --m_header.m_usecount;
- }
-
- private:
- //!This struct includes needed data and derives from
- //!interprocess_mutex to allow EBO when using null_mutex
- struct header_t : Mutex
- {
- std::size_t m_usecount; //Number of attached allocators
-
- header_t()
- : m_usecount(0) {}
- } m_header;
 };
 
 } //namespace detail {

Modified: branches/release/boost/interprocess/allocators/detail/node_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/node_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/node_pool.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -24,7 +24,9 @@
 #include <boost/intrusive/slist.hpp>
 #include <boost/math/common_factor_ct.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/allocators/detail/allocator_common.hpp>
 #include <cstddef>
 #include <functional>
 #include <algorithm>
@@ -51,10 +53,14 @@
    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_iterator multiallocation_iterator;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
 
    private:
- typedef typename bi::make_slist < node_t, bi::base_hook<slist_hook_t>
- , bi::constant_time_size<false> >::type chunkslist_t;
+ typedef typename bi::make_slist
+ < node_t, bi::base_hook<slist_hook_t>
+ , bi::linear<true>
+ , bi::constant_time_size<false> >::type chunkslist_t;
    public:
 
    //!Segment manager typedef
@@ -62,10 +68,8 @@
 
    //!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_chunk)
- : m_node_size(node_size)
- , m_nodes_per_chunk(nodes_per_chunk)
- , m_real_node_size(detail::lcm(node_size, sizeof(node_t)))
- , m_block_size(detail::get_rounded_size(m_real_node_size*m_nodes_per_chunk, sizeof(node_t)))
+ : m_nodes_per_chunk(nodes_per_chunk)
+ , 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_chunklist()
@@ -76,7 +80,7 @@
 
    //!Destructor. Deallocates all allocated chunks. Never throws
    ~private_node_pool_impl()
- { priv_clear(); }
+ { this->purge_chunks(); }
 
    std::size_t get_real_num_node() const
    { return m_nodes_per_chunk; }
@@ -86,116 +90,91 @@
    { return detail::get_pointer(mp_segment_mngr_base); }
 
    //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
- void *allocate(std::size_t count)
+ void *allocate_node()
    {
- std::size_t bytes = count*m_node_size;
- if(bytes > m_real_node_size){//Normal allocation, no pooling used
- void *addr = mp_segment_mngr_base->allocate(bytes);
- if(!addr) throw bad_alloc();
- return addr;
- }
- else //Node allocation, pooling used
- return priv_alloc_node();
+ //If there are no free nodes we allocate a new block
+ if (m_freelist.empty())
+ priv_alloc_chunk();
+ //We take the first free node
+ node_t *n = (node_t*)&m_freelist.front();
+ m_freelist.pop_front();
+ ++m_allocated;
+ return n;
    }
    
    //!Deallocates an array pointed by ptr. Never throws
- void deallocate(void *ptr, std::size_t count)
+ void deallocate_node(void *ptr)
    {
- std::size_t bytes = count*m_node_size;
- if(bytes > m_real_node_size)//Normal allocation was used
- mp_segment_mngr_base->deallocate(ptr);
- else //Node allocation was used
- priv_dealloc_node(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.
+ //!Allocates a singly linked list of n nodes ending in null pointer and pushes them in the chain.
    //!can throw boost::interprocess::bad_alloc
- void allocate_nodes(const std::size_t n, free_nodes_t &nodes)
+ void allocate_nodes(multiallocation_chain &nodes, const std::size_t n)
    {
       std::size_t i = 0;
       try{
          for(; i < n; ++i){
- nodes.push_front(*priv_alloc_node());
+ nodes.push_front(this->allocate_node());
          }
       }
       catch(...){
- priv_deallocate_nodes(nodes, i);
+ this->deallocate_nodes(nodes, i);
          throw;
       }
    }
 
- //!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(free_nodes_t &nodes)
- { priv_deallocate_nodes(nodes, nodes.size()); }
-
- //!Deallocates the first n nodes of a linked list of nodes. Never throws
- void deallocate_nodes(free_nodes_t &nodes, std::size_t n)
- { priv_deallocate_nodes(nodes, n); }
-
- //!Deallocates all the free chunks of memory. Never throws
- void deallocate_free_chunks()
- { priv_deallocate_free_chunks(); }
-
- std::size_t num_free_nodes()
- { return m_freelist.size(); }
-
- void swap(private_node_pool_impl &other)
+ //!Allocates a singly linked list of n nodes ending in null pointer
+ //!can throw boost::interprocess::bad_alloc
+ multiallocation_iterator allocate_nodes(const std::size_t n)
    {
- std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
- m_chunklist.swap(other.m_chunklist);
- m_freelist.swap(other.m_freelist);
- std::swap(m_allocated, other.m_allocated);
+ 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 nodes.get_it();
    }
 
- private:
+ //!Deallocates a linked list of nodes. Never throws
+ void deallocate_nodes(multiallocation_chain &nodes)
+ {
+ this->deallocate_nodes(nodes.get_it());
+ nodes.reset();
+ }
 
- void priv_deallocate_nodes(free_nodes_t &nodes, const std::size_t num)
+ //!Deallocates the first n nodes of a linked list of nodes. Never throws
+ void deallocate_nodes(multiallocation_chain &nodes, std::size_t num)
    {
       assert(nodes.size() >= num);
       for(std::size_t i = 0; i < num; ++i){
- node_t *to_deallocate = &nodes.front();
- nodes.pop_front();
- deallocate(to_deallocate, 1);
+ deallocate_node(nodes.pop_front());
       }
    }
 
- 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>
+ //!Deallocates the nodes pointed by the multiallocation iterator. Never throws
+ void deallocate_nodes(multiallocation_iterator it)
    {
- is_between(const void *addr, std::size_t size)
- : beg_((const char *)addr), end_(beg_+size)
- {}
-
- bool operator()(typename free_nodes_t::const_reference v) const
- {
- return (beg_ <= (const char *)&v &&
- end_ > (const char *)&v);
+ multiallocation_iterator itend;
+ while(it != itend){
+ void *addr = &*it;
+ ++it;
+ deallocate_node(addr);
       }
- private:
- const char * beg_;
- const char * end_;
- };
+ }
 
- void priv_deallocate_free_chunks()
+ //!Deallocates all the free chunks of memory. Never throws
+ void deallocate_free_chunks()
    {
       typedef typename free_nodes_t::iterator nodelist_iterator;
       typename chunkslist_t::iterator bit(m_chunklist.before_begin()),
@@ -204,16 +183,19 @@
       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_chunk, alignment_of<node_t>::value);
+
       while(it != itend){
          //Collect all the nodes from the chunk 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_chunk_from_hook(&*it);
+ const void *addr = get_chunk_from_hook(&*it, blocksize);
 
- //Execute the algorithm and get an iterator to the last value
          m_freelist.remove_and_dispose_if
- (is_between(addr, m_block_size), push_in_list(free_nodes, last_it));
+ (is_between(addr, blocksize), push_in_list(free_nodes, last_it));
 
          //If the number of nodes is equal to m_nodes_per_chunk
          //this means that the block can be deallocated
@@ -253,57 +235,88 @@
          , backup_list.size());
    }
 
- //!Deallocates all used memory. Never throws
- void priv_clear()
+ 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_chunks()
    {
       //check for memory leaks
       assert(m_allocated==0);
-
+ std::size_t blocksize = detail::get_rounded_size
+ (m_real_node_size*m_nodes_per_chunk, alignment_of<node_t>::value);
       typename chunkslist_t::iterator
          it(m_chunklist.begin()), itend(m_chunklist.end()), aux;
 
       //We iterate though the NodeBlock list to free the memory
       while(!m_chunklist.empty()){
- void *addr = get_chunk_from_hook(&m_chunklist.front());
+ void *addr = get_chunk_from_hook(&m_chunklist.front(), blocksize);
          m_chunklist.pop_front();
          mp_segment_mngr_base->deallocate(addr);
- }
+ }
+ //Just clear free node list
+ m_freelist.clear();
    }
 
- //!Allocates one node, using single segregated storage algorithm.
- //!Never throws
- node_t *priv_alloc_node()
+ void swap(private_node_pool_impl &other)
    {
- //If there are no free nodes we allocate a new block
- if (m_freelist.empty())
- priv_alloc_chunk();
- //We take the first free node
- node_t *n = (node_t*)&m_freelist.front();
- m_freelist.pop_front();
- ++m_allocated;
- return n;
+ std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+ m_chunklist.swap(other.m_chunklist);
+ m_freelist.swap(other.m_freelist);
+ std::swap(m_allocated, other.m_allocated);
    }
 
- //!Deallocates one node, using single segregated storage algorithm.
- //!Never throws
- void priv_dealloc_node(void *pElem)
+ private:
+
+ struct push_in_list
    {
- //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;
- }
+ 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_((const char *)addr), end_(beg_+size)
+ {}
+
+ bool operator()(typename free_nodes_t::const_reference v) const
+ {
+ return (beg_ <= (const char *)&v &&
+ end_ > (const char *)&v);
+ }
+ private:
+ const char * beg_;
+ const char * end_;
+ };
 
    //!Allocates a chunk of nodes. Can throw boost::interprocess::bad_alloc
    void priv_alloc_chunk()
    {
       //We allocate a new NodeBlock and put it as first
       //element in the free Node list
- char *pNode = detail::char_ptr_cast(mp_segment_mngr_base->allocate(m_block_size + sizeof(node_t)));
+ std::size_t blocksize =
+ detail::get_rounded_size(m_real_node_size*m_nodes_per_chunk, alignment_of<node_t>::value);
+ char *pNode = detail::char_ptr_cast
+ (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
       if(!pNode) throw bad_alloc();
       char *pBlock = pNode;
- m_chunklist.push_front(get_chunk_hook(pBlock));
+ m_chunklist.push_front(get_chunk_hook(pBlock, blocksize));
 
       //We initialize all Nodes in Node Block to insert
       //them in the free Node list
@@ -314,26 +327,24 @@
 
    private:
    //!Returns a reference to the chunk hook placed in the end of the chunk
- inline node_t & get_chunk_hook (void *chunk)
+ static inline node_t & get_chunk_hook (void *chunk, std::size_t blocksize)
    {
       return *static_cast<node_t*>(
- static_cast<void*>((detail::char_ptr_cast(chunk)+m_block_size)));
+ static_cast<void*>((detail::char_ptr_cast(chunk) + blocksize)));
    }
 
    //!Returns the starting address of the chunk reference to the chunk hook placed in the end of the chunk
- inline void *get_chunk_from_hook (node_t *hook)
+ inline void *get_chunk_from_hook (node_t *hook, std::size_t blocksize)
    {
- return static_cast<void*>((detail::char_ptr_cast(hook) - m_block_size));
+ return static_cast<void*>((detail::char_ptr_cast(hook) - blocksize));
    }
 
    private:
    typedef typename pointer_to_other
       <void_pointer, segment_manager_base_type>::type segment_mngr_base_ptr_t;
 
- const std::size_t m_node_size;
    const std::size_t m_nodes_per_chunk;
    const std::size_t m_real_node_size;
- const std::size_t m_block_size;
    segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
    chunkslist_t m_chunklist; //Intrusive container of chunks
    free_nodes_t m_freelist; //Intrusive container of free nods
@@ -376,114 +387,28 @@
 //!a reference count but the class does not delete itself, this is
 //!responsibility of user classes. Node size (NodeSize) and the number of
 //!nodes allocated per chunk (NodesPerChunk) are known at compile time
+//!Pooled shared memory allocator using adaptive pool. Includes
+//!a reference count but the class does not delete itself, this is
+//!responsibility of user classes. Node size (NodeSize) and the number of
+//!nodes allocated per chunk (NodesPerChunk) are known at compile time
 template< class SegmentManager
- , class Mutex
         , std::size_t NodeSize
         , std::size_t NodesPerChunk
>
 class shared_node_pool
- : public private_node_pool<SegmentManager, NodeSize, NodesPerChunk>
+ : public detail::shared_pool_impl
+ < private_node_pool
+ <SegmentManager, NodeSize, NodesPerChunk>
+ >
 {
- private:
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef private_node_pool
- <SegmentManager, NodeSize, NodesPerChunk> private_node_allocator_t;
-
+ typedef detail::shared_pool_impl
+ < private_node_pool
+ <SegmentManager, NodeSize, NodesPerChunk>
+ > base_t;
    public:
- typedef SegmentManager segment_manager;
- typedef typename private_node_allocator_t::free_nodes_t free_nodes_t;
-
- //!Constructor from a segment manager. Never throws
- shared_node_pool(segment_manager *segment_mngr)
- : private_node_allocator_t(segment_mngr){}
-
- //!Destructor. Deallocates all allocated chunks. Never throws
- ~shared_node_pool()
+ shared_node_pool(SegmentManager *segment_mgnr)
+ : base_t(segment_mgnr)
    {}
-
- //!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
- void *allocate(std::size_t count)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- return private_node_allocator_t::allocate(count);
- }
-
- //!Deallocates an array pointed by ptr. Never throws
- void deallocate(void *ptr, std::size_t count)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate(ptr, count);
- }
-
- //!Allocates a singly linked list of n nodes ending in null pointer.
- //!can throw boost::interprocess::bad_alloc
- void allocate_nodes(const std::size_t n, free_nodes_t &nodes)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::allocate_nodes(n, nodes);
- }
-
- //!Deallocates a linked list of nodes ending in null pointer. Never throws
- void deallocate_nodes(free_nodes_t &nodes, std::size_t n)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_nodes(nodes, n);
- }
-
- void deallocate_nodes(free_nodes_t &nodes)
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_nodes(nodes);
- }
-
- //!Deallocates all the free chunks of memory. Never throws
- void deallocate_free_chunks()
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- private_node_allocator_t::deallocate_free_chunks();
- }
-
- //!Increments internal reference count and returns new count. Never throws
- std::size_t inc_ref_count()
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- return ++m_header.m_usecount;
- }
-
- //!Decrements internal reference count and returns new count. Never throws
- std::size_t dec_ref_count()
- {
- //-----------------------
- boost::interprocess::scoped_lock<Mutex> guard(m_header);
- //-----------------------
- assert(m_header.m_usecount > 0);
- return --m_header.m_usecount;
- }
-
- private:
- //!This struct includes needed data and derives from
- //!interprocess_mutex to allow EBO when using null_mutex
- struct header_t : Mutex
- {
- std::size_t m_usecount; //Number of attached allocators
-
- header_t()
- : m_usecount(0) {}
- } m_header;
 };
 
 } //namespace detail {

Modified: branches/release/boost/interprocess/allocators/detail/node_tools.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/detail/node_tools.hpp (original)
+++ branches/release/boost/interprocess/allocators/detail/node_tools.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2008. 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)
 //
@@ -37,7 +37,8 @@
       : public slist_hook_t
    {};
 
- typedef typename bi::make_slist<node_t, bi::base_hook<slist_hook_t> >::type node_slist_t;
+ typedef typename bi::make_slist
+ <node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
 };
 
 } //namespace detail {

Modified: branches/release/boost/interprocess/allocators/node_allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/node_allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/node_allocator.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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,8 +8,8 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-#ifndef BOOST_INTERPROCESS_POOLED_NODE_ALLOCATOR_HPP
-#define BOOST_INTERPROCESS_POOLED_NODE_ALLOCATOR_HPP
+#ifndef BOOST_INTERPROCESS_NODE_ALLOCATOR_HPP
+#define BOOST_INTERPROCESS_NODE_ALLOCATOR_HPP
 
 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
 # pragma once
@@ -22,9 +22,10 @@
 #include <boost/assert.hpp>
 #include <boost/utility/addressof.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/allocators/detail/node_pool.hpp>
 #include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/allocators/detail/allocator_common.hpp>
 #include <memory>
 #include <algorithm>
 #include <cstddef>
@@ -35,6 +36,177 @@
 namespace boost {
 namespace interprocess {
 
+/// @cond
+
+namespace detail{
+
+template < unsigned int Version
+ , class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ >
+class node_allocator_base
+ : public node_pool_allocation_impl
+ < node_allocator_base
+ < Version, T, SegmentManager, NodesPerChunk>
+ , Version
+ , T
+ , SegmentManager
+ >
+{
+ public:
+ typedef typename SegmentManager::void_pointer void_pointer;
+ typedef SegmentManager segment_manager;
+ typedef node_allocator_base
+ <Version, T, SegmentManager, NodesPerChunk> self_t;
+ typedef detail::shared_node_pool
+ < SegmentManager, sizeof(T), NodesPerChunk> node_pool_t;
+ typedef typename detail::
+ pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
+
+ BOOST_STATIC_ASSERT((Version <=2));
+
+ public:
+ //-------
+ typedef typename detail::
+ pointer_to_other<void_pointer, T>::type pointer;
+ typedef typename detail::
+ pointer_to_other<void_pointer, const T>::type const_pointer;
+ typedef T value_type;
+ typedef typename detail::add_reference
+ <value_type>::type reference;
+ typedef typename detail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef detail::version_type<node_allocator_base, Version> version;
+ typedef transform_iterator
+ < typename SegmentManager::
+ multiallocation_iterator
+ , detail::cast_functor <T> > multiallocation_iterator;
+ typedef typename SegmentManager::
+ multiallocation_chain multiallocation_chain;
+
+ //!Obtains node_allocator_base from
+ //!node_allocator_base
+ template<class T2>
+ struct rebind
+ {
+ typedef node_allocator_base<Version, T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ /// @cond
+ private:
+ //!Not assignable from related node_allocator_base
+ template<unsigned int Version2, class T2, class SegmentManager2, std::size_t N2>
+ node_allocator_base& operator=
+ (const node_allocator_base<Version2, T2, SegmentManager2, N2>&);
+
+ //!Not assignable from other node_allocator_base
+ node_allocator_base& operator=(const node_allocator_base&);
+ /// @endcond
+
+ public:
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ node_allocator_base(segment_manager *segment_mngr)
+ : mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(segment_mngr)) { }
+
+ //!Copy constructor from other node_allocator_base. Increments the reference
+ //!count of the associated node pool. Never throws
+ node_allocator_base(const node_allocator_base &other)
+ : mp_node_pool(other.get_node_pool())
+ {
+ mp_node_pool->inc_ref_count();
+ }
+
+ //!Copy constructor from related node_allocator_base. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ template<class T2>
+ node_allocator_base
+ (const node_allocator_base<Version, T2, SegmentManager, NodesPerChunk> &other)
+ : mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(other.get_segment_manager())) { }
+
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
+ ~node_allocator_base()
+ { detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); }
+
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ node_pool_t* get_node_pool() const
+ { return detail::get_pointer(mp_node_pool); }
+
+ //!Returns the segment manager.
+ //!Never throws
+ segment_manager* get_segment_manager()const
+ { return mp_node_pool->get_segment_manager(); }
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2)
+ { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
+
+ /// @cond
+ private:
+ node_pool_ptr mp_node_pool;
+ /// @endcond
+};
+
+//!Equality test for same type
+//!of node_allocator_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
+bool operator==(const node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
+ const node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+ { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
+
+//!Inequality test for same type
+//!of node_allocator_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
+ const node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+ { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk = 64
+ >
+class node_allocator_v1
+ : public node_allocator_base
+ < 1
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ >
+{
+ public:
+ typedef detail::node_allocator_base
+ < 1, T, SegmentManager, NodesPerChunk> base_t;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef node_allocator_v1<T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ node_allocator_v1(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ node_allocator_v1
+ (const node_allocator_v1<T2, SegmentManager, NodesPerChunk> &other)
+ : base_t(other)
+ {}
+};
+
+} //namespace detail{
+
+/// @endcond
+
 //!An STL node allocator that uses a segment manager as memory
 //!source. The internal pointer type will of the same type (raw, smart) as
 //!"typename SegmentManager::void_pointer" type. This allows
@@ -43,25 +215,49 @@
 //!of node_allocator with equal sizeof(T) placed in the same segment
 //!group. NodesPerChunk is the number of nodes allocated at once when the allocator
 //!needs runs out of nodes
-template<class T, class SegmentManager, std::size_t NodesPerChunk>
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ >
 class node_allocator
+ /// @cond
+ : public detail::node_allocator_base
+ < 2
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ >
+ /// @endcond
 {
+
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ typedef detail::node_allocator_base
+ < 2, T, SegmentManager, NodesPerChunk> base_t;
    public:
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const void>::type cvoid_pointer;
- typedef SegmentManager segment_manager;
- typedef typename SegmentManager::
- mutex_family::mutex_type mutex_type;
- typedef node_allocator
- <T, SegmentManager, NodesPerChunk> self_t;
+ typedef detail::version_type<node_allocator, 2> version;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef node_allocator<T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ node_allocator(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
 
+ template<class T2>
+ node_allocator
+ (const node_allocator<T2, SegmentManager, NodesPerChunk> &other)
+ : base_t(other)
+ {}
+
+ #else //BOOST_INTERPROCESS_DOXYGEN_INVOKED
    public:
- //-------
- typedef typename detail::
- pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const T>::type const_pointer;
+ typedef implementation_defined::segment_manager segment_manager;
+ typedef segment_manager::void_pointer void_pointer;
+ typedef implementation_defined::pointer pointer;
+ typedef implementation_defined::const_pointer const_pointer;
    typedef T value_type;
    typedef typename detail::add_reference
                      <value_type>::type reference;
@@ -69,225 +265,170 @@
                      <const value_type>::type const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
- typedef detail::shared_node_pool
- < SegmentManager, mutex_type
- , sizeof(T), NodesPerChunk> node_pool_t;
- typedef typename detail::
- pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
 
- //!Obtains node_allocator from other
+ //!Obtains node_allocator from
    //!node_allocator
    template<class T2>
    struct rebind
    {
- typedef node_allocator<T2, SegmentManager, NodesPerChunk> other;
+ typedef node_allocator<T2, SegmentManager, NodesPerChunk> other;
    };
 
- /// @cond
    private:
- //!Not assignable from related
- //!node_allocator
+ //!Not assignable from
+ //!related node_allocator
    template<class T2, class SegmentManager2, std::size_t N2>
    node_allocator& operator=
       (const node_allocator<T2, SegmentManager2, N2>&);
 
- //!Not assignable from other
- //!node_allocator
+ //!Not assignable from
+ //!other node_allocator
    node_allocator& operator=(const node_allocator&);
- /// @endcond
 
    public:
-
    //!Constructor from a segment manager. If not present, constructs a node
    //!pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
- node_allocator(segment_manager *segment_mngr)
- : mp_node_pool(priv_get_or_create(segment_mngr))
- {}
+ node_allocator(segment_manager *segment_mngr);
 
    //!Copy constructor from other node_allocator. Increments the reference
    //!count of the associated node pool. Never throws
- node_allocator(const node_allocator &other)
- : mp_node_pool(other.get_node_pool())
- { mp_node_pool->inc_ref_count(); }
+ node_allocator(const node_allocator &other);
 
    //!Copy constructor from related node_allocator. If not present, constructs
    //!a node pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
    template<class T2>
    node_allocator
- (const node_allocator<T2, SegmentManager, NodesPerChunk> &other)
- : mp_node_pool(priv_get_or_create(other.get_segment_manager()))
- {}
+ (const node_allocator<T2, SegmentManager, NodesPerChunk> &other);
 
    //!Destructor, removes node_pool_t from memory
    //!if its reference count reaches to zero. Never throws
- ~node_allocator()
- { priv_destroy_if_last_link(); }
+ ~node_allocator();
 
    //!Returns a pointer to the node pool.
    //!Never throws
- node_pool_t* get_node_pool() const
- { return detail::get_pointer(mp_node_pool); }
+ node_pool_t* get_node_pool() const;
 
    //!Returns the segment manager.
    //!Never throws
- segment_manager* get_segment_manager()const
- { return mp_node_pool->get_segment_manager(); }
+ segment_manager* get_segment_manager()const;
 
- //!Returns the number of elements that could be allocated. Never throws
- size_type max_size() const
- { return this->get_segment_manager()->get_size()/sizeof(value_type); }
+ //!Returns the number of elements that could be allocated.
+ //!Never throws
+ size_type max_size() const;
 
    //!Allocate memory for an array of count elements.
    //!Throws boost::interprocess::bad_alloc if there is no enough memory
- pointer allocate(size_type count, cvoid_pointer = 0)
- {
- if(count > ((size_type)-1)/sizeof(value_type))
- throw bad_alloc();
- return pointer(static_cast<T*>(mp_node_pool->allocate(count)));
- }
+ pointer allocate(size_type count, cvoid_pointer hint = 0);
 
    //!Deallocate allocated memory.
    //!Never throws
- void deallocate(const pointer &ptr, size_type count)
- { mp_node_pool->deallocate(detail::get_pointer(ptr), count); }
+ void deallocate(const pointer &ptr, size_type count);
 
- //!Deallocates all free chunks of the pool
- void deallocate_free_chunks()
- { mp_node_pool->deallocate_free_chunks(); }
+ //!Deallocates all free chunks
+ //!of the pool
+ void deallocate_free_chunks();
 
    //!Swaps allocators. Does not throw. If each allocator is placed in a
    //!different memory segment, the result is undefined.
- friend void swap(self_t &alloc1, self_t &alloc2)
- { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
-
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
+ friend void swap(self_t &alloc1, self_t &alloc2);
 
    //!Returns address of mutable object.
    //!Never throws
- pointer address(reference value) const
- { return pointer(boost::addressof(value)); }
+ pointer address(reference value) const;
 
    //!Returns address of non mutable object.
    //!Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(boost::addressof(value)); }
+ const_pointer address(const_reference value) const;
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
- void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ //!Throws if T's default constructor throws
+ void construct(const pointer &ptr);
 
    //!Destroys object. Throws if object's
    //!destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-
- /// @cond
- private:
- //!Object function that creates the node allocator if it is not created and
- //!increments reference count if it is already created
- struct get_or_create_func
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type, sizeof(T), NodesPerChunk> node_pool_t;
-
- //!This connects or constructs the unique instance of node_pool_t
- //!Can throw boost::interprocess::bad_alloc
- void operator()()
- {
- //Find or create the node_pool_t
- mp_node_pool = mp_named_alloc->template find_or_construct
- <node_pool_t>(unique_instance)(mp_named_alloc);
- //If valid, increment link count
- if(mp_node_pool != 0)
- mp_node_pool->inc_ref_count();
- }
-
- //!Constructor. Initializes function
- //!object parameters
- get_or_create_func(segment_manager *hdr) : mp_named_alloc(hdr){}
-
- node_pool_t *mp_node_pool;
- segment_manager *mp_named_alloc;
- };
-
- //!Initialization function, creates an executes atomically the
- //!initialization object functions. Can throw boost::interprocess::bad_alloc
- node_pool_t *priv_get_or_create(segment_manager *named_alloc)
- {
- get_or_create_func func(named_alloc);
- named_alloc->atomic_func(func);
- return func.mp_node_pool;
- }
-
- //!Object function that decrements the reference count. If the count
- //!reaches to zero destroys the node allocator from memory.
- //!Never throws
- struct destroy_if_last_link_func
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk> node_pool_t;
-
- //!Decrements reference count and destroys the object if there is no
- //!more attached allocators. Never throws
- void operator()()
- {
- //If not the last link return
- if(mp_node_pool->dec_ref_count() != 0) return;
-
- //Last link, let's destroy the segment_manager
- mp_named_alloc->template destroy<node_pool_t>(unique_instance);
- }
-
- //!Constructor. Initializes function
- //!object parameters
- destroy_if_last_link_func(segment_manager *nhdr,
- node_pool_t *phdr)
- : mp_named_alloc(nhdr), mp_node_pool(phdr)
- {}
+ void destroy(const pointer &ptr);
 
- segment_manager *mp_named_alloc;
- node_pool_t *mp_node_pool;
- };
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it);
 
- //!Destruction function, initializes and executes destruction function
- //!object. Never throws
- void priv_destroy_if_last_link()
- {
- typedef detail::shared_node_pool
- <SegmentManager, mutex_type,sizeof(T), NodesPerChunk> node_pool_t;
- //Get segment manager
- segment_manager *named_segment_mngr = this->get_segment_manager();
- //Execute destruction functor atomically
- destroy_if_last_link_func func(named_segment_mngr, detail::get_pointer(mp_node_pool));
- named_segment_mngr->atomic_func(func);
- }
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one();
 
- private:
- node_pool_ptr mp_node_pool;
- /// @endcond
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ multiallocation_iterator allocate_individual(std::size_t num_elements);
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p);
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it);
+ #endif
 };
 
-//!Equality test for same type of
-//!node_allocator
-template<class T, class S, std::size_t NodesPerChunk> inline
-bool operator==(const node_allocator<T, S, NodesPerChunk> &alloc1,
- const node_allocator<T, S, NodesPerChunk> &alloc2)
- { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
 
-//!Inequality test for same type of
-//!node_allocator
-template<class T, class S, std::size_t NodesPerChunk> inline
-bool operator!=(const node_allocator<T, S, NodesPerChunk> &alloc1,
- const node_allocator<T, S, NodesPerChunk> &alloc2)
- { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
+//!Equality test for same type
+//!of node_allocator
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator==(const node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
+ const node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
+
+//!Inequality test for same type
+//!of node_allocator
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
+ const node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
+
+#endif
 
 } //namespace interprocess {
 } //namespace boost {
 
 #include <boost/interprocess/detail/config_end.hpp>
 
-#endif //#ifndef BOOST_INTERPROCESS_POOLED_NODE_ALLOCATOR_HPP
+#endif //#ifndef BOOST_INTERPROCESS_NODE_ALLOCATOR_HPP

Modified: branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp (original)
+++ branches/release/boost/interprocess/allocators/private_adaptive_pool.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -30,38 +30,47 @@
 #include <cstddef>
 
 //!\file
-//!Describes private_adaptive_pool pooled shared memory STL compatible allocator
+//!Describes private_adaptive_pool_base pooled shared memory STL compatible allocator
 
 namespace boost {
 namespace interprocess {
 
-//!An STL node allocator that uses a segment manager as memory
-//!source. The internal pointer type will of the same type (raw, smart) as
-//!"typename SegmentManager::void_pointer" type. This allows
-//!placing the allocator in shared memory, memory mapped-files, etc...
-//!This allocator has its own node pool. NodesPerChunk is the minimum number of nodes
-//!allocated at once when the allocator needs runs out of nodes.
-template<class T, class SegmentManager, std::size_t NodesPerChunk, std::size_t MaxFreeChunks>
-class private_adaptive_pool
+/// @cond
+
+namespace detail {
+
+template < unsigned int Version
+ , class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
+ >
+class private_adaptive_pool_base
+ : public node_pool_allocation_impl
+ < private_adaptive_pool_base < Version, T, SegmentManager, NodesPerChunk
+ , MaxFreeChunks, OverheadPercent>
+ , Version
+ , T
+ , SegmentManager
+ >
 {
    /// @cond
    private:
    typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const void>::type cvoid_pointer;
    typedef SegmentManager segment_manager;
- typedef typename detail::
- pointer_to_other<void_pointer, char>::type char_pointer;
- typedef typename detail::pointer_to_other
- <void_pointer, segment_manager>::type segment_mngr_ptr_t;
- typedef typename SegmentManager::
- mutex_family::mutex_type mutex_type;
- typedef private_adaptive_pool
- <T, SegmentManager, NodesPerChunk, MaxFreeChunks> self_t;
+ typedef private_adaptive_pool_base
+ < Version, T, SegmentManager, NodesPerChunk
+ , MaxFreeChunks, OverheadPercent> self_t;
    typedef detail::private_adaptive_node_pool
- <SegmentManager, sizeof(T)
- , NodesPerChunk, MaxFreeChunks> priv_node_pool_t;
+ <SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ > node_pool_t;
 
+ BOOST_STATIC_ASSERT((Version <=2));
 
    /// @endcond
 
@@ -77,120 +86,358 @@
                      <const value_type>::type const_reference;
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
+ typedef detail::version_type
+ <private_adaptive_pool_base, Version> version;
+ typedef transform_iterator
+ < typename SegmentManager::
+ multiallocation_iterator
+ , detail::cast_functor <T> > multiallocation_iterator;
+ typedef typename SegmentManager::
+ multiallocation_chain multiallocation_chain;
 
    //!Obtains node_allocator from other node_allocator
    template<class T2>
    struct rebind
    {
- typedef private_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks> other;
+ typedef private_adaptive_pool_base
+ <Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
    };
 
    /// @cond
    private:
- //!Not assignable from related private_adaptive_pool
- template<class T2, class MemoryAlgorithm2, std::size_t N2, std::size_t F2>
- private_adaptive_pool& operator=
- (const private_adaptive_pool<T2, MemoryAlgorithm2, N2, F2>&);
+ //!Not assignable from related private_adaptive_pool_base
+ template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2, std::size_t F2, unsigned char OP2>
+ private_adaptive_pool_base& operator=
+ (const private_adaptive_pool_base<Version2, T2, MemoryAlgorithm2, N2, F2, OP2>&);
 
- //!Not assignable from other private_adaptive_pool
- private_adaptive_pool& operator=(const private_adaptive_pool&);
+ //!Not assignable from other private_adaptive_pool_base
+ private_adaptive_pool_base& operator=(const private_adaptive_pool_base&);
    /// @endcond
 
    public:
    //!Constructor from a segment manager
- private_adaptive_pool(segment_manager *segment_mngr)
+ private_adaptive_pool_base(segment_manager *segment_mngr)
       : m_node_pool(segment_mngr)
    {}
 
- //!Copy constructor from other private_adaptive_pool. Never throws
- private_adaptive_pool(const private_adaptive_pool &other)
+ //!Copy constructor from other private_adaptive_pool_base. Never throws
+ private_adaptive_pool_base(const private_adaptive_pool_base &other)
       : m_node_pool(other.get_segment_manager())
    {}
 
- //!Copy constructor from related private_adaptive_pool. Never throws.
+ //!Copy constructor from related private_adaptive_pool_base. Never throws.
    template<class T2>
- private_adaptive_pool
- (const private_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks> &other)
+ private_adaptive_pool_base
+ (const private_adaptive_pool_base
+ <Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
       : m_node_pool(other.get_segment_manager())
    {}
 
    //!Destructor, frees all used memory. Never throws
- ~private_adaptive_pool()
+ ~private_adaptive_pool_base()
    {}
 
    //!Returns the segment manager. Never throws
    segment_manager* get_segment_manager()const
    { return m_node_pool.get_segment_manager(); }
 
- //!Returns the number of elements that could be allocated. Never throws
- size_type max_size() const
- { return this->get_segment_manager()/sizeof(value_type); }
-
- //!Allocate memory for an array of count elements.
- //!Throws boost::interprocess::bad_alloc if there is no enough memory
- pointer allocate(size_type count, cvoid_pointer hint = 0)
- {
- (void)hint;
- if(count > ((size_type)-1)/sizeof(value_type))
- throw bad_alloc();
- return pointer(static_cast<value_type*>(m_node_pool.allocate(count)));
- }
-
- //!Deallocate allocated memory. Never throws
- void deallocate(const pointer &ptr, size_type count)
- { m_node_pool.deallocate(detail::get_pointer(ptr), count); }
-
- //!Deallocates all free chunks of the pool
- void deallocate_free_chunks()
- { m_node_pool.deallocate_free_chunks(); }
+ //!Returns the internal node pool. Never throws
+ node_pool_t* get_node_pool() const
+ { return const_cast<node_pool_t*>(&m_node_pool); }
 
    //!Swaps allocators. Does not throw. If each allocator is placed in a
- //!different shared memory segments, the result is undefined.*/
+ //!different shared memory segments, the result is undefined.
    friend void swap(self_t &alloc1,self_t &alloc2)
    { alloc1.m_node_pool.swap(alloc2.m_node_pool); }
 
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
+ /// @cond
+ private:
+ node_pool_t m_node_pool;
+ /// @endcond
+};
+
+//!Equality test for same type of private_adaptive_pool_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator==(const private_adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
+ const private_adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
+{ return &alloc1 == &alloc2; }
+
+//!Inequality test for same type of private_adaptive_pool_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const private_adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
+ const private_adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
+{ return &alloc1 != &alloc2; }
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk = 64
+ , std::size_t MaxFreeChunks = 2
+ , unsigned char OverheadPercent = 5
+ >
+class private_adaptive_pool_v1
+ : public private_adaptive_pool_base
+ < 1
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+{
+ public:
+ typedef detail::private_adaptive_pool_base
+ < 1, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef private_adaptive_pool_v1<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ private_adaptive_pool_v1(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ private_adaptive_pool_v1
+ (const private_adaptive_pool_v1<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : base_t(other)
+ {}
+};
+
+} //namespace detail {
+
+/// @endcond
+
+//!An STL node allocator that uses a segment manager as memory
+//!source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
+//!This allocator has its own node pool.
+//!
+//!NodesPerChunk is the minimum number of nodes of nodes allocated at once when
+//!the allocator needs runs out of nodes. MaxFreeChunks is the maximum number of totally free chunks
+//!that the adaptive node pool will hold. The rest of the totally free chunks will be
+//!deallocated with the segment manager.
+//!
+//!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
+//!(memory usable for nodes / total memory allocated from the segment manager)
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
+ >
+class private_adaptive_pool
+ /// @cond
+ : public detail::private_adaptive_pool_base
+ < 2
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ >
+ /// @endcond
+{
+
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ typedef detail::private_adaptive_pool_base
+ < 2, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> base_t;
+ public:
+ typedef detail::version_type<private_adaptive_pool, 2> version;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef private_adaptive_pool
+ <T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ private_adaptive_pool(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ private_adaptive_pool
+ (const private_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : base_t(other)
+ {}
+
+ #else
+ public:
+ typedef implementation_defined::segment_manager segment_manager;
+ typedef segment_manager::void_pointer void_pointer;
+ typedef implementation_defined::pointer pointer;
+ typedef implementation_defined::const_pointer const_pointer;
+ typedef T value_type;
+ typedef typename detail::add_reference
+ <value_type>::type reference;
+ typedef typename detail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ //!Obtains private_adaptive_pool from
+ //!private_adaptive_pool
+ template<class T2>
+ struct rebind
+ {
+ typedef private_adaptive_pool
+ <T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ private:
+ //!Not assignable from
+ //!related private_adaptive_pool
+ template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char OP2>
+ private_adaptive_pool& operator=
+ (const private_adaptive_pool<T2, SegmentManager2, N2, F2>&);
+
+ //!Not assignable from
+ //!other private_adaptive_pool
+ private_adaptive_pool& operator=(const private_adaptive_pool&);
+
+ public:
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ private_adaptive_pool(segment_manager *segment_mngr);
+
+ //!Copy constructor from other private_adaptive_pool. Increments the reference
+ //!count of the associated node pool. Never throws
+ private_adaptive_pool(const private_adaptive_pool &other);
+
+ //!Copy constructor from related private_adaptive_pool. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ template<class T2>
+ private_adaptive_pool
+ (const private_adaptive_pool<T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other);
+
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
+ ~private_adaptive_pool();
+
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ node_pool_t* get_node_pool() const;
+
+ //!Returns the segment manager.
+ //!Never throws
+ segment_manager* get_segment_manager()const;
+
+ //!Returns the number of elements that could be allocated.
+ //!Never throws
+ size_type max_size() const;
+
+ //!Allocate memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate(size_type count, cvoid_pointer hint = 0);
+
+ //!Deallocate allocated memory.
+ //!Never throws
+ void deallocate(const pointer &ptr, size_type count);
+
+ //!Deallocates all free chunks
+ //!of the pool
+ void deallocate_free_chunks();
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2);
 
    //!Returns address of mutable object.
    //!Never throws
- pointer address(reference value) const
- { return pointer(boost::addressof(value)); }
+ pointer address(reference value) const;
 
    //!Returns address of non mutable object.
    //!Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(boost::addressof(value)); }
+ const_pointer address(const_reference value) const;
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
- void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ //!Throws if T's default constructor throws
+ void construct(const pointer &ptr);
 
    //!Destroys object. Throws if object's
    //!destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
+ void destroy(const pointer &ptr);
 
- /// @cond
- private:
- priv_node_pool_t m_node_pool;
- /// @endcond
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it);
+
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one();
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ multiallocation_iterator allocate_individual(std::size_t num_elements);
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p);
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it);
+ #endif
 };
 
-//!Equality test for same type of private_adaptive_pool
-template<class T, class S, std::size_t NodesPerChunk, std::size_t F> inline
-bool operator==(const private_adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
- const private_adaptive_pool<T, S, NodesPerChunk, F> &alloc2)
-{ return &alloc1 == &alloc2; }
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+//!Equality test for same type
+//!of private_adaptive_pool
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator==(const private_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc1,
+ const private_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc2);
+
+//!Inequality test for same type
+//!of private_adaptive_pool
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const private_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc1,
+ const private_adaptive_pool<T, S, NodesPerChunk, F, OP> &alloc2);
 
-//!Inequality test for same type of private_adaptive_pool
-template<class T, class S, std::size_t NodesPerChunk, std::size_t F> inline
-bool operator!=(const private_adaptive_pool<T, S, NodesPerChunk, F> &alloc1,
- const private_adaptive_pool<T, S, NodesPerChunk, F> &alloc2)
-{
- return &alloc1 != &alloc2;
-}
+#endif
 
 } //namespace interprocess {
 } //namespace boost {

Modified: branches/release/boost/interprocess/allocators/private_node_allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/private_node_allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/private_node_allocator.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,13 +1,13 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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_PRIVATE_NODE_ALLOCATOR_HPP
 #define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
 
@@ -50,12 +50,8 @@
    typedef typename detail::
       pointer_to_other<void_pointer, const void>::type cvoid_pointer;
    typedef SegmentManager segment_manager;
- typedef typename detail::
- pointer_to_other<void_pointer, char>::type char_pointer;
    typedef typename detail::pointer_to_other
       <void_pointer, segment_manager>::type segment_mngr_ptr_t;
- typedef typename SegmentManager::
- mutex_family::mutex_type mutex_type;
    typedef private_node_allocator
       <T, SegmentManager, NodesPerChunk> self_t;
    typedef detail::private_node_pool
@@ -128,21 +124,30 @@
    pointer allocate(size_type count, cvoid_pointer hint = 0)
    {
       (void)hint;
- if(count > ((size_type)-1)/sizeof(value_type))
+ if(count > this->max_size())
          throw bad_alloc();
- return pointer(static_cast<value_type*>(m_node_pool.allocate(count)));
+ else if(count == 1)
+ return pointer(static_cast<value_type*>(m_node_pool.allocate_node()));
+ else
+ return pointer(static_cast<value_type*>
+ (m_node_pool.get_segment_manager()->allocate(sizeof(T)*count)));
    }
 
    //!Deallocate allocated memory. Never throws
    void deallocate(const pointer &ptr, size_type count)
- { m_node_pool.deallocate(detail::get_pointer(ptr), count); }
+ {
+ if(count == 1)
+ m_node_pool.deallocate_node(detail::get_pointer(ptr));
+ else
+ m_node_pool.get_segment_manager()->deallocate(detail::get_pointer(ptr));
+ }
 
    //!Deallocates all free chunks of the pool
    void deallocate_free_chunks()
    { m_node_pool.deallocate_free_chunks(); }
 
    //!Swaps allocators. Does not throw. If each allocator is placed in a
- //!different shared memory segments, the result is undefined.*/
+ //!different shared memory segments, the result is undefined.
    friend void swap(self_t &alloc1,self_t &alloc2)
    { alloc1.m_node_pool.swap(alloc2.m_node_pool); }
 
@@ -160,7 +165,7 @@
    { return const_pointer(boost::addressof(value)); }
 
    //!Default construct an object.
- //!Throws if T's default constructor throws*/
+ //!Throws if T's default constructor throws
    void construct(const pointer &ptr)
    { new(detail::get_pointer(ptr)) value_type; }
 
@@ -196,3 +201,432 @@
 
 #endif //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
 
+*/
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2008. 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_PRIVATE_NODE_ALLOCATOR_HPP
+#define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/interprocess/detail/config_begin.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+
+#include <boost/interprocess/interprocess_fwd.hpp>
+#include <boost/assert.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/interprocess/allocators/detail/node_pool.hpp>
+#include <boost/interprocess/exceptions.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
+#include <boost/interprocess/detail/workaround.hpp>
+#include <memory>
+#include <algorithm>
+#include <cstddef>
+
+//!\file
+//!Describes private_node_allocator_base pooled shared memory STL compatible allocator
+
+namespace boost {
+namespace interprocess {
+
+/// @cond
+
+namespace detail {
+
+template < unsigned int Version
+ , class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ >
+class private_node_allocator_base
+ : public node_pool_allocation_impl
+ < private_node_allocator_base < Version, T, SegmentManager, NodesPerChunk>
+ , Version
+ , T
+ , SegmentManager
+ >
+{
+ /// @cond
+ private:
+ typedef typename SegmentManager::void_pointer void_pointer;
+ typedef SegmentManager segment_manager;
+ typedef private_node_allocator_base
+ < Version, T, SegmentManager, NodesPerChunk> self_t;
+ typedef detail::private_node_pool
+ <SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ > node_pool_t;
+
+ BOOST_STATIC_ASSERT((Version <=2));
+
+ /// @endcond
+
+ public:
+ typedef typename detail::
+ pointer_to_other<void_pointer, T>::type pointer;
+ typedef typename detail::
+ pointer_to_other<void_pointer, const T>::type const_pointer;
+ typedef T value_type;
+ typedef typename detail::add_reference
+ <value_type>::type reference;
+ typedef typename detail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef detail::version_type
+ <private_node_allocator_base, Version> version;
+ typedef transform_iterator
+ < typename SegmentManager::
+ multiallocation_iterator
+ , detail::cast_functor <T> > multiallocation_iterator;
+ typedef typename SegmentManager::
+ multiallocation_chain multiallocation_chain;
+
+ //!Obtains node_allocator from other node_allocator
+ template<class T2>
+ struct rebind
+ {
+ typedef private_node_allocator_base
+ <Version, T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ /// @cond
+ private:
+ //!Not assignable from related private_node_allocator_base
+ template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2>
+ private_node_allocator_base& operator=
+ (const private_node_allocator_base<Version2, T2, MemoryAlgorithm2, N2>&);
+
+ //!Not assignable from other private_node_allocator_base
+ private_node_allocator_base& operator=(const private_node_allocator_base&);
+ /// @endcond
+
+ public:
+ //!Constructor from a segment manager
+ private_node_allocator_base(segment_manager *segment_mngr)
+ : m_node_pool(segment_mngr)
+ {}
+
+ //!Copy constructor from other private_node_allocator_base. Never throws
+ private_node_allocator_base(const private_node_allocator_base &other)
+ : m_node_pool(other.get_segment_manager())
+ {}
+
+ //!Copy constructor from related private_node_allocator_base. Never throws.
+ template<class T2>
+ private_node_allocator_base
+ (const private_node_allocator_base
+ <Version, T2, SegmentManager, NodesPerChunk> &other)
+ : m_node_pool(other.get_segment_manager())
+ {}
+
+ //!Destructor, frees all used memory. Never throws
+ ~private_node_allocator_base()
+ {}
+
+ //!Returns the segment manager. Never throws
+ segment_manager* get_segment_manager()const
+ { return m_node_pool.get_segment_manager(); }
+
+ //!Returns the internal node pool. Never throws
+ node_pool_t* get_node_pool() const
+ { return const_cast<node_pool_t*>(&m_node_pool); }
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different shared memory segments, the result is undefined.
+ friend void swap(self_t &alloc1,self_t &alloc2)
+ { alloc1.m_node_pool.swap(alloc2.m_node_pool); }
+
+ /// @cond
+ private:
+ node_pool_t m_node_pool;
+ /// @endcond
+};
+
+//!Equality test for same type of private_node_allocator_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
+bool operator==(const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
+ const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+{ return &alloc1 == &alloc2; }
+
+//!Inequality test for same type of private_node_allocator_base
+template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
+bool operator!=(const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
+ const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+{ return &alloc1 != &alloc2; }
+
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk = 64
+ >
+class private_node_allocator_v1
+ : public private_node_allocator_base
+ < 1
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ >
+{
+ public:
+ typedef detail::private_node_allocator_base
+ < 1, T, SegmentManager, NodesPerChunk> base_t;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef private_node_allocator_v1<T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ private_node_allocator_v1(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ private_node_allocator_v1
+ (const private_node_allocator_v1<T2, SegmentManager, NodesPerChunk> &other)
+ : base_t(other)
+ {}
+};
+
+} //namespace detail {
+
+/// @endcond
+
+//!An STL node allocator that uses a segment manager as memory
+//!source. The internal pointer type will of the same type (raw, smart) as
+//!"typename SegmentManager::void_pointer" type. This allows
+//!placing the allocator in shared memory, memory mapped-files, etc...
+//!This allocator has its own node pool. NodesPerChunk is the number of nodes allocated
+//!at once when the allocator needs runs out of nodes
+template < class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ >
+class private_node_allocator
+ /// @cond
+ : public detail::private_node_allocator_base
+ < 2
+ , T
+ , SegmentManager
+ , NodesPerChunk
+ >
+ /// @endcond
+{
+
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ typedef detail::private_node_allocator_base
+ < 2, T, SegmentManager, NodesPerChunk> base_t;
+ public:
+ typedef detail::version_type<private_node_allocator, 2> version;
+
+ template<class T2>
+ struct rebind
+ {
+ typedef private_node_allocator
+ <T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ private_node_allocator(SegmentManager *segment_mngr)
+ : base_t(segment_mngr)
+ {}
+
+ template<class T2>
+ private_node_allocator
+ (const private_node_allocator<T2, SegmentManager, NodesPerChunk> &other)
+ : base_t(other)
+ {}
+
+ #else
+ public:
+ typedef implementation_defined::segment_manager segment_manager;
+ typedef segment_manager::void_pointer void_pointer;
+ typedef implementation_defined::pointer pointer;
+ typedef implementation_defined::const_pointer const_pointer;
+ typedef T value_type;
+ typedef typename detail::add_reference
+ <value_type>::type reference;
+ typedef typename detail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ //!Obtains private_node_allocator from
+ //!private_node_allocator
+ template<class T2>
+ struct rebind
+ {
+ typedef private_node_allocator
+ <T2, SegmentManager, NodesPerChunk> other;
+ };
+
+ private:
+ //!Not assignable from
+ //!related private_node_allocator
+ template<class T2, class SegmentManager2, std::size_t N2>
+ private_node_allocator& operator=
+ (const private_node_allocator<T2, SegmentManager2, N2>&);
+
+ //!Not assignable from
+ //!other private_node_allocator
+ private_node_allocator& operator=(const private_node_allocator&);
+
+ public:
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ private_node_allocator(segment_manager *segment_mngr);
+
+ //!Copy constructor from other private_node_allocator. Increments the reference
+ //!count of the associated node pool. Never throws
+ private_node_allocator(const private_node_allocator &other);
+
+ //!Copy constructor from related private_node_allocator. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ template<class T2>
+ private_node_allocator
+ (const private_node_allocator<T2, SegmentManager, NodesPerChunk> &other);
+
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
+ ~private_node_allocator();
+
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ node_pool_t* get_node_pool() const;
+
+ //!Returns the segment manager.
+ //!Never throws
+ segment_manager* get_segment_manager()const;
+
+ //!Returns the number of elements that could be allocated.
+ //!Never throws
+ size_type max_size() const;
+
+ //!Allocate memory for an array of count elements.
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate(size_type count, cvoid_pointer hint = 0);
+
+ //!Deallocate allocated memory.
+ //!Never throws
+ void deallocate(const pointer &ptr, size_type count);
+
+ //!Deallocates all free chunks
+ //!of the pool
+ void deallocate_free_chunks();
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2);
+
+ //!Returns address of mutable object.
+ //!Never throws
+ pointer address(reference value) const;
+
+ //!Returns address of non mutable object.
+ //!Never throws
+ const_pointer address(const_reference value) const;
+
+ //!Default construct an object.
+ //!Throws if T's default constructor throws
+ void construct(const pointer &ptr);
+
+ //!Destroys object. Throws if object's
+ //!destructor throws
+ void destroy(const pointer &ptr);
+
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold. This size only works for memory allocated with
+ //!allocate, allocation_command and allocate_many.
+ size_type size(const pointer &p) const;
+
+ std::pair<pointer, bool>
+ allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type preferred_size,
+ size_type &received_size, const pointer &reuse = 0);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ multiallocation_iterator allocate_many(size_type elem_size, std::size_t num_elements);
+
+ //!Allocates n_elements elements, each one of size elem_sizes[i]in a
+ //!contiguous chunk
+ //!of memory. The elements must be deallocated
+ multiallocation_iterator allocate_many(const size_type *elem_sizes, size_type n_elements);
+
+ //!Allocates many elements of size elem_size in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. The elements must be deallocated
+ //!with deallocate(...)
+ void deallocate_many(multiallocation_iterator it);
+
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws boost::interprocess::bad_alloc if there is no enough memory
+ pointer allocate_one();
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ multiallocation_iterator allocate_individual(std::size_t num_elements);
+
+ //!Deallocates memory previously allocated with allocate_one().
+ //!You should never use deallocate_one to deallocate memory allocated
+ //!with other functions different from allocate_one(). Never throws
+ void deallocate_one(const pointer &p);
+
+ //!Allocates many elements of size == 1 in a contiguous chunk
+ //!of memory. The minimum number to be allocated is min_elements,
+ //!the preferred and maximum number is
+ //!preferred_elements. The number of actually allocated elements is
+ //!will be assigned to received_size. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ void deallocate_individual(multiallocation_iterator it);
+ #endif
+};
+
+#ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+
+//!Equality test for same type
+//!of private_node_allocator
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator==(const private_node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
+ const private_node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
+
+//!Inequality test for same type
+//!of private_node_allocator
+template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
+bool operator!=(const private_node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
+ const private_node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
+
+#endif
+
+} //namespace interprocess {
+} //namespace boost {
+
+#include <boost/interprocess/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
+

Modified: branches/release/boost/interprocess/containers/deque.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/deque.hpp (original)
+++ branches/release/boost/interprocess/containers/deque.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1359,9 +1359,9 @@
       size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
                               this->s_buffer_size();
       this->priv_reserve_map_at_front(new_nodes);
- size_type i;
+ size_type i = 1;
       BOOST_TRY {
- for (i = 1; i <= new_nodes; ++i)
+ for (; i <= new_nodes; ++i)
             *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
       }
       BOOST_CATCH(...) {
@@ -1453,6 +1453,7 @@
          for(;first2 != mid2; ++first2){
             detail::get_pointer(&*first2)->~value_type();
          }
+ BOOST_RETHROW
       }
       BOOST_CATCH_END
    }

Modified: branches/release/boost/interprocess/containers/detail/flat_tree.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/detail/flat_tree.hpp (original)
+++ branches/release/boost/interprocess/containers/detail/flat_tree.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/containers/detail/node_alloc_holder.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/detail/node_alloc_holder.hpp (original)
+++ branches/release/boost/interprocess/containers/detail/node_alloc_holder.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -74,6 +74,9 @@
    typedef detail::integral_constant<unsigned,
       boost::interprocess::detail::
          version<NodeAlloc>::value> alloc_version;
+ typedef typename ICont::iterator icont_iterator;
+ typedef typename ICont::const_iterator icont_citerator;
+ typedef allocator_destroyer<NodeAlloc> Destroyer;
 
    node_alloc_holder(const ValAlloc &a)
       : members_(a)
@@ -173,7 +176,7 @@
       BOOST_CATCH(...){
          valueptr->first.~first_type();
          static_cast<hook_type*>(nodeptr)->~hook_type();
- throw;
+ BOOST_RETHROW
       }
       BOOST_CATCH_END
    }
@@ -198,7 +201,7 @@
       BOOST_CATCH(...){
          valueptr->first.~first_type();
          static_cast<hook_type*>(nodeptr)->~hook_type();
- throw;
+ BOOST_RETHROW
       }
       BOOST_CATCH_END
    }
@@ -292,18 +295,42 @@
          if(constructed){
             this->destroy(p);
          }
- this->deallocate_one(p);
- multiallocation_iterator itend;
- while(itbeg != itend){
- Node *n = &*itbeg;
- ++itbeg;
- this->deallocate_one(n);
- }
+ this->node_alloc().deallocate_many(itbeg);
+ BOOST_RETHROW
       }
       BOOST_CATCH_END
       return beg;
    }
 
+ void clear(allocator_v1)
+ { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+
+ void clear(allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ this->icont().clear_and_dispose(chain_holder.get_chain_builder());
+ }
+
+ icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v1)
+ { return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
+
+ icont_iterator erase_range(icont_iterator first, icont_iterator last, allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
+ }
+
+ template<class Key, class Comparator>
+ size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
+ { return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
+
+ template<class Key, class Comparator>
+ size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
+ {
+ allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
+ return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
+ }
+
    protected:
    struct cloner
    {
@@ -359,10 +386,10 @@
    { return this->members_.m_icont; }
 
    NodeAlloc &node_alloc()
- { return this->members_; }
+ { return static_cast<NodeAlloc &>(this->members_); }
 
    const NodeAlloc &node_alloc() const
- { return this->members_; }
+ { return static_cast<const NodeAlloc &>(this->members_); }
 };
 
 } //namespace detail {

Modified: branches/release/boost/interprocess/containers/detail/tree.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/detail/tree.hpp (original)
+++ branches/release/boost/interprocess/containers/detail/tree.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -732,13 +732,13 @@
    { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
 
    size_type erase(const key_type& k)
- { return this->icont().erase_and_dispose(k, KeyNodeCompare(value_comp()), Destroyer(this->node_alloc())); }
+ { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
 
    iterator erase(const_iterator first, const_iterator last)
- { return iterator(this->icont().erase_and_dispose(first.get(), last.get(), Destroyer(this->node_alloc()))); }
+ { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
 
    void clear()
- { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+ { AllocHolder::clear(alloc_version()); }
 
    // set operations:
    iterator find(const key_type& k)

Modified: branches/release/boost/interprocess/containers/flat_map.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/flat_map.hpp (original)
+++ branches/release/boost/interprocess/containers/flat_map.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/containers/flat_set.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/flat_set.hpp (original)
+++ branches/release/boost/interprocess/containers/flat_set.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/containers/list.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/list.hpp (original)
+++ branches/release/boost/interprocess/containers/list.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -404,7 +404,7 @@
    //!
    //! <b>Complexity</b>: Linear to the number of elements in the list.
    void clear()
- { this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+ { AllocHolder::clear(alloc_version()); }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
    //!
@@ -786,7 +786,7 @@
    //!
    //! <b>Complexity</b>: Linear to the distance between first and last.
    iterator erase(iterator first, iterator last)
- { return iterator(this->icont().erase_and_dispose(first.get(), last.get(), Destroyer(this->node_alloc()))); }
+ { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
 
    //! <b>Effects</b>: Assigns the n copies of val to *this.
    //!
@@ -1085,6 +1085,7 @@
 
    /// @cond
    private:
+
    //Iterator range version
    template<class InpIterator>
    void priv_create_and_insert_nodes
@@ -1160,7 +1161,7 @@
 
    template<class Integer>
    void priv_insert_dispatch(iterator p, Integer n, Integer x, detail::true_)
- { this->priv_create_and_insert_nodes(p, n, x); }
+ { this->insert(p, (size_type)n, x); }
 
    void priv_fill_assign(size_type n, const T& val)
    {

Modified: branches/release/boost/interprocess/containers/map.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/map.hpp (original)
+++ branches/release/boost/interprocess/containers/map.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/containers/set.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/set.hpp (original)
+++ branches/release/boost/interprocess/containers/set.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/containers/slist.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/slist.hpp (original)
+++ branches/release/boost/interprocess/containers/slist.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-2008. 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-2007
+// This file comes from SGI's stl_slist.h file. Modified by Ion Gaztanaga 2004-2008
 // Renaming, isolating and porting to generic algorithms. Pointer typedef
 // set to allocator::pointer to allow placing it in shared memory.
 //
@@ -347,7 +347,7 @@
    slist(InpIt first, InpIt last,
          const allocator_type& a = allocator_type())
       : AllocHolder(a)
- { this->insert_after(this->end_node(), first, last); }
+ { this->insert_after(this->before_begin(), first, last); }
 
    //! <b>Effects</b>: Copy constructs a list.
    //!
@@ -804,7 +804,7 @@
    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
    void resize(size_type new_size, const T& x)
    {
- typename Icont::iterator end_n(this->icont().end()), cur(end_n), cur_next;
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
       while (++(cur_next = cur) != end_n && new_size > 0){
          --new_size;
          cur = cur_next;
@@ -823,7 +823,7 @@
    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
    void resize(size_type new_size)
    {
- typename Icont::iterator end_n(this->icont().end()), cur(end_n), cur_next;
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
       size_type len = this->size();
       size_type left = new_size;
       
@@ -835,7 +835,7 @@
          this->erase_after(iterator(cur), iterator(end_n));
       }
       else{
- this->priv_create_and_insert_nodes(this->end(), new_size - len);
+ this->priv_create_and_insert_nodes(iterator(cur), new_size - len);
       }
    }
 
@@ -1252,9 +1252,9 @@
 
    void priv_fill_assign(size_type n, const T& val)
    {
- iterator end_n(end());
- iterator prev(before_begin());
- iterator node(begin());
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
       for ( ; node != end_n && n > 0 ; --n){
          *node = val;
          prev = node;
@@ -1274,9 +1274,9 @@
    void priv_assign_dispatch(InpIt first, InpIt last,
                            detail::false_)
    {
- iterator end_n(end());
- iterator prev(before_begin());
- iterator node(begin());
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
       while (node != end_n && first != last){
          *node = *first;
          prev = node;
@@ -1295,7 +1295,7 @@
 
    template <class InIter>
    void priv_insert_after_range_dispatch(iterator prev_pos, InIter first, InIter last, detail::false_)
- { return priv_create_and_insert_nodes(prev_pos, first, last); }
+ { this->priv_create_and_insert_nodes(prev_pos, first, last); }
 
    //Functors for member algorithm defaults
    struct value_less

Modified: branches/release/boost/interprocess/containers/string.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/string.hpp (original)
+++ branches/release/boost/interprocess/containers/string.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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-2007
+// This file comes from SGI's string file. Modified by Ion Gaztanaga 2004-2008
 // Renaming, isolating and porting to generic algorithms. Pointer typedef
 // set to allocator::pointer to allow placing it in shared memory.
 //
@@ -1684,7 +1684,7 @@
          for (; constructed--; ++dest_init){
             this->destroy(dest_init);
          }
- BOOST_RETHROW;
+ BOOST_RETHROW
       }
       BOOST_CATCH_END
       return (constructed);

Modified: branches/release/boost/interprocess/containers/vector.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/vector.hpp (original)
+++ branches/release/boost/interprocess/containers/vector.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -731,7 +731,7 @@
          //There is not enough memory, allocate a new
          //buffer or expand the old one.
          bool same_buffer_start;
- size_type real_cap;
+ size_type real_cap = 0;
          std::pair<pointer, bool> ret =
             this->allocation_command
                (allocate_new | expand_fwd | expand_bwd,
@@ -740,6 +740,9 @@
          //Check for forward expansion
          same_buffer_start = ret.second && this->members_.m_start == ret.first;
          if(same_buffer_start){
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
             this->members_.m_capacity = real_cap;
          }
          //If there is no forward expansion, move objects
@@ -748,6 +751,9 @@
             copy_move_it dummy_it(detail::get_pointer(this->members_.m_start));
             //Backwards (and possibly forward) expansion
             if(ret.second){
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
                this->priv_range_insert_expand_backwards
                   ( detail::get_pointer(ret.first)
                   , real_cap
@@ -758,6 +764,9 @@
             }
             //New buffer
             else{
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
                this->priv_range_insert_new_allocation
                   ( detail::get_pointer(ret.first)
                   , real_cap
@@ -1184,11 +1193,17 @@
          
          //If we had room or we have expanded forward
          if (same_buffer_start){
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
             this->priv_range_insert_expand_forward
                (detail::get_pointer(pos), first, last, n);
          }
          //Backwards (and possibly forward) expansion
          else if(ret.second){
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
             this->priv_range_insert_expand_backwards
                ( detail::get_pointer(ret.first)
                , real_cap
@@ -1199,6 +1214,9 @@
          }
          //New buffer
          else{
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
             this->priv_range_insert_new_allocation
                ( detail::get_pointer(ret.first)
                , real_cap
@@ -1778,6 +1796,15 @@
       if (n >= size())
          throw std::out_of_range("vector::at");
    }
+
+ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
+ public:
+ unsigned int num_expand_fwd;
+ unsigned int num_expand_bwd;
+ unsigned int num_alloc;
+ void reset_alloc_stats()
+ { num_expand_fwd = num_expand_bwd = num_alloc = 0; }
+ #endif
    /// @endcond
 };
 

Modified: branches/release/boost/interprocess/creation_tags.hpp
==============================================================================
--- branches/release/boost/interprocess/creation_tags.hpp (original)
+++ branches/release/boost/interprocess/creation_tags.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/algorithms.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/algorithms.hpp (original)
+++ branches/release/boost/interprocess/detail/algorithms.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -92,7 +92,7 @@
       for (; new_count--; ++dest_init){
          detail::get_pointer(&*dest_init)->~value_type();
       }
- BOOST_RETHROW;
+ BOOST_RETHROW
    }
    BOOST_CATCH_END
    return first;

Modified: branches/release/boost/interprocess/detail/atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/atomic.hpp (original)
+++ branches/release/boost/interprocess/detail/atomic.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 // (C) Copyright Markus Schoepflin 2007
 //
 // Distributed under the Boost Software License, Version 1.0. (See

Modified: branches/release/boost/interprocess/detail/cast_tags.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/cast_tags.hpp (original)
+++ branches/release/boost/interprocess/detail/cast_tags.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/config_begin.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/config_begin.hpp (original)
+++ branches/release/boost/interprocess/detail/config_begin.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -9,6 +9,7 @@
    #define _CRT_SECURE_NO_DEPRECATE
    #endif
    #pragma warning (push)
+ #pragma warning (disable : 4702) // unreachable code
    #pragma warning (disable : 4706) // assignment within conditional expression
    #pragma warning (disable : 4127) // conditional expression is constant
    #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned

Modified: branches/release/boost/interprocess/detail/in_place_interface.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/in_place_interface.hpp (original)
+++ branches/release/boost/interprocess/detail/in_place_interface.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/interprocess_tester.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/interprocess_tester.hpp (original)
+++ branches/release/boost/interprocess/detail/interprocess_tester.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2008. 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: branches/release/boost/interprocess/detail/iterators.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/iterators.hpp (original)
+++ branches/release/boost/interprocess/detail/iterators.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
@@ -428,6 +428,12 @@
       operator->() const
    { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
 
+ Iterator & base()
+ { return m_it; }
+
+ const Iterator & base() const
+ { return m_it; }
+
    private:
    Iterator m_it;
 

Modified: branches/release/boost/interprocess/detail/managed_memory_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_memory_impl.hpp (original)
+++ branches/release/boost/interprocess/detail/managed_memory_impl.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp (original)
+++ branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -332,7 +332,8 @@
 
             //If the following throws, we will truncate the file to 1
             mapped_region region(dev, read_write, 0, 0, addr);
- boost::uint32_t *patomic_word = static_cast<boost::uint32_t*>(region.get_address());
+ boost::uint32_t *patomic_word = 0; //avoid gcc warning
+ patomic_word = static_cast<boost::uint32_t*>(region.get_address());
             boost::uint32_t previous = detail::atomic_cas32(patomic_word, InitializingSegment, UninitializedSegment);
 
             if(previous == UninitializedSegment){

Modified: branches/release/boost/interprocess/detail/math_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/math_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/math_functions.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,7 +1,7 @@
 //////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Stephen Cleary 2000.
-// (C) Copyright Ion Gaztanaga 2007.
+// (C) Copyright Ion Gaztanaga 2007-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/interprocess/detail/min_max.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/min_max.hpp (original)
+++ branches/release/boost/interprocess/detail/min_max.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/interprocess/detail/mpl.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/mpl.hpp (original)
+++ branches/release/boost/interprocess/detail/mpl.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/interprocess/detail/named_proxy.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/named_proxy.hpp (original)
+++ branches/release/boost/interprocess/detail/named_proxy.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/os_file_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_file_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/os_file_functions.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_thread_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/os_thread_functions.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/pointer_type.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/pointer_type.hpp (original)
+++ branches/release/boost/interprocess/detail/pointer_type.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.

Modified: branches/release/boost/interprocess/detail/posix_time_types_wrk.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/posix_time_types_wrk.hpp (original)
+++ branches/release/boost/interprocess/detail/posix_time_types_wrk.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/segment_manager_helper.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/segment_manager_helper.hpp (original)
+++ branches/release/boost/interprocess/detail/segment_manager_helper.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -210,7 +210,7 @@
    BOOST_CATCH(...){
       std::size_t destroyed = 0;
       table.destroy_n(mem, constructed, destroyed);
- BOOST_RETHROW;
+ BOOST_RETHROW
    }
    BOOST_CATCH_END
 }

Modified: branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp (original)
+++ branches/release/boost/interprocess/detail/tmp_dir_helpers.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2008. 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: branches/release/boost/interprocess/detail/type_traits.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/type_traits.hpp (original)
+++ branches/release/boost/interprocess/detail/type_traits.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/interprocess/detail/utilities.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/utilities.hpp (original)
+++ branches/release/boost/interprocess/detail/utilities.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007.
+// (C) Copyright Ion Gaztanaga 2005-2008.
 // (C) Copyright Gennaro Prota 2003 - 2004.
 //
 // Distributed under the Boost Software License, Version 1.0.
@@ -25,6 +25,9 @@
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/interprocess/detail/min_max.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/detail/iterators.hpp>
+#include <boost/interprocess/detail/version_type.hpp>
 #include <utility>
 #include <algorithm>
 
@@ -70,14 +73,27 @@
 struct scoped_ptr_dealloc_functor
 {
    typedef typename Allocator::pointer pointer;
+ typedef detail::integral_constant<unsigned,
+ boost::interprocess::detail::
+ version<Allocator>::value> alloc_version;
+ typedef detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef detail::integral_constant<unsigned, 2> allocator_v2;
 
+ private:
+ void priv_deallocate(const typename Allocator::pointer &p, allocator_v1)
+ { m_alloc.deallocate(p, 1); }
+
+ void priv_deallocate(const typename Allocator::pointer &p, allocator_v2)
+ { m_alloc.deallocate_one(p); }
+
+ public:
    Allocator& m_alloc;
 
    scoped_ptr_dealloc_functor(Allocator& a)
- : m_alloc(a) {}
+ : m_alloc(a) {}
 
    void operator()(pointer ptr)
- { if (ptr) m_alloc.deallocate(ptr, 1); }
+ { if (ptr) priv_deallocate(ptr, alloc_version()); }
 };
 
 //!A deleter for scoped_ptr that deallocates the memory
@@ -86,7 +102,20 @@
 struct scoped_deallocator
 {
    typedef typename Allocator::pointer pointer;
+ typedef detail::integral_constant<unsigned,
+ boost::interprocess::detail::
+ version<Allocator>::value> alloc_version;
+ typedef detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef detail::integral_constant<unsigned, 2> allocator_v2;
+
+ private:
+ void priv_deallocate(allocator_v1)
+ { m_alloc.deallocate(m_ptr, 1); }
+
+ void priv_deallocate(allocator_v2)
+ { m_alloc.deallocate_one(m_ptr); }
 
+ public:
    pointer m_ptr;
    Allocator& m_alloc;
 
@@ -94,7 +123,7 @@
       : m_ptr(p), m_alloc(a) {}
 
    ~scoped_deallocator()
- { if (m_ptr) m_alloc.deallocate(m_ptr, 1); }
+ { if (m_ptr)priv_deallocate(alloc_version()); }
 
    void release()
    { m_ptr = 0; }
@@ -189,9 +218,22 @@
 class allocator_destroyer
 {
    typedef typename A::value_type value_type;
+ typedef detail::integral_constant<unsigned,
+ boost::interprocess::detail::
+ version<A>::value> alloc_version;
+ typedef detail::integral_constant<unsigned, 1> allocator_v1;
+ typedef detail::integral_constant<unsigned, 2> allocator_v2;
+
    private:
    A & a_;
 
+ private:
+ void priv_deallocate(const typename A::pointer &p, allocator_v1)
+ { a_.deallocate(p, 1); }
+
+ void priv_deallocate(const typename A::pointer &p, allocator_v2)
+ { a_.deallocate_one(p); }
+
    public:
    allocator_destroyer(A &a)
       : a_(a)
@@ -200,35 +242,86 @@
    void operator()(const typename A::pointer &p)
    {
       detail::get_pointer(p)->~value_type();
- a_.deallocate(p, 1);
+ priv_deallocate(p, alloc_version());
    }
 };
 
-//!A class used for exception-safe multi-allocation + construction.
-template <class Allocator>
-struct multiallocation_deallocator
+template <class A>
+class allocator_destroyer_and_chain_builder
 {
- typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_iterator multiallocation_iterator;
+ typedef typename A::multiallocation_chain multiallocation_chain;
 
- multiallocation_iterator m_itbeg;
- Allocator& m_alloc;
+ A & a_;
+ multiallocation_chain &c_;
 
- multiallocation_deallocator(multiallocation_iterator itbeg, Allocator& a)
- : m_itbeg(itbeg), m_alloc(a) {}
+ public:
+ allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
+ : a_(a), c_(c)
+ {}
+
+ void operator()(const typename A::pointer &p)
+ {
+ value_type *vp = detail::get_pointer(p);
+ vp->~value_type();
+ c_.push_back(vp);
+ }
+};
 
- ~multiallocation_deallocator()
+template <class A>
+class allocator_multialloc_chain_node_deallocator
+{
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_iterator multiallocation_iterator;
+ typedef typename A::multiallocation_chain multiallocation_chain;
+ typedef allocator_destroyer_and_chain_builder<A> chain_builder;
+
+ A & a_;
+ multiallocation_chain c_;
+
+ public:
+ allocator_multialloc_chain_node_deallocator(A &a)
+ : a_(a), c_()
+ {}
+
+ chain_builder get_chain_builder()
+ { return chain_builder(a_, c_); }
+
+ ~allocator_multialloc_chain_node_deallocator()
    {
- multiallocation_iterator endit;
- while(m_itbeg != endit){
- m_alloc.deallocate(&*m_itbeg, 1);
- ++m_itbeg;
- }
+ multiallocation_iterator it(c_.get_it());
+ if(it != multiallocation_iterator())
+ a_.deallocate_individual(it);
    }
-
- void increment()
- { ++m_itbeg; }
 };
 
+template <class A>
+class allocator_multialloc_chain_array_deallocator
+{
+ typedef typename A::value_type value_type;
+ typedef typename A::multiallocation_iterator multiallocation_iterator;
+ typedef typename A::multiallocation_chain multiallocation_chain;
+ typedef allocator_destroyer_and_chain_builder<A> chain_builder;
+
+ A & a_;
+ multiallocation_chain c_;
+
+ public:
+ allocator_multialloc_chain_array_deallocator(A &a)
+ : a_(a), c_()
+ {}
+
+ chain_builder get_chain_builder()
+ { return chain_builder(a_, c_); }
+
+ ~allocator_multialloc_chain_array_deallocator()
+ {
+ multiallocation_iterator it(c_.get_it());
+ if(it != multiallocation_iterator())
+ a_.deallocate_many(it);
+ }
+};
 
 //!A class used for exception-safe multi-allocation + construction.
 template <class Allocator>
@@ -577,6 +670,60 @@
 }
 #endif
 
+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 MultiallocChain, class T>
+class multiallocation_chain_adaptor
+{
+ private:
+ MultiallocChain chain_;
+
+ multiallocation_chain_adaptor
+ (const multiallocation_chain_adaptor &);
+ multiallocation_chain_adaptor &operator=
+ (const multiallocation_chain_adaptor &);
+
+ public:
+ typedef transform_iterator
+ < typename MultiallocChain::
+ multiallocation_iterator
+ , detail::cast_functor <T> > multiallocation_iterator;
+
+ multiallocation_chain_adaptor()
+ : chain_()
+ {}
+
+ void push_back(T *mem)
+ { chain_.push_back(mem); }
+
+ void push_front(T *mem)
+ { chain_.push_front(mem); }
+
+ void swap(multiallocation_chain_adaptor &other_chain)
+ { chain_.swap(other_chain.chain_); }
+
+ void splice_back(multiallocation_chain_adaptor &other_chain)
+ { chain_.splice_back(other_chain.chain_); }
+
+ T *pop_front()
+ { return static_cast<T*>(chain_.pop_front()); }
+
+ bool empty() const
+ { return chain_.empty(); }
+
+ multiallocation_iterator get_it() const
+ { return multiallocation_iterator(chain_.get_it()); }
+
+ std::size_t size() const
+ { return chain_.size(); }
+};
+
 } //namespace detail {
 
 //!The pair is movable if any of its members is movable

Modified: branches/release/boost/interprocess/detail/version_type.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/version_type.hpp (original)
+++ branches/release/boost/interprocess/detail/version_type.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/win32_api.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/win32_api.hpp (original)
+++ branches/release/boost/interprocess/detail/win32_api.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/detail/workaround.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/workaround.hpp (original)
+++ branches/release/boost/interprocess/detail/workaround.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -15,9 +15,13 @@
 
 #if !(defined BOOST_WINDOWS) || (defined BOOST_DISABLE_WIN32)
 
+ #include <unistd.h>
+
    #if defined(_POSIX_THREAD_PROCESS_SHARED)
    # if !((_XOPEN_VERSION >= 600) && (_POSIX_THREAD_PROCESS_SHARED - 0 <= 0))
- # if !defined(__CYGWIN__)
+ //Cygwin defines _POSIX_THREAD_PROCESS_SHARED but does not implement it.
+ //Mac Os X >= Leopard defines _POSIX_THREAD_PROCESS_SHARED but does not seems to work.
+ # if !defined(__CYGWIN__) && !defined(__APPLE__)
    # define BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
    # endif
    # endif
@@ -88,6 +92,10 @@
       #endif
    #endif
 
+ #if ((_POSIX_VERSION + 0)>= 200112L || (_XOPEN_VERSION + 0)>= 500)
+ #define BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
+ #endif
+
 #endif
 
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
@@ -102,7 +110,7 @@
 # endif
 #endif
 
-#if defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) || defined(BOOST_INTERPROCESS_VARIADIC_TEMPLATES)
+#if defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && defined(BOOST_INTERPROCESS_VARIADIC_TEMPLATES)
 #define BOOST_INTERPROCESS_PERFECT_FORWARDING
 #endif
 

Modified: branches/release/boost/interprocess/errors.hpp
==============================================================================
--- branches/release/boost/interprocess/errors.hpp (original)
+++ branches/release/boost/interprocess/errors.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/exceptions.hpp
==============================================================================
--- branches/release/boost/interprocess/exceptions.hpp (original)
+++ branches/release/boost/interprocess/exceptions.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/file_mapping.hpp
==============================================================================
--- branches/release/boost/interprocess/file_mapping.hpp (original)
+++ branches/release/boost/interprocess/file_mapping.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/indexes/flat_map_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/flat_map_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/flat_map_index.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/indexes/iset_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/iset_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/iset_index.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/indexes/iunordered_set_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/iunordered_set_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/iunordered_set_index.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -289,15 +289,14 @@
       size_type cur_size = this->size();
       size_type cur_count = this->bucket_count();
       bucket_ptr old_p = this->bucket_pointer();
- size_type sug_count;
       
       if(!this->size() && old_p != bucket_ptr(&this->init_bucket)){
- sug_count = 1;
          this->rehash(bucket_traits(bucket_ptr(&this->init_bucket), 1));
          destroy_buckets(this->alloc, old_p, cur_count);
       }
       else{
- sug_count = index_type::suggested_upper_bucket_count(cur_size);
+ size_type sug_count = 0; //gcc warning
+ sug_count = index_type::suggested_upper_bucket_count(cur_size);
 
          if(sug_count >= cur_count)
             return;

Modified: branches/release/boost/interprocess/indexes/map_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/map_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/map_index.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/indexes/null_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/null_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/null_index.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/indexes/unordered_map_index.hpp
==============================================================================
--- branches/release/boost/interprocess/indexes/unordered_map_index.hpp (original)
+++ branches/release/boost/interprocess/indexes/unordered_map_index.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/interprocess_fwd.hpp
==============================================================================
--- branches/release/boost/interprocess/interprocess_fwd.hpp (original)
+++ branches/release/boost/interprocess/interprocess_fwd.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -129,13 +129,19 @@
 template<class T, class SegmentManager, std::size_t NodesPerChunk = 64>
 class cached_node_allocator;
 
-template<class T, class SegmentManager, std::size_t NodesPerChunk = 64, std::size_t MaxFreeChunks = 2>
+template<class T, class SegmentManager, std::size_t NodesPerChunk = 64, std::size_t MaxFreeChunks = 2
+ , unsigned char OverheadPercent = 5
+>
 class adaptive_pool;
 
-template<class T, class SegmentManager, std::size_t NodesPerChunk = 64, std::size_t MaxFreeChunks = 2>
+template<class T, class SegmentManager, std::size_t NodesPerChunk = 64, std::size_t MaxFreeChunks = 2
+ , unsigned char OverheadPercent = 5
+>
 class private_adaptive_pool;
 
-template<class T, class SegmentManager, std::size_t NodesPerChunk = 64, std::size_t MaxFreeChunks = 2>
+template<class T, class SegmentManager, std::size_t NodesPerChunk = 64, std::size_t MaxFreeChunks = 2
+ , unsigned char OverheadPercent = 5
+>
 class cached_adaptive_pool;
 
 
@@ -151,10 +157,10 @@
 //////////////////////////////////////////////////////////////////////////////
 
 //Single segment memory allocation algorithms
-template<class MutexFamily, class VoidMutex = void*>//offset_ptr<void> >
+template<class MutexFamily, class VoidMutex = offset_ptr<void> >
 class simple_seq_fit;
 
-template<class MutexFamily, class VoidMutex = offset_ptr<void> >
+template<class MutexFamily, class VoidMutex = offset_ptr<void>, std::size_t MemAlignment = 0>
 class rbtree_best_fit;
 
 //////////////////////////////////////////////////////////////////////////////

Modified: branches/release/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- branches/release/boost/interprocess/ipc/message_queue.hpp (original)
+++ branches/release/boost/interprocess/ipc/message_queue.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/managed_external_buffer.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_external_buffer.hpp (original)
+++ branches/release/boost/interprocess/managed_external_buffer.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -20,6 +20,7 @@
 #include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/detail/managed_memory_impl.hpp>
 #include <boost/interprocess/detail/move.hpp>
+#include <cassert>
 
 //!\file
 //!Describes a named user memory allocation user class.
@@ -49,6 +50,8 @@
    basic_managed_external_buffer
       (create_only_t, void *addr, std::size_t size)
    {
+ //Check if alignment is correct
+ assert((0 == (((std::size_t)addr) & (AllocationAlgorithm::Alignment - std::size_t(1u)))));
       if(!base_t::create_impl(addr, size)){
          throw interprocess_exception();
       }
@@ -58,6 +61,8 @@
    basic_managed_external_buffer
       (open_only_t, void *addr, std::size_t size)
    {
+ //Check if alignment is correct
+ assert((0 == (((std::size_t)addr) & (AllocationAlgorithm::Alignment - std::size_t(1u)))));
       if(!base_t::open_impl(addr, size)){
          throw interprocess_exception();
       }

Modified: branches/release/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_heap_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_heap_memory.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_mapped_file.hpp (original)
+++ branches/release/boost/interprocess/managed_mapped_file.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_shared_memory.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_windows_shared_memory.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/mapped_region.hpp
==============================================================================
--- branches/release/boost/interprocess/mapped_region.hpp (original)
+++ branches/release/boost/interprocess/mapped_region.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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/allocators/allocation_type.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/type_traits.hpp>
+#include <boost/interprocess/detail/iterators.hpp>
 #include <boost/assert.hpp>
 #include <boost/static_assert.hpp>
 
@@ -100,10 +101,136 @@
    pointer operator->() const
    { return &(*(*this)); }
 
+ static basic_multiallocation_iterator create_simple_range(void *mem)
+ {
+ basic_multiallocation_iterator it;
+ typedef multi_allocation_next<VoidPointer> next_impl_t;
+ next_impl_t * tmp_mem = static_cast<next_impl_t*>(mem);
+ it = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
+ tmp_mem->next_ = 0;
+ return it;
+ }
+
    private:
    multi_allocation_next<VoidPointer> next_alloc_;
 };
 
+template<class VoidPointer>
+class basic_multiallocation_chain
+{
+ private:
+ basic_multiallocation_iterator<VoidPointer> it_;
+ VoidPointer last_mem_;
+ std::size_t num_mem_;
+
+ basic_multiallocation_chain(const basic_multiallocation_chain &);
+ basic_multiallocation_chain &operator=(const basic_multiallocation_chain &);
+
+ public:
+ typedef basic_multiallocation_iterator<VoidPointer> multiallocation_iterator;
+
+ basic_multiallocation_chain()
+ : it_(0), last_mem_(0), num_mem_(0)
+ {}
+
+ void reset()
+ {
+ this->it_ = multiallocation_iterator();
+ this->last_mem_ = 0;
+ this->num_mem_ = 0;
+ }
+
+ void push_back(void *mem)
+ {
+ typedef multi_allocation_next<VoidPointer> next_impl_t;
+ next_impl_t * tmp_mem = static_cast<next_impl_t*>(mem);
+
+ if(!this->last_mem_){
+ this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
+ }
+ else{
+ static_cast<next_impl_t*>(detail::get_pointer(this->last_mem_))->next_ = tmp_mem;
+ }
+ tmp_mem->next_ = 0;
+ this->last_mem_ = tmp_mem;
+ ++num_mem_;
+ }
+
+ void push_front(void *mem)
+ {
+ typedef multi_allocation_next<VoidPointer> next_impl_t;
+ next_impl_t * tmp_mem = static_cast<next_impl_t*>(mem);
+ ++num_mem_;
+
+ if(!this->last_mem_){
+ this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
+ tmp_mem->next_ = 0;
+ this->last_mem_ = tmp_mem;
+ }
+ else{
+ next_impl_t * old_first = (next_impl_t*)(&*this->it_);
+ tmp_mem->next_ = old_first;
+ this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
+ }
+ }
+
+ void swap(basic_multiallocation_chain &other_chain)
+ {
+ std::swap(this->it_, other_chain.it_);
+ std::swap(this->last_mem_, other_chain.last_mem_);
+ std::swap(this->num_mem_, other_chain.num_mem_);
+ }
+
+ void splice_back(basic_multiallocation_chain &other_chain)
+ {
+ typedef multi_allocation_next<VoidPointer> next_impl_t;
+ multiallocation_iterator end_it;
+ multiallocation_iterator other_it = other_chain.get_it();
+ multiallocation_iterator this_it = this->get_it();
+ if(end_it == other_it){
+ return;
+ }
+ else if(end_it == this_it){
+ this->swap(other_chain);
+ }
+ else{
+ static_cast<next_impl_t*>(detail::get_pointer(this->last_mem_))->next_
+ = (next_impl_t*)&*other_chain.it_;
+ this->last_mem_ = other_chain.last_mem_;
+ this->num_mem_ += other_chain.num_mem_;
+ }
+ }
+
+ void *pop_front()
+ {
+ multiallocation_iterator itend;
+ if(this->it_ == itend){
+ this->last_mem_= 0;
+ this->num_mem_ = 0;
+ return 0;
+ }
+ else{
+ void *addr = &*it_;
+ ++it_;
+ --num_mem_;
+ if(!num_mem_){
+ this->last_mem_ = 0;
+ this->it_ = multiallocation_iterator();
+ }
+ return addr;
+ }
+ }
+
+ bool empty() const
+ { return !num_mem_; }
+
+ multiallocation_iterator get_it() const
+ { return it_; }
+
+ std::size_t size() const
+ { return num_mem_; }
+};
+
 
 //!This class implements several allocation functions shared by different algorithms
 //!(aligned allocation, multiple allocation...).
@@ -125,6 +252,7 @@
    static const std::size_t AllocatedCtrlUnits = MemoryAlgorithm::AllocatedCtrlUnits;
    static const std::size_t BlockCtrlBytes = MemoryAlgorithm::BlockCtrlBytes;
    static const std::size_t BlockCtrlUnits = MemoryAlgorithm::BlockCtrlUnits;
+ static const std::size_t UsableByPreviousChunk = MemoryAlgorithm::UsableByPreviousChunk;
 
    static void assert_alignment(const void *ptr)
    { assert_alignment((std::size_t)ptr); }
@@ -165,10 +293,11 @@
    static void* allocate_aligned
       (MemoryAlgorithm *memory_algo, std::size_t nbytes, std::size_t alignment)
    {
+
       //Ensure power of 2
       if ((alignment & (alignment - std::size_t(1u))) != 0){
          //Alignment is not power of two
- BOOST_ASSERT((alignment & (alignment - std::size_t(1u))) != 0);
+ BOOST_ASSERT((alignment & (alignment - std::size_t(1u))) == 0);
          return 0;
       }
 
@@ -176,6 +305,9 @@
       if(alignment <= Alignment){
          return memory_algo->priv_allocate(allocate_new, nbytes, nbytes, real_size).first;
       }
+
+ if(nbytes > UsableByPreviousChunk)
+ nbytes -= UsableByPreviousChunk;
       
       //We can find a aligned portion if we allocate a chunk that has alignment
       //nbytes + alignment bytes or more.
@@ -191,7 +323,9 @@
       // | MBU |
       // -----------------------------------------------------
       std::size_t request =
- minimum_allocation + (2*MinBlockUnits*Alignment - AllocatedCtrlBytes);
+ minimum_allocation + (2*MinBlockUnits*Alignment - AllocatedCtrlBytes
+ //prevsize - UsableByPreviousChunk
+ );
 
       //Now allocate the buffer
       void *buffer = memory_algo->priv_allocate(allocate_new, request, request, real_size).first;
@@ -207,7 +341,8 @@
             max_value(ceil_units(nbytes) + AllocatedCtrlUnits, std::size_t(MinBlockUnits));
          //We can create a new block in the end of the segment
          if(old_size >= (first_min_units + MinBlockUnits)){
- block_ctrl *second = new((char*)first + Alignment*first_min_units) block_ctrl;
+ //block_ctrl *second = new((char*)first + Alignment*first_min_units) block_ctrl;
+ block_ctrl *second = (block_ctrl *)((char*)first + Alignment*first_min_units);
             first->m_size = first_min_units;
             second->m_size = old_size - first->m_size;
             BOOST_ASSERT(second->m_size >= MinBlockUnits);
@@ -285,6 +420,7 @@
       ,const std::size_t max_size, const std::size_t preferred_size
       ,std::size_t &received_size)
    {
+ (void)memory_algo;
       //Obtain the real block
       block_ctrl *block = memory_algo->priv_get_block(ptr);
       std::size_t old_block_units = block->m_size;
@@ -296,11 +432,11 @@
       assert_alignment(ptr);
 
       //Put this to a safe value
- received_size = (old_block_units - AllocatedCtrlUnits)*Alignment;
+ received_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
 
       //Now translate it to Alignment units
- const std::size_t max_user_units = floor_units(max_size);
- const std::size_t preferred_user_units = ceil_units(preferred_size);
+ const std::size_t max_user_units = floor_units(max_size - UsableByPreviousChunk);
+ const std::size_t preferred_user_units = ceil_units(preferred_size - UsableByPreviousChunk);
 
       //Check if rounded max and preferred are possible correct
       if(max_user_units < preferred_user_units)
@@ -331,7 +467,7 @@
       }
 
       //Update new size
- received_size = shrunk_user_units*Alignment;
+ received_size = shrunk_user_units*Alignment + UsableByPreviousChunk;
       return true;
    }
 
@@ -350,22 +486,23 @@
       }
 
       //Check if the old size was just the shrunk size (no splitting)
- if((old_block_units - AllocatedCtrlUnits) == ceil_units(preferred_size))
+ if((old_block_units - AllocatedCtrlUnits) == ceil_units(preferred_size - UsableByPreviousChunk))
          return true;
 
       //Now we can just rewrite the size of the old buffer
- block->m_size = received_size/Alignment + AllocatedCtrlUnits;
+ block->m_size = (received_size-UsableByPreviousChunk)/Alignment + AllocatedCtrlUnits;
       BOOST_ASSERT(block->m_size >= BlockCtrlUnits);
- memory_algo->priv_mark_new_allocated_block(block);
 
       //We create the new block
- block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + block->m_size*Alignment)) block_ctrl;
-
+// block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
+// (detail::char_ptr_cast(block) + block->m_size*Alignment)) block_ctrl;
+ block_ctrl *new_block = reinterpret_cast<block_ctrl*>
+ (detail::char_ptr_cast(block) + block->m_size*Alignment);
       //Write control data to simulate this new block was previously allocated
       //and deallocate it
       new_block->m_size = old_block_units - block->m_size;
       BOOST_ASSERT(new_block->m_size >= BlockCtrlUnits);
+ memory_algo->priv_mark_new_allocated_block(block);
       memory_algo->priv_mark_new_allocated_block(new_block);
       memory_algo->priv_deallocate(memory_algo->priv_get_user_buffer(new_block));
       return true;
@@ -401,11 +538,11 @@
       multi_allocation_next_ptr first = 0, previous = 0;
       std::size_t low_idx = 0;
       while(low_idx < n_elements){
- std::size_t total_bytes = total_request_units*Alignment - AllocatedCtrlBytes;
+ std::size_t total_bytes = total_request_units*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk;
          std::size_t min_allocation = (!sizeof_element)
             ? elem_units
             : memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element);
- min_allocation = min_allocation*Alignment - AllocatedCtrlBytes;
+ min_allocation = min_allocation*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk;
 
          std::size_t received_size;
          std::pair<void *, bool> ret = memory_algo->priv_allocate
@@ -419,6 +556,7 @@
          char *block_address = (char*)block;
 
          std::size_t total_used_units = 0;
+// block_ctrl *prev_block = 0;
          while(total_used_units < received_units){
             if(sizeof_element){
                elem_units = memory_algo->priv_get_total_units(elem_sizes[low_idx]*sizeof_element);
@@ -428,7 +566,10 @@
                break;
             total_request_units -= elem_units;
             //This is the position where the new block must be created
- block_ctrl *new_block = new(block_address)block_ctrl;
+// if(prev_block)
+// memory_algo->priv_mark_new_allocated_block(prev_block);
+ block_ctrl *new_block = (block_ctrl *)(block_address);
+// block_ctrl *new_block = new(block_address)block_ctrl;
             assert_alignment(new_block);
 
             //The last block should take all the remaining space
@@ -446,18 +587,19 @@
                //split it obtaining a new free memory block do it.
                if((received_units - total_used_units) >= (elem_units + MemoryAlgorithm::BlockCtrlUnits)){
                   std::size_t shrunk_received;
- std::size_t shrunk_request = elem_units*Alignment - AllocatedCtrlBytes;
- bool ret = shrink
+ std::size_t shrunk_request = elem_units*Alignment - AllocatedCtrlBytes + UsableByPreviousChunk;
+ bool shrink_ok = shrink
                         (memory_algo
                         ,memory_algo->priv_get_user_buffer(new_block)
                         ,shrunk_request
                         ,shrunk_request
                         ,shrunk_received);
+ (void)shrink_ok;
                   //Shrink must always succeed with passed parameters
- BOOST_ASSERT(ret);
+ BOOST_ASSERT(shrink_ok);
                   //Some sanity checks
                   BOOST_ASSERT(shrunk_request == shrunk_received);
- BOOST_ASSERT(elem_units == (shrunk_request/Alignment + AllocatedCtrlUnits));
+ BOOST_ASSERT(elem_units == ((shrunk_request-UsableByPreviousChunk)/Alignment + AllocatedCtrlUnits));
                   //"new_block->m_size" must have been reduced to elem_units by "shrink"
                   BOOST_ASSERT(new_block->m_size == elem_units);
                   //Now update the total received units with the reduction
@@ -483,6 +625,7 @@
             }
             previous = p;
             ++low_idx;
+ //prev_block = new_block;
          }
          //Sanity check
          BOOST_ASSERT(total_used_units == received_units);

Modified: branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -64,6 +64,8 @@
 
    typedef detail::basic_multiallocation_iterator
       <void_pointer> multiallocation_iterator;
+ typedef detail::basic_multiallocation_chain
+ <void_pointer> multiallocation_chain;
 
    private:
    class block_ctrl;
@@ -137,6 +139,9 @@
    //!Multiple element allocation, different size
    multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
 
+ //!Multiple element deallocation
+ void deallocate_many(multiallocation_iterator it);
+
    /// @endcond
 
    //!Deallocates previously allocated bytes
@@ -170,8 +175,13 @@
                            std::size_t preferred_size,std::size_t &received_size,
                            T *reuse_ptr = 0);
 
+ std::pair<void *, bool>
+ raw_allocation_command (allocation_type command, std::size_t limit_size,
+ std::size_t preferred_size,std::size_t &received_size,
+ void *reuse_ptr = 0, std::size_t sizeof_object = 1);
+
    //!Returns the size of the buffer previously allocated pointed by ptr
- std::size_t size(void *ptr) const;
+ std::size_t size(const void *ptr) const;
 
    //!Allocates aligned bytes, returns 0 if there is not more memory.
    //!Alignment must be power of 2
@@ -247,13 +257,16 @@
 
    void priv_mark_new_allocated_block(block_ctrl *block);
 
+ public:
    static const std::size_t Alignment = detail::alignment_of<detail::max_align>::value;
+ private:
    static const std::size_t BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
    static const std::size_t BlockCtrlUnits = BlockCtrlBytes/Alignment;
    static const std::size_t MinBlockUnits = BlockCtrlUnits;
    static const std::size_t MinBlockSize = MinBlockUnits*Alignment;
    static const std::size_t AllocatedCtrlBytes = BlockCtrlBytes;
    static const std::size_t AllocatedCtrlUnits = BlockCtrlUnits;
+ static const std::size_t UsableByPreviousChunk = 0;
 
    public:
    static const std::size_t PayloadPerAllocation = BlockCtrlBytes;
@@ -381,6 +394,7 @@
 
    std::size_t received_size;
    void *addr = priv_check_and_allocate(last_units, prev, last, received_size);
+ (void)addr;
    assert(addr);
    assert(received_size == last_units*Alignment - AllocatedCtrlBytes);
    
@@ -549,19 +563,34 @@
                         std::size_t preferred_size,std::size_t &received_size,
                         T *reuse_ptr)
 {
- if(command & try_shrink_in_place){
- bool success =
- algo_impl_t::try_shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
- return std::pair<T *, bool> ((success ? reuse_ptr : 0), true);
- }
    std::pair<void*, bool> ret = priv_allocation_command
       (command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
+
    BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
    return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);
 }
 
 template<class MutexFamily, class VoidPointer>
 inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
+ raw_allocation_command (allocation_type command, std::size_t limit_objects,
+ std::size_t preferred_objects,std::size_t &received_objects,
+ void *reuse_ptr, std::size_t sizeof_object)
+{
+ if(!sizeof_object)
+ return std::pair<void *, bool>(0, 0);
+ if(command & try_shrink_in_place){
+ bool success = algo_impl_t::try_shrink
+ ( this, reuse_ptr, limit_objects*sizeof_object
+ , preferred_objects*sizeof_object, received_objects);
+ received_objects /= sizeof_object;
+ return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
+ }
+ return priv_allocation_command
+ (command, limit_objects, preferred_objects, received_objects, reuse_ptr, sizeof_object);
+}
+
+template<class MutexFamily, class VoidPointer>
+inline std::pair<void*, bool> simple_seq_fit_impl<MutexFamily, VoidPointer>::
    priv_allocation_command (allocation_type command, std::size_t limit_size,
                        std::size_t preferred_size, std::size_t &received_size,
                        void *reuse_ptr, std::size_t sizeof_object)
@@ -589,13 +618,13 @@
 
 template<class MutexFamily, class VoidPointer>
 inline std::size_t simple_seq_fit_impl<MutexFamily, VoidPointer>::
- size(void *ptr) const
+ size(const void *ptr) const
 {
    //We need no synchronization since this block is not going
    //to be modified
    //Obtain the real size of the block
    block_ctrl *block = reinterpret_cast<block_ctrl*>
- (priv_get_block(detail::char_ptr_cast(ptr)));
+ (priv_get_block(detail::char_ptr_cast(const_cast<void*>(ptr))));
    return block->get_user_bytes();
 }
 
@@ -690,6 +719,20 @@
 }
 
 template<class MutexFamily, class VoidPointer>
+inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::
+ deallocate_many(typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator it)
+{
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ while(it){
+ void *addr = &*it;
+ ++it;
+ this->priv_deallocate(addr);
+ }
+}
+
+template<class MutexFamily, class VoidPointer>
 inline typename simple_seq_fit_impl<MutexFamily, VoidPointer>::multiallocation_iterator
    simple_seq_fit_impl<MutexFamily, VoidPointer>::
    allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)

Modified: branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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,7 +60,7 @@
 
 //!This class implements an algorithm that stores the free nodes in a red-black tree
 //!to have logarithmic search/insert times.
-template<class MutexFamily, class VoidPointer>
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 class rbtree_best_fit
 {
    /// @cond
@@ -77,6 +77,8 @@
    typedef VoidPointer void_pointer;
    typedef detail::basic_multiallocation_iterator
       <void_pointer> multiallocation_iterator;
+ typedef detail::basic_multiallocation_chain
+ <void_pointer> multiallocation_chain;
 
    /// @cond
 
@@ -106,9 +108,9 @@
    {
       //!This block's memory size (including block_ctrl
       //!header) in Alignment units
- std::size_t m_prev_size : sizeof(std::size_t)*CHAR_BIT - 1;
- std::size_t m_end : 1;
- std::size_t m_size : sizeof(std::size_t)*CHAR_BIT - 1;
+ std::size_t m_prev_size : sizeof(std::size_t)*CHAR_BIT;
+ std::size_t m_size : sizeof(std::size_t)*CHAR_BIT - 2;
+ std::size_t m_prev_allocated : 1;
       std::size_t m_allocated : 1;
    };
 
@@ -117,7 +119,7 @@
       : public SizeHolder, public TreeHook
    {
       block_ctrl()
- { this->m_end = 0; this->m_size = 0; this->m_allocated = 0; }
+ { this->m_size = 0; this->m_allocated = 0, this->m_prev_allocated = 0; }
 
       friend bool operator<(const block_ctrl &a, const block_ctrl &b)
       { return a.m_size < b.m_size; }
@@ -195,6 +197,9 @@
    //!Multiple element allocation, different size
    multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element);
 
+ //!Multiple element allocation, different size
+ void deallocate_many(multiallocation_iterator it);
+
    /// @endcond
 
    //!Deallocates previously allocated bytes
@@ -230,6 +235,11 @@
                            std::size_t preferred_size,std::size_t &received_size,
                            T *reuse_ptr = 0);
 
+ std::pair<void *, bool>
+ raw_allocation_command (allocation_type command, std::size_t limit_object,
+ std::size_t preferred_object,std::size_t &received_object,
+ void *reuse_ptr = 0, std::size_t sizeof_object = 1);
+
    //!Returns the size of the buffer previously allocated pointed by ptr
    std::size_t size(const void *ptr) const;
 
@@ -279,17 +289,14 @@
                                ,bool only_preferred_backwards
                                ,std::size_t backwards_multiple);
 
- //!Set the size in the tail of the block
- void priv_tail_size(block_ctrl *ptr, std::size_t size);
+ //!Get poitner of the previous block (previous block must be free)
+ block_ctrl * priv_prev_block(block_ctrl *ptr);
 
- //!Real private aligned allocation function
- //void* priv_allocate_aligned (std::size_t nbytes, std::size_t alignment);
+ //!Returns true if the previous block is allocated
+ bool priv_is_prev_allocated(block_ctrl *ptr);
 
- //!Get the size in the tail of the block
- std::size_t priv_tail_size(block_ctrl *ptr);
-
- //!Get the size in the tail of the previous block
- block_ctrl * priv_prev_block(block_ctrl *ptr);
+ //!Get a pointer of the "end" block from the first block of the segment
+ block_ctrl * priv_end_block(block_ctrl *first_segment_block);
 
    //!Get the size in the tail of the previous block
    block_ctrl * priv_next_block(block_ctrl *ptr);
@@ -316,44 +323,50 @@
 
    void priv_mark_new_allocated_block(block_ctrl *block);
 
- static const std::size_t Alignment = detail::alignment_of<detail::max_align>::value;
+ public:
+
+ static const std::size_t Alignment = !MemAlignment
+ ? detail::alignment_of<detail::max_align>::value
+ : MemAlignment
+ ;
+
+ private:
    //Due to embedded bits in size, Alignment must be at least 2
- BOOST_STATIC_ASSERT((Alignment >= 2));
+ BOOST_STATIC_ASSERT((Alignment >= 4));
    //Due to rbtree size optimizations, Alignment must have at least pointer alignment
    BOOST_STATIC_ASSERT((Alignment >= detail::alignment_of<void_pointer>::value));
    static const std::size_t AlignmentMask = (Alignment - 1);
    static const std::size_t BlockCtrlBytes = detail::ct_rounded_size<sizeof(block_ctrl), Alignment>::value;
    static const std::size_t BlockCtrlUnits = BlockCtrlBytes/Alignment;
- static const std::size_t AllocatedCtrlBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
- static const std::size_t AllocatedCtrlUnits = AllocatedCtrlBytes/Alignment;
+ static const std::size_t AllocatedCtrlBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
+ static const std::size_t AllocatedCtrlUnits = AllocatedCtrlBytes/Alignment;
    static const std::size_t EndCtrlBlockBytes = detail::ct_rounded_size<sizeof(SizeHolder), Alignment>::value;
- static const std::size_t EndCtrlBlockUnits = EndCtrlBlockBytes/Alignment;
- static const std::size_t MinBlockUnits = BlockCtrlUnits;
+ static const std::size_t EndCtrlBlockUnits = EndCtrlBlockBytes/Alignment;
+ static const std::size_t MinBlockUnits = BlockCtrlUnits;
+ static const std::size_t UsableByPreviousChunk = sizeof(std::size_t);
 
    //Make sure the maximum alignment is power of two
    BOOST_STATIC_ASSERT((0 == (Alignment & (Alignment - std::size_t(1u)))));
    /// @endcond
    public:
- static const std::size_t PayloadPerAllocation = AllocatedCtrlBytes;
+ static const std::size_t PayloadPerAllocation = AllocatedCtrlBytes - UsableByPreviousChunk;
 };
 
-template<class MutexFamily, class VoidPointer>
-inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>
    ::priv_first_block_offset(const void *this_ptr, std::size_t extra_hdr_bytes)
 {
- //First align "this" pointer
- std::size_t uint_this = (std::size_t)this_ptr;
- std::size_t uint_aligned_this = uint_this/Alignment*Alignment;
- std::size_t this_disalignment = (uint_this - uint_aligned_this);
- std::size_t block1_off =
- detail::get_rounded_size(sizeof(rbtree_best_fit) + extra_hdr_bytes + this_disalignment, Alignment)
- - this_disalignment;
- algo_impl_t::assert_alignment(this_disalignment + block1_off);
+ std::size_t uint_this = (std::size_t)this_ptr;
+ std::size_t main_hdr_end = uint_this + sizeof(rbtree_best_fit) + extra_hdr_bytes;
+ std::size_t aligned_main_hdr_end = detail::get_rounded_size(main_hdr_end, Alignment);
+ std::size_t block1_off = aligned_main_hdr_end - uint_this;
+ algo_impl_t::assert_alignment(aligned_main_hdr_end);
+ algo_impl_t::assert_alignment(uint_this + block1_off);
    return block1_off;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    rbtree_best_fit(std::size_t size, std::size_t extra_hdr_bytes)
 {
    //Initialize the header
@@ -368,26 +381,25 @@
    priv_add_segment(detail::char_ptr_cast(this) + block1_off, size - block1_off);
 }
 
-template<class MutexFamily, class VoidPointer>
-inline rbtree_best_fit<MutexFamily, VoidPointer>::~rbtree_best_fit()
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::~rbtree_best_fit()
 {
    //There is a memory leak!
 // assert(m_header.m_allocated == 0);
 // assert(m_header.m_root.m_next->m_next == block_ctrl_ptr(&m_header.m_root));
 }
 
-template<class MutexFamily, class VoidPointer>
-void rbtree_best_fit<MutexFamily, VoidPointer>::grow(std::size_t extra_size)
-{
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::grow(std::size_t extra_size)
+{
    //Get the address of the first block
    std::size_t block1_off =
       priv_first_block_offset(this, m_header.m_extra_hdr_bytes);
 
    block_ctrl *first_block = reinterpret_cast<block_ctrl *>
                                  (detail::char_ptr_cast(this) + block1_off);
- block_ctrl *old_end_block = priv_prev_block(first_block);
+ block_ctrl *old_end_block = priv_end_block(first_block);
    assert(priv_is_allocated_block(old_end_block));
- assert(old_end_block->m_end);
    std::size_t old_border_offset = (detail::char_ptr_cast(old_end_block) -
                                     detail::char_ptr_cast(this)) + EndCtrlBlockBytes;
 
@@ -406,18 +418,16 @@
       (detail::char_ptr_cast(old_end_block) + align_offset*Alignment);
    new_end_block->m_size = (detail::char_ptr_cast(first_block) -
                                  detail::char_ptr_cast(new_end_block))/Alignment;
+ first_block->m_prev_size = new_end_block->m_size;
    assert(first_block == priv_next_block(new_end_block));
- new_end_block->m_end = 1;
    priv_mark_new_allocated_block(new_end_block);
-
- assert(new_end_block == priv_prev_block(first_block));
+
+ assert(new_end_block == priv_end_block(first_block));
 
    //The old end block is the new block
- std::size_t old_end_prev = old_end_block->m_prev_size;
- block_ctrl *new_block = new(old_end_block)block_ctrl;
+ block_ctrl *new_block = old_end_block;
    new_block->m_size = (detail::char_ptr_cast(new_end_block) -
                         detail::char_ptr_cast(new_block))/Alignment;
- new_block->m_prev_size = old_end_prev;
    assert(new_block->m_size >= BlockCtrlUnits);
    priv_mark_new_allocated_block(new_block);
    assert(priv_next_block(new_block) == new_end_block);
@@ -428,8 +438,8 @@
    this->priv_deallocate(priv_get_user_buffer(new_block));
 }
 
-template<class MutexFamily, class VoidPointer>
-void rbtree_best_fit<MutexFamily, VoidPointer>::shrink_to_fit()
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::shrink_to_fit()
 {
    //Get the address of the first block
    std::size_t block1_off =
@@ -439,32 +449,36 @@
                                  (detail::char_ptr_cast(this) + block1_off);
    algo_impl_t::assert_alignment(first_block);
 
- block_ctrl *old_end_block = priv_prev_block(first_block);
+ block_ctrl *old_end_block = priv_end_block(first_block);
    algo_impl_t::assert_alignment(old_end_block);
    assert(priv_is_allocated_block(old_end_block));
- assert(old_end_block->m_end);
 
- block_ctrl *last_block = priv_prev_block(old_end_block);
    algo_impl_t::assert_alignment(old_end_block);
 
- std::size_t old_end_block_size = old_end_block->m_size;
+ std::size_t old_end_block_size = old_end_block->m_size;
 
- void *unique_block = 0;
- if(last_block == first_block){
+ void *unique_buffer = 0;
+ block_ctrl *last_block;
+ if(priv_next_block(first_block) == old_end_block){
       std::size_t ignore;
- unique_block = priv_allocate(allocate_new, 0, 0, ignore).first;
- if(!unique_block)
+ unique_buffer = priv_allocate(allocate_new, 0, 0, ignore).first;
+ if(!unique_buffer)
          return;
+ algo_impl_t::assert_alignment(unique_buffer);
+ block_ctrl *unique_block = priv_get_block(unique_buffer);
+ assert(priv_is_allocated_block(unique_block));
       algo_impl_t::assert_alignment(unique_block);
- last_block = priv_prev_block(old_end_block);
+ last_block = priv_next_block(unique_block);
+ assert(!priv_is_allocated_block(last_block));
       algo_impl_t::assert_alignment(last_block);
    }
+ else{
+ if(priv_is_prev_allocated(old_end_block))
+ return;
+ last_block = priv_prev_block(old_end_block);
+ }
 
- //The last block must be free to be able to shrink
- if(priv_is_allocated_block(last_block))
- return;
-
- std::size_t last_block_size = last_block->m_size;
+ std::size_t last_block_size = last_block->m_size;
 
    //Erase block from the free tree, since we will erase it
    m_header.m_imultiset.erase(Imultiset::s_iterator_to(*last_block));
@@ -474,20 +488,23 @@
    
    block_ctrl *new_end_block = last_block;
    algo_impl_t::assert_alignment(new_end_block);
- priv_mark_as_allocated_block(new_end_block);
- new_end_block->m_end = 1;
    new_end_block->m_size = old_end_block_size + last_block_size;
- priv_tail_size(new_end_block, new_end_block->m_size);
- assert(priv_prev_block(first_block) == new_end_block);
+ priv_mark_as_allocated_block(new_end_block);
+
+ //Although the first block might be allocated, we'll
+ //store the offset to the end block since in the previous
+ //offset can't be overwritten by a previous block
+ first_block->m_prev_size = new_end_block->m_size;
+ assert(priv_end_block(first_block) == new_end_block);
 
    //Update managed buffer's size
    m_header.m_size = shrunk_border_offset;
- if(unique_block)
- priv_deallocate(unique_block);
+ if(unique_buffer)
+ priv_deallocate(unique_buffer);
 }
 
-template<class MutexFamily, class VoidPointer>
-void rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_add_segment(void *addr, std::size_t size)
 {
    //Check alignment
@@ -506,17 +523,15 @@
          (detail::char_ptr_cast(addr) + first_big_block->m_size*Alignment))SizeHolder);
 
    //This will overwrite the prev part of the "end" node
- priv_tail_size(first_big_block, first_big_block->m_size);
    priv_mark_as_free_block (first_big_block);
    first_big_block->m_prev_size = end_block->m_size =
       (detail::char_ptr_cast(first_big_block) - detail::char_ptr_cast(end_block))/Alignment;
- end_block->m_end = 1;
- end_block->m_allocated = 1;
+ priv_mark_as_allocated_block(end_block);
 
    assert(priv_next_block(first_big_block) == end_block);
- assert(priv_prev_block(end_block) == first_big_block);
    assert(priv_next_block(end_block) == first_big_block);
- assert(priv_prev_block(first_big_block) == end_block);
+ assert(priv_end_block(first_big_block) == end_block);
+ assert(priv_prev_block(end_block) == first_big_block);
 
    //Some check to validate the algorithm, since it makes some assumptions
    //to optimize the space wasted in bookkeeping:
@@ -530,27 +545,24 @@
    m_header.m_imultiset.insert(*first_big_block);
 }
 
-template<class MutexFamily, class VoidPointer>
-inline void rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_mark_new_allocated_block(block_ctrl *new_block)
-{
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_allocated_block(new_block);
-}
+{ priv_mark_as_allocated_block(new_block); }
 
-template<class MutexFamily, class VoidPointer>
-inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::get_size() const
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::get_size() const
 { return m_header.m_size; }
 
-template<class MutexFamily, class VoidPointer>
-inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::get_free_memory() const
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::get_free_memory() const
 {
    return m_header.m_size - m_header.m_allocated -
       priv_first_block_offset(this, m_header.m_extra_hdr_bytes);
 }
 
-template<class MutexFamily, class VoidPointer>
-inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    get_min_size (std::size_t extra_hdr_bytes)
 {
    return (algo_impl_t::ceil_units(sizeof(rbtree_best_fit)) +
@@ -558,8 +570,8 @@
            MinBlockUnits + EndCtrlBlockUnits)*Alignment;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline bool rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
     all_memory_deallocated()
 {
    //-----------------------
@@ -575,8 +587,8 @@
          (m_header.m_size - block1_off - EndCtrlBlockBytes)/Alignment;
 }
 
-template<class MutexFamily, class VoidPointer>
-bool rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
     check_sanity()
 {
    //-----------------------
@@ -609,8 +621,8 @@
    return true;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline void* rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    allocate(std::size_t nbytes)
 {
    //-----------------------
@@ -621,8 +633,8 @@
    return ret;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline void* rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    allocate_aligned(std::size_t nbytes, std::size_t alignment)
 {
    //-----------------------
@@ -631,26 +643,42 @@
    return algo_impl_t::allocate_aligned(this, nbytes, alignment);
 }
 
-template<class MutexFamily, class VoidPointer>
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 template<class T>
-inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer>::
+inline std::pair<T*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    allocation_command (allocation_type command, std::size_t limit_size,
                         std::size_t preferred_size,std::size_t &received_size,
                         T *reuse_ptr)
 {
- if(command & try_shrink_in_place){
- bool success =
- algo_impl_t::try_shrink(this, reuse_ptr, limit_size, preferred_size, received_size);
- return std::pair<T *, bool> ((success ? reuse_ptr : 0), true);
- }
    std::pair<void*, bool> ret = priv_allocation_command
       (command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
+
    BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
    return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);
 }
 
-template<class MutexFamily, class VoidPointer>
-inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
+ raw_allocation_command (allocation_type command, std::size_t limit_objects,
+ std::size_t preferred_objects,std::size_t &received_objects,
+ void *reuse_ptr, std::size_t sizeof_object)
+{
+ if(!sizeof_object)
+ return std::pair<void *, bool>(0, 0);
+ if(command & try_shrink_in_place){
+ bool success = algo_impl_t::try_shrink
+ ( this, reuse_ptr, limit_objects*sizeof_object
+ , preferred_objects*sizeof_object, received_objects);
+ received_objects /= sizeof_object;
+ return std::pair<void *, bool> ((success ? reuse_ptr : 0), true);
+ }
+ return priv_allocation_command
+ (command, limit_objects, preferred_objects, received_objects, reuse_ptr, sizeof_object);
+}
+
+
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::pair<void*, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_allocation_command (allocation_type command, std::size_t limit_size,
                        std::size_t preferred_size,std::size_t &received_size,
                        void *reuse_ptr, std::size_t sizeof_object)
@@ -673,18 +701,18 @@
    return ret;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline std::size_t rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    size(const void *ptr) const
 {
    //We need no synchronization since this block's size is not going
    //to be modified by anyone else
    //Obtain the real size of the block
- return (priv_get_block(ptr)->m_size - AllocatedCtrlUnits)*Alignment;
+ return (priv_get_block(ptr)->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline void rbtree_best_fit<MutexFamily, VoidPointer>::zero_free_memory()
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::zero_free_memory()
 {
    //-----------------------
    boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
@@ -700,8 +728,8 @@
    }
 }
 
-template<class MutexFamily, class VoidPointer>
-void* rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_expand_both_sides(allocation_type command
                          ,std::size_t min_size
                          ,std::size_t preferred_size
@@ -717,7 +745,7 @@
    }
    else{
       received_size = this->size(reuse_ptr);
- if(received_size >= preferred_size)
+ if(received_size >= preferred_size || received_size >= min_size)
          return reuse_ptr;
    }
 
@@ -731,18 +759,21 @@
       block_ctrl *reuse = priv_get_block(reuse_ptr);
 
       //Sanity check
- assert(reuse->m_size == priv_tail_size(reuse));
+ //assert(reuse->m_size == priv_tail_size(reuse));
       algo_impl_t::assert_alignment(reuse);
 
       block_ctrl *prev_block;
 
       //If the previous block is not free, there is nothing to do
- if(priv_is_allocated_block(prev_block = priv_prev_block(reuse))){
+ if(priv_is_prev_allocated(reuse)){
          return 0;
       }
 
+ prev_block = priv_prev_block(reuse);
+ assert(!priv_is_allocated_block(prev_block));
+
       //Some sanity checks
- assert(prev_block->m_size == priv_tail_size(prev_block));
+ assert(prev_block->m_size == reuse->m_prev_size);
       algo_impl_t::assert_alignment(prev_block);
 
       //Let's calculate the number of extra bytes of data before the current
@@ -769,32 +800,41 @@
       if(std::size_t(prev_block->m_size*Alignment) >= needs_backwards_aligned){
          //Now take all next space. This will succeed
          if(command & expand_fwd){
- if(!priv_expand(reuse_ptr, received_size, received_size, received_size)){
+ std::size_t received_size2;
+ if(!priv_expand(reuse_ptr, received_size, received_size, received_size2)){
                assert(0);
             }
+ assert(received_size = received_size2);
          }
          //We need a minimum size to split the previous one
          if(prev_block->m_size >= (needs_backwards_aligned/Alignment + BlockCtrlUnits)){
             block_ctrl *new_block = reinterpret_cast<block_ctrl *>
                (detail::char_ptr_cast(reuse) - needs_backwards_aligned);
 
- //Erase old previous block, since we will change it
- m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
-
             //Free old previous buffer
             new_block->m_size =
- AllocatedCtrlUnits + (needs_backwards_aligned + received_size)/Alignment;
+ AllocatedCtrlUnits + (needs_backwards_aligned + (received_size - UsableByPreviousChunk))/Alignment;
             assert(new_block->m_size >= BlockCtrlUnits);
             priv_mark_new_allocated_block(new_block);
 
             prev_block->m_size = (detail::char_ptr_cast(new_block) -
                                   detail::char_ptr_cast(prev_block))/Alignment;
             assert(prev_block->m_size >= BlockCtrlUnits);
- priv_tail_size(prev_block, prev_block->m_size);
             priv_mark_as_free_block(prev_block);
 
- //Insert the remaining previous block in the free tree
- m_header.m_imultiset.insert( m_header.m_imultiset.begin(), *prev_block);
+ //Update the old previous block in the free chunks tree
+ //If the new size fulfills tree invariants do nothing,
+ //otherwise erase() + insert()
+ {
+ imultiset_iterator prev_block_it(Imultiset::s_iterator_to(*prev_block));
+ imultiset_iterator was_smaller_it(prev_block_it);
+ if(prev_block_it != m_header.m_imultiset.begin() &&
+ (--(was_smaller_it = prev_block_it))->m_size > prev_block->m_size){
+ m_header.m_imultiset.erase(prev_block_it);
+ m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *prev_block);
+ }
+ }
+
             received_size = needs_backwards_aligned + received_size;
             m_header.m_allocated += needs_backwards_aligned;
          
@@ -812,14 +852,15 @@
          //Check if there is no place to create a new block and
          //the whole new block is multiple of the backwards expansion multiple
          else if(prev_block->m_size >= needs_backwards_aligned/Alignment &&
- 0 == (prev_block->m_size % lcm)) {
+ 0 == ((prev_block->m_size*Alignment) % lcm)) {
             //Erase old previous block, since we will change it
             m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
 
             //Just merge the whole previous block
- const std::size_t needs_backwards_aligned = prev_block->m_size*Alignment;
- const std::size_t needs_backwards = detail::get_truncated_size(needs_backwards_aligned, backwards_multiple);
- received_size = received_size/backwards_multiple*backwards_multiple + needs_backwards;
+ needs_backwards = detail::get_truncated_size
+ (prev_block->m_size*Alignment, backwards_multiple);
+ //received_size = received_size/backwards_multiple*backwards_multiple + needs_backwards;
+ received_size = received_size + needs_backwards;
 
             m_header.m_allocated += prev_block->m_size*Alignment;
             //Now update sizes
@@ -843,9 +884,9 @@
    return 0;
 }
 
-template<class MutexFamily, class VoidPointer>
-inline typename rbtree_best_fit<MutexFamily, VoidPointer>::multiallocation_iterator
- rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_iterator
+ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    allocate_many(std::size_t elem_bytes, std::size_t num_elements)
 {
    //-----------------------
@@ -854,9 +895,23 @@
    return algo_impl_t::allocate_many(this, elem_bytes, num_elements);
 }
 
-template<class MutexFamily, class VoidPointer>
-inline typename rbtree_best_fit<MutexFamily, VoidPointer>::multiallocation_iterator
- rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
+ deallocate_many(typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_iterator it)
+{
+ //-----------------------
+ boost::interprocess::scoped_lock<interprocess_mutex> guard(m_header);
+ //-----------------------
+ while(it){
+ void *addr = &*it;
+ ++it;
+ this->priv_deallocate(addr);
+ }
+}
+
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+inline typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::multiallocation_iterator
+ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element)
 {
    //-----------------------
@@ -865,8 +920,8 @@
    return algo_impl_t::allocate_many(this, elem_sizes, n_elements, sizeof_element);
 }
 
-template<class MutexFamily, class VoidPointer>
-std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+std::pair<void *, bool> rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_allocate(allocation_type command
                 ,std::size_t limit_size
                 ,std::size_t preferred_size
@@ -929,32 +984,34 @@
    return return_type(0, false);
 }
 
-template<class MutexFamily, class VoidPointer>
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 inline
-typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *
- rbtree_best_fit<MutexFamily, VoidPointer>::priv_get_block(const void *ptr)
+typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *
+ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_get_block(const void *ptr)
 {
    return reinterpret_cast<block_ctrl*>(detail::char_ptr_cast(ptr) - AllocatedCtrlBytes);
 }
 
-template<class MutexFamily, class VoidPointer>
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 inline
-void *rbtree_best_fit<MutexFamily, VoidPointer>::
- priv_get_user_buffer(const typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *block)
+void *rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
+ priv_get_user_buffer(const typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *block)
 { return detail::char_ptr_cast(block) + AllocatedCtrlBytes; }
 
-template<class MutexFamily, class VoidPointer>
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 inline
-std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::
+std::size_t rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_get_total_units(std::size_t userbytes)
 {
- std::size_t units = detail::get_rounded_size(userbytes, Alignment)/Alignment + AllocatedCtrlUnits;
+ if(userbytes < UsableByPreviousChunk)
+ userbytes = UsableByPreviousChunk;
+ std::size_t units = detail::get_rounded_size(userbytes - UsableByPreviousChunk, Alignment)/Alignment + AllocatedCtrlUnits;
    if(units < BlockCtrlUnits) units = BlockCtrlUnits;
    return units;
 }
 
-template<class MutexFamily, class VoidPointer>
-bool rbtree_best_fit<MutexFamily, VoidPointer>::
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    priv_expand (void *ptr
                ,const std::size_t min_size
                ,const std::size_t preferred_size
@@ -966,16 +1023,16 @@
 
    //The block must be marked as allocated and the sizes must be equal
    assert(priv_is_allocated_block(block));
- assert(old_block_units == priv_tail_size(block));
+ //assert(old_block_units == priv_tail_size(block));
    
    //Put this to a safe value
- received_size = (old_block_units - AllocatedCtrlUnits)*Alignment;
- if(received_size > preferred_size)
+ received_size = (old_block_units - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
+ if(received_size >= preferred_size || received_size >= min_size)
       return true;
 
    //Now translate it to Alignment units
- const std::size_t min_user_units = algo_impl_t::ceil_units(min_size);
- const std::size_t preferred_user_units = algo_impl_t::ceil_units(preferred_size);
+ const std::size_t min_user_units = algo_impl_t::ceil_units(min_size - UsableByPreviousChunk);
+ const std::size_t preferred_user_units = algo_impl_t::ceil_units(preferred_size - UsableByPreviousChunk);
 
    //Some parameter checks
    assert(min_user_units <= preferred_user_units);
@@ -994,7 +1051,7 @@
    const std::size_t merged_user_units = merged_units - AllocatedCtrlUnits;
 
    if(merged_user_units < min_user_units){
- received_size = merged_user_units*Alignment;
+ received_size = merged_units*Alignment - UsableByPreviousChunk;
       return false;
    }
 
@@ -1007,30 +1064,44 @@
 
    //Check if we can split the next one in two parts
    if((merged_units - intended_units) >= BlockCtrlUnits){
- //Now we have to update the data in the tree
- m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block));
-
       //This block is bigger than needed, split it in
       //two blocks, the first one will be merged and
       //the second's size will be the remaining space
- assert(next_block->m_size == priv_tail_size(next_block));
+ assert(next_block->m_size == priv_next_block(next_block)->m_prev_size);
+ const std::size_t rem_units = merged_units - intended_units;
 
+ //Check if we we need to update the old next block in the free chunks tree
+ //If the new size fulfills tree invariants, we just need to replace the node
+ //(the block start has been displaced), otherwise erase() + insert().
+ //
+ //This fixup must be done in two parts, because the new next chunk might
+ //overwrite the tree hook of the old next chunk. So we first erase the
+ //old if needed and we'll insert the new one after creating the new next
+ imultiset_iterator old_next_block_it(Imultiset::s_iterator_to(*next_block));
+ const bool size_invariants_broken =
+ (next_block->m_size - rem_units ) < BlockCtrlUnits ||
+ (old_next_block_it != m_header.m_imultiset.begin() &&
+ (--imultiset_iterator(old_next_block_it))->m_size > rem_units);
+ if(size_invariants_broken){
+ m_header.m_imultiset.erase(old_next_block_it);
+ }
       //This is the remaining block
- block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
+ block_ctrl *rem_block = new(reinterpret_cast<block_ctrl*>
                      (detail::char_ptr_cast(block) + intended_units*Alignment))block_ctrl;
- new_block->m_size = merged_units - intended_units;
- algo_impl_t::assert_alignment(new_block);
- assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_free_block(new_block);
-
- //Insert the new block in the container
- m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *new_block);
+ rem_block->m_size = rem_units;
+ algo_impl_t::assert_alignment(rem_block);
+ assert(rem_block->m_size >= BlockCtrlUnits);
+ priv_mark_as_free_block(rem_block);
+
+ //Now the second part of the fixup
+ if(size_invariants_broken)
+ m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *rem_block);
+ else
+ m_header.m_imultiset.replace_node(old_next_block_it, *rem_block);
 
       //Write the new length
       block->m_size = intended_user_units + AllocatedCtrlUnits;
       assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, block->m_size);
       m_header.m_allocated += (intended_units - old_block_units)*Alignment;
    }
    //There is no free space to create a new node: just merge both blocks
@@ -1041,61 +1112,97 @@
       //Write the new length
       block->m_size = merged_units;
       assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, merged_units);
       m_header.m_allocated += (merged_units - old_block_units)*Alignment;
    }
-
- received_size = (block->m_size - AllocatedCtrlUnits)*Alignment;
+ priv_mark_as_allocated_block(block);
+ received_size = (block->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
    return true;
 }
 
-template<class MutexFamily, class VoidPointer> inline
-void rbtree_best_fit<MutexFamily, VoidPointer>::priv_tail_size
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *ptr, std::size_t size)
-{ priv_next_block(ptr)->m_prev_size = size; }
-
-template<class MutexFamily, class VoidPointer> inline
-std::size_t rbtree_best_fit<MutexFamily, VoidPointer>::priv_tail_size
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *ptr)
-{ return priv_next_block(ptr)->m_prev_size; }
-
-template<class MutexFamily, class VoidPointer> inline
-typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *
- rbtree_best_fit<MutexFamily, VoidPointer>::priv_prev_block
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *ptr)
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *
+ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_prev_block
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *ptr)
 {
+ assert(!ptr->m_prev_allocated);
    return reinterpret_cast<block_ctrl *>
       (detail::char_ptr_cast(ptr) - ptr->m_prev_size*Alignment);
 }
 
-template<class MutexFamily, class VoidPointer> inline
-typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *
- rbtree_best_fit<MutexFamily, VoidPointer>::priv_next_block
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *ptr)
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_is_prev_allocated
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *ptr)
+{
+ if(ptr->m_prev_allocated){
+ return true;
+ }
+ else{
+ block_ctrl *prev = priv_prev_block(ptr);
+ (void)prev;
+ assert(!priv_is_allocated_block(prev));
+ return false;
+ }
+}
+
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *
+ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_end_block
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *first_segment_block)
+{
+ assert(first_segment_block->m_prev_allocated);
+ block_ctrl *end_block = reinterpret_cast<block_ctrl *>
+ (detail::char_ptr_cast(first_segment_block) - first_segment_block->m_prev_size*Alignment);
+ (void)end_block;
+ assert(priv_is_allocated_block(end_block));
+ assert(end_block > first_segment_block);
+ return end_block;
+}
+
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *
+ rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_next_block
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *ptr)
 {
    return reinterpret_cast<block_ctrl *>
       (detail::char_ptr_cast(ptr) + ptr->m_size*Alignment);
 }
 
-template<class MutexFamily, class VoidPointer> inline
-bool rbtree_best_fit<MutexFamily, VoidPointer>::priv_is_allocated_block
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *block)
-{ return block->m_allocated != 0; }
-
-template<class MutexFamily, class VoidPointer> inline
-void rbtree_best_fit<MutexFamily, VoidPointer>::priv_mark_as_allocated_block
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *block)
-{ block->m_allocated = 1; }
-
-template<class MutexFamily, class VoidPointer> inline
-void rbtree_best_fit<MutexFamily, VoidPointer>::priv_mark_as_free_block
- (typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl *block)
-{ block->m_allocated = 0; }
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_is_allocated_block
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *block)
+{
+ bool allocated = block->m_allocated != 0;
+ block_ctrl *next_block = (block_ctrl *)
+ (detail::char_ptr_cast(block) + block->m_size*Alignment);
+ bool next_block_prev_allocated = next_block->m_prev_allocated != 0;
+ (void)next_block_prev_allocated;
+ assert(allocated == next_block_prev_allocated);
+ return allocated;
+}
 
-template<class MutexFamily, class VoidPointer> inline
-void* rbtree_best_fit<MutexFamily, VoidPointer>::priv_check_and_allocate
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_mark_as_allocated_block
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *block)
+{
+ //assert(!priv_is_allocated_block(block));
+ block->m_allocated = 1;
+ ((block_ctrl *)(((char*)block) + block->m_size*Alignment))->m_prev_allocated = 1;
+}
+
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_mark_as_free_block
+ (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *block)
+{
+ block->m_allocated = 0;
+ ((block_ctrl *)(((char*)block) + block->m_size*Alignment))->m_prev_allocated = 0;
+ //assert(!priv_is_allocated_block(ptr));
+ priv_next_block(block)->m_prev_size = block->m_size;
+}
+
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
+void* rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_check_and_allocate
    (std::size_t nunits
- ,typename rbtree_best_fit<MutexFamily, VoidPointer>::block_ctrl* block
+ ,typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl* block
    ,std::size_t &received_size)
 {
    std::size_t upper_nunits = nunits + BlockCtrlUnits;
@@ -1109,32 +1216,30 @@
       std::size_t block_old_size = block->m_size;
       block->m_size = nunits;
       assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, block->m_size);
 
       //This is the remaining block
- block_ctrl *new_block = new(reinterpret_cast<block_ctrl*>
+ block_ctrl *rem_block = new(reinterpret_cast<block_ctrl*>
                      (detail::char_ptr_cast(block) + Alignment*nunits))block_ctrl;
- algo_impl_t::assert_alignment(new_block);
- new_block->m_size = block_old_size - nunits;
- assert(new_block->m_size >= BlockCtrlUnits);
- priv_tail_size(new_block, new_block->m_size);
- priv_mark_as_free_block(new_block);
+ algo_impl_t::assert_alignment(rem_block);
+ rem_block->m_size = block_old_size - nunits;
+ assert(rem_block->m_size >= BlockCtrlUnits);
+ priv_mark_as_free_block(rem_block);
 
       imultiset_iterator it_hint;
       if(it_old == m_header.m_imultiset.begin()
- || (--imultiset_iterator(it_old))->m_size < new_block->m_size){
+ || (--imultiset_iterator(it_old))->m_size < rem_block->m_size){
          //option a: slow but secure
- //m_header.m_imultiset.insert(m_header.m_imultiset.erase(it_old), *new_block);
+ //m_header.m_imultiset.insert(m_header.m_imultiset.erase(it_old), *rem_block);
          //option b: Construct an empty node and swap
- //Imultiset::init_node(*new_block);
- //block->swap_nodes(*new_block);
+ //Imultiset::init_node(*rem_block);
+ //block->swap_nodes(*rem_block);
          //option c: replace the node directly
- m_header.m_imultiset.replace_node(Imultiset::s_iterator_to(*it_old), *new_block);
+ m_header.m_imultiset.replace_node(Imultiset::s_iterator_to(*it_old), *rem_block);
       }
       else{
          //Now we have to update the data in the tree
          m_header.m_imultiset.erase(it_old);
- m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *new_block);
+ m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *rem_block);
       }
          
    }
@@ -1148,7 +1253,7 @@
    //We need block_ctrl for deallocation stuff, so
    //return memory user can overwrite
    m_header.m_allocated += block->m_size*Alignment;
- received_size = (block->m_size - AllocatedCtrlUnits)*Alignment;
+ received_size = (block->m_size - AllocatedCtrlUnits)*Alignment + UsableByPreviousChunk;
 
    //Mark the block as allocated
    priv_mark_as_allocated_block(block);
@@ -1157,11 +1262,12 @@
    //cleared with zero_free_memory
    TreeHook *t = static_cast<TreeHook*>(block);
    std::memset(t, 0, sizeof(*t));
+ this->priv_next_block(block)->m_prev_size = 0;
    return priv_get_user_buffer(block);
 }
 
-template<class MutexFamily, class VoidPointer>
-void rbtree_best_fit<MutexFamily, VoidPointer>::deallocate(void* addr)
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::deallocate(void* addr)
 {
    if(!addr) return;
    //-----------------------
@@ -1170,8 +1276,8 @@
    return this->priv_deallocate(addr);
 }
 
-template<class MutexFamily, class VoidPointer>
-void rbtree_best_fit<MutexFamily, VoidPointer>::priv_deallocate(void* addr)
+template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
+void rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::priv_deallocate(void* addr)
 {
    if(!addr) return;
 
@@ -1179,7 +1285,7 @@
   
    //The blocks must be marked as allocated and the sizes must be equal
    assert(priv_is_allocated_block(block));
- assert(block->m_size == priv_tail_size(block));
+// assert(block->m_size == priv_tail_size(block));
 
    //Check if alignment and block size are right
    algo_impl_t::assert_alignment(addr);
@@ -1194,33 +1300,48 @@
    block_ctrl *block_to_insert = block;
 
    //Get the next block
- block_ctrl *next_block = priv_next_block(block);
+ block_ctrl *next_block = priv_next_block(block);
+ bool merge_with_prev = !priv_is_prev_allocated(block);
+ bool merge_with_next = !priv_is_allocated_block(next_block);
+
+ //Merge logic. First just update block sizes, then fix free chunks tree
+ if(merge_with_prev || merge_with_next){
+ //Merge if the previous is free
+ if(merge_with_prev){
+ //Get the previous block
+ block_ctrl *prev_block = priv_prev_block(block);
+ prev_block->m_size += block->m_size;
+ assert(prev_block->m_size >= BlockCtrlUnits);
+ block_to_insert = prev_block;
+ }
+ //Merge if the next is free
+ if(merge_with_next){
+ block_to_insert->m_size += next_block->m_size;
+ assert(block_to_insert->m_size >= BlockCtrlUnits);
+ if(merge_with_prev)
+ m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block));
+ }
 
- //Merge if the next is free
- if(!priv_is_allocated_block(next_block)){
- block->m_size += next_block->m_size;
- assert(block->m_size >= BlockCtrlUnits);
- priv_tail_size(block, block->m_size);
- m_header.m_imultiset.erase(Imultiset::s_iterator_to(*next_block));
+ bool only_merge_next = !merge_with_prev && merge_with_next;
+ imultiset_iterator free_block_to_check_it
+ (Imultiset::s_iterator_to(only_merge_next ? *next_block : *block_to_insert));
+ imultiset_iterator was_bigger_it(free_block_to_check_it);
+
+ //Now try to shortcut erasure + insertion (O(log(N))) with
+ //a O(1) operation if merging does not alter tree positions
+ if(++was_bigger_it != m_header.m_imultiset.end() &&
+ block_to_insert->m_size > was_bigger_it->m_size ){
+ m_header.m_imultiset.erase(free_block_to_check_it);
+ m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *block_to_insert);
+ }
+ else if(only_merge_next){
+ m_header.m_imultiset.replace_node(free_block_to_check_it, *block_to_insert);
+ }
    }
-
- //Get the previous block
- block_ctrl *prev_block = priv_prev_block(block);
-
- //Now check that tail size and control size are equal
- assert(prev_block->m_size == priv_tail_size(prev_block));
-
- //Merge if the previous is free
- if(!priv_is_allocated_block(prev_block)){
- prev_block->m_size += block->m_size;
- assert(prev_block->m_size >= BlockCtrlUnits);
- priv_tail_size(prev_block, prev_block->m_size);
- m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
- block_to_insert = prev_block;
+ else{
+ m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *block_to_insert);
    }
-
    priv_mark_as_free_block(block_to_insert);
- m_header.m_imultiset.insert(m_header.m_imultiset.begin(), *block_to_insert);
 }
 
 } //namespace interprocess {

Modified: branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/simple_seq_fit.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/offset_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/offset_ptr.hpp (original)
+++ branches/release/boost/interprocess/offset_ptr.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -61,7 +61,7 @@
    typedef void (self_t::*unspecified_bool_type)() const;
 
    #if defined(_MSC_VER) && (_MSC_VER >= 1400)
- __declspec(noinline)
+ __declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0
    #endif
    void set_offset(const volatile void *ptr)
    {
@@ -77,7 +77,7 @@
    }
 
    #if defined(_MSC_VER) && (_MSC_VER >= 1400)
- __declspec(noinline)
+ __declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0
    #endif
    void* get_pointer() const
    { return (m_offset == 1) ? 0 : (detail::char_ptr_cast(this) + m_offset); }

Modified: branches/release/boost/interprocess/segment_manager.hpp
==============================================================================
--- branches/release/boost/interprocess/segment_manager.hpp (original)
+++ branches/release/boost/interprocess/segment_manager.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -70,7 +70,8 @@
    /// @cond
    
    //Experimental. Don't use
- typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator;
+ typedef typename MemoryAlgorithm::multiallocation_iterator multiallocation_iterator;
+ typedef typename MemoryAlgorithm::multiallocation_chain multiallocation_chain;
 
    /// @endcond
 
@@ -148,6 +149,11 @@
    multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::size_t sizeof_element, std::nothrow_t)
    { return MemoryAlgorithm::allocate_many(elem_sizes, n_elements, sizeof_element); }
 
+ //!Deallocates elements pointed by the
+ //!multiallocation iterator range.
+ void deallocate_many(multiallocation_iterator it)
+ { MemoryAlgorithm::deallocate_many(it); }
+
    /// @endcond
 
    //!Allocates nbytes bytes. Throws boost::interprocess::bad_alloc
@@ -189,6 +195,19 @@
       return ret;
    }
 
+ std::pair<void *, bool>
+ raw_allocation_command (allocation_type command, std::size_t limit_objects,
+ std::size_t preferred_objects,std::size_t &received_objects,
+ void *reuse_ptr = 0, std::size_t sizeof_object = 1)
+ {
+ std::pair<void *, bool> ret = MemoryAlgorithm::raw_allocation_command
+ ( command | nothrow_allocation, limit_objects, preferred_objects, received_objects
+ , reuse_ptr, sizeof_object);
+ if(!(command & nothrow_allocation) && !ret.first)
+ throw bad_alloc();
+ return ret;
+ }
+
    //!Deallocates the bytes allocated with allocate/allocate_many()
    //!pointed by addr
    void deallocate (void *addr)
@@ -219,6 +238,10 @@
    void zero_free_memory()
    { MemoryAlgorithm::zero_free_memory(); }
 
+ //!Returns the size of the buffer previously allocated pointed by ptr
+ std::size_t size(const void *ptr) const
+ { return MemoryAlgorithm::size(ptr); }
+
    /// @cond
    protected:
    void * prot_anonymous_construct
@@ -249,7 +272,8 @@
 
       //Now construct the header
       block_header_t * hdr = new(ptr_struct) block_header_t(block_info);
- void *ptr = hdr->value();
+ void *ptr = 0; //avoid gcc warning
+ ptr = hdr->value();
 
       //Now call constructors
       detail::array_construct(ptr, num, table);
@@ -1039,7 +1063,7 @@
       //Ignore exceptions
       BOOST_CATCH(...){
          if(dothrow)
- BOOST_RETHROW;
+ BOOST_RETHROW
          return 0;
       }
       BOOST_CATCH_END
@@ -1073,7 +1097,8 @@
       //Now construct the intrusive hook plus the header
       intrusive_value_type * intrusive_hdr = new(buffer_ptr) intrusive_value_type();
       block_header_t * hdr = new(intrusive_hdr->get_block_header())block_header_t(block_info);
- void *ptr = hdr->value();
+ void *ptr = 0; //avoid gcc warning
+ ptr = hdr->value();
 
       //Copy name to memory segment and insert data
       CharT *name_ptr = static_cast<CharT *>(hdr->template name<CharT>());
@@ -1086,7 +1111,7 @@
       //Ignore exceptions
       BOOST_CATCH(...){
          if(dothrow)
- BOOST_RETHROW;
+ BOOST_RETHROW
          return 0;
       }
       BOOST_CATCH_END
@@ -1212,7 +1237,8 @@
       }
 
       hdr = new(hdr)block_header_t(block_info);
- void *ptr = hdr->value();
+ void *ptr = 0; //avoid gcc warning
+ ptr = hdr->value();
 
       //Copy name to memory segment and insert data
       CharT *name_ptr = static_cast<CharT *>(hdr->template name<CharT>());

Modified: branches/release/boost/interprocess/shared_memory_object.hpp
==============================================================================
--- branches/release/boost/interprocess/shared_memory_object.hpp (original)
+++ branches/release/boost/interprocess/shared_memory_object.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/smart_ptr/deleter.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/deleter.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/deleter.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007.
+// (C) Copyright Ion Gaztanaga 2007-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/detail/shared_count.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -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-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2006-2008. 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)
 //
@@ -92,7 +92,7 @@
       }
       BOOST_CATCH (...){
          d(p); // delete p
- throw;
+ BOOST_RETHROW
       }
       BOOST_CATCH_END
    }

Modified: branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -9,7 +9,7 @@
 
 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 // Copyright 2004-2005 Peter Dimov
-// Copyright 2007 Ion Gaztanaga
+// Copyright 2007-2008 Ion Gaztanaga
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -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-2007.
+// (C) Copyright Ion Gaztanaga 2006-2008.
 // 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: branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -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-2007.
+// (C) Copyright Ion Gaztanaga 2006-2008.
 // 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: branches/release/boost/interprocess/streams/bufferstream.hpp
==============================================================================
--- branches/release/boost/interprocess/streams/bufferstream.hpp (original)
+++ branches/release/boost/interprocess/streams/bufferstream.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/streams/vectorstream.hpp
==============================================================================
--- branches/release/boost/interprocess/streams/vectorstream.hpp (original)
+++ branches/release/boost/interprocess/streams/vectorstream.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/emulation/interprocess_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/interprocess_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/interprocess_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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,9 +54,7 @@
    if(now >= abs_time) return false;
 
    do{
- boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0);
-
- if (m_s == 1 && prev_s == 0){
+ if(this->try_lock()){
          break;
       }
       now = microsec_clock::universal_time();

Modified: branches/release/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp (original)
+++ branches/release/boost/interprocess/sync/emulation/named_creation_functor.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2007-2008. 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: branches/release/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/file_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/file_lock.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/interprocess_barrier.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_barrier.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_barrier.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/interprocess_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_condition.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/interprocess_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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)
 //
@@ -109,13 +109,7 @@
    #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
       volatile boost::uint32_t m_s;
    #elif defined(BOOST_INTERPROCESS_USE_POSIX)
- #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
- pthread_mutex_t m_mut;
- #else
- pthread_mutex_t m_mut;
- pthread_cond_t m_cond;
- bool m_locked;
- #endif
+ pthread_mutex_t m_mut;
    #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
    /// @endcond
 };

Modified: branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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,7 +36,7 @@
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <cassert>
 
-#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
+#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED && defined BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
    #include <pthread.h>
    #include <errno.h>
    #include <boost/interprocess/sync/posix/pthread_helpers.hpp>
@@ -107,15 +107,7 @@
    unsigned int m_nLockCount;
    detail::OS_thread_id_t m_nOwner;
    #else //#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- #if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 500) && defined BOOST_INTERPROCESS_POSIX_TIMEOUTS
- pthread_mutex_t m_mut;
- #else //#if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 500) && defined BOOST_INTERPROCESS_POSIX_TIMEOUTS
- pthread_mutex_t m_mut;
- pthread_cond_t m_unlocked;
- pthread_t m_thread_id;
- bool m_valid_id;
- unsigned int m_count;
- #endif //#if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 500) && defined BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ pthread_mutex_t m_mut;
    #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
    /// @endcond
 };

Modified: branches/release/boost/interprocess/sync/interprocess_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_semaphore.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/interprocess_upgradable_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/interprocess_upgradable_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/interprocess_upgradable_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/lock_options.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/lock_options.hpp (original)
+++ branches/release/boost/interprocess/sync/lock_options.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/mutex_family.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/mutex_family.hpp (original)
+++ branches/release/boost/interprocess/sync/mutex_family.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/named_condition.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/named_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/named_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/named_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/named_recursive_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/named_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/named_semaphore.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
  //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/null_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/null_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/null_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_condition.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -27,13 +27,13 @@
 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <boost/interprocess/exceptions.hpp>
+#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+# include <boost/interprocess/detail/os_thread_functions.hpp>
+#endif
 
 namespace boost {
-
 namespace interprocess {
 
-#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
-
 inline interprocess_mutex::interprocess_mutex()
 {
    detail::mutexattr_wrapper mut_attr;
@@ -56,139 +56,51 @@
 inline bool interprocess_mutex::try_lock()
 {
    int res = pthread_mutex_trylock(&m_mut);
- if (res == EDEADLK) throw lock_exception();
- assert(res == 0 || res == EBUSY);
+ if (!(res == 0 || res == EBUSY))
+ throw lock_exception();
    return res == 0;
 }
 
 inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+
    timespec ts = detail::ptime_to_timespec(abs_time);
    int res = pthread_mutex_timedlock(&m_mut, &ts);
- if (res == EDEADLK || (res != 0 && res != ETIMEDOUT))
+ if (res != 0 && res != ETIMEDOUT)
       throw lock_exception();
    return res == 0;
-}
 
-inline void interprocess_mutex::unlock()
-{
- int res = 0;
- res = pthread_mutex_unlock(&m_mut);
-// if (res == EPERM) throw lock_exception();
- assert(res == 0);
-}
+ #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS
 
-#else //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+ //Obtain current count and target time
+ boost::posix_time::ptime now = microsec_clock::universal_time();
 
-inline interprocess_mutex::interprocess_mutex()
- : m_locked(false)
-{
- //Mutex init
- detail::mutexattr_wrapper mut_attr;
- detail::mutex_initializer mut(m_mut, mut_attr);
-
- //Condition init
- detail::condattr_wrapper cond_attr;
- detail::condition_initializer cond(m_cond, cond_attr);
-
- mut.release();
- cond.release();
-}
+ if(now >= abs_time) return false;
 
-inline interprocess_mutex::~interprocess_mutex()
-{
- assert(!m_locked);
- int res = 0;
- res = pthread_mutex_destroy(&m_mut);
- assert(res == 0);
+ do{
+ if(this->try_lock()){
+ break;
+ }
+ now = microsec_clock::universal_time();
+
+ if(now >= abs_time){
+ return false;
+ }
+ // relinquish current time slice
+ detail::thread_yield();
+ }while (true);
+ return true;
 
- res = pthread_cond_destroy(&m_cond);
- assert(res == 0);
-}
-
-inline void interprocess_mutex::lock()
-{
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- while (m_locked){
- res = pthread_cond_wait(&m_cond, &m_mut);
- assert(res == 0);
- }
-
- assert(!m_locked);
- m_locked = true;
-
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
-}
-
-inline bool interprocess_mutex::try_lock()
-{
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- bool ret = false;
- if (!m_locked)
- {
- m_locked = true;
- ret = true;
- }
-
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
- return ret;
-}
-
-inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- timespec ts = detail::ptime_to_timespec(abs_time);
-
- while (m_locked)
- {
- res = pthread_cond_timedwait(&m_cond, &m_mut, &ts);
- assert(res == 0 || res == ETIMEDOUT);
-
- if (res == ETIMEDOUT)
- break;
- }
-
- bool ret = false;
- if (!m_locked)
- {
- m_locked = true;
- ret = true;
- }
-
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
- return ret;
+ #endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
 }
 
 inline void interprocess_mutex::unlock()
 {
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- assert(m_locked);
- m_locked = false;
-
- res = pthread_cond_signal(&m_cond);
- assert(res == 0);
-
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
+ int res = 0;
+ res = pthread_mutex_unlock(&m_mut);
+ assert(res == 0);
 }
 
-#endif //#ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
-
 } //namespace interprocess {
-
 } //namespace boost {

Modified: branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -27,12 +27,14 @@
 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <boost/interprocess/exceptions.hpp>
+#ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+# include <boost/interprocess/detail/os_thread_functions.hpp>
+#endif
 
 namespace boost {
 
 namespace interprocess {
 
-#if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 500) && defined BOOST_INTERPROCESS_POSIX_TIMEOUTS
 inline interprocess_recursive_mutex::interprocess_recursive_mutex()
 {
    detail::mutexattr_wrapper mut_attr(true);
@@ -48,179 +50,58 @@
 
 inline void interprocess_recursive_mutex::lock()
 {
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- if (res == EDEADLK) throw lock_exception();
- assert(res == 0);
+ if (pthread_mutex_lock(&m_mut) != 0)
+ throw lock_exception();
 }
 
 inline bool interprocess_recursive_mutex::try_lock()
 {
- int res = 0;
- res = pthread_mutex_trylock(&m_mut);
- if (res == EDEADLK) throw lock_exception();
- assert(res == 0 || res == EBUSY);
+ int res = pthread_mutex_trylock(&m_mut);
+ if (!(res == 0 || res == EBUSY))
+ throw lock_exception();
    return res == 0;
 }
 
 inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
+
    timespec ts = detail::ptime_to_timespec(abs_time);
    int res = pthread_mutex_timedlock(&m_mut, &ts);
- if (res == EDEADLK) throw lock_exception();
- assert(res == 0 || res == EBUSY);
+ if (res != 0 && res != ETIMEDOUT)
+ throw lock_exception();
    return res == 0;
-}
-
-inline void interprocess_recursive_mutex::unlock()
-{
- int res = 0;
- res = pthread_mutex_unlock(&m_mut);
- if (res == EPERM) throw lock_exception();
- assert(res == 0);
-}
-
-#else //#if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 500) && defined BOOST_INTERPROCESS_POSIX_TIMEOUTS
 
-inline interprocess_recursive_mutex::interprocess_recursive_mutex()
- : m_valid_id(false), m_count(0)
-{
- //Mutex init
- detail::mutexattr_wrapper mut_attr;
- detail::mutex_initializer mut(m_mut, mut_attr);
-
- //Condition init
- detail::condattr_wrapper cond_attr;
- detail::condition_initializer cond(m_unlocked, cond_attr);
+ #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS
 
- mut.release();
- cond.release();
-}
-
-inline interprocess_recursive_mutex::~interprocess_recursive_mutex()
-{
- int res = 0;
- res = pthread_mutex_destroy(&m_mut);
- assert(res == 0);
+ //Obtain current count and target time
+ boost::posix_time::ptime now = microsec_clock::universal_time();
 
- res = pthread_cond_destroy(&m_unlocked);
- assert(res == 0);
-}
+ if(now >= abs_time) return false;
 
-inline void interprocess_recursive_mutex::lock()
-{
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- if(res != 0){
- throw interprocess_exception(system_error_code());
- }
- assert(res == 0);
-
- pthread_t tid = pthread_self();
- if (m_valid_id && pthread_equal(m_thread_id, tid)){
- ++m_count;
- }
- else{
- while (m_valid_id)
- {
- res = pthread_cond_wait(&m_unlocked, &m_mut);
- assert(res == 0);
+ do{
+ if(this->try_lock()){
+ break;
       }
+ now = microsec_clock::universal_time();
 
- m_thread_id = tid;
- m_valid_id = true;
- m_count = 1;
- }
-
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
-}
-
-inline bool interprocess_recursive_mutex::try_lock()
-{
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- bool ret = false;
- pthread_t tid = pthread_self();
- if (m_valid_id && pthread_equal(m_thread_id, tid)){
- ++m_count;
- ret = true;
- }
- else if (!m_valid_id){
- m_thread_id = tid;
- m_valid_id = true;
- m_count = 1;
- ret = true;
- }
-
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
- return ret;
-}
-
-inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{
- int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- bool ret = false;
- pthread_t tid = pthread_self();
- if (m_valid_id && pthread_equal(m_thread_id, tid)){
- ++m_count;
- ret = true;
- }
- else{
- timespec ts = detail::ptime_to_timespec(abs_time);
-
- while (m_valid_id){
- res = pthread_cond_timedwait(&m_unlocked, &m_mut, &ts);
- if (res == ETIMEDOUT)
- break;
- assert(res == 0);
- }
-
- if (!m_valid_id){
- m_thread_id = tid;
- m_valid_id = true;
- m_count = 1;
- ret = true;
+ if(now >= abs_time){
+ return false;
       }
- }
+ // relinquish current time slice
+ detail::thread_yield();
+ }while (true);
+ return true;
 
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
- return ret;
+ #endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS
 }
 
 inline void interprocess_recursive_mutex::unlock()
 {
    int res = 0;
- res = pthread_mutex_lock(&m_mut);
- assert(res == 0);
-
- pthread_t tid = pthread_self();
- if (m_valid_id && !pthread_equal(m_thread_id, tid)){
- res = pthread_mutex_unlock(&m_mut);
- assert(res == 0);
- throw lock_exception();
- }
-
- if (--m_count == 0){
- assert(m_valid_id);
- m_valid_id = false;
-
- res = pthread_cond_signal(&m_unlocked);
- assert(res == 0);
- }
-
    res = pthread_mutex_unlock(&m_mut);
    assert(res == 0);
 }
 
-#endif //#if (_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 500) && defined BOOST_INTERPROCESS_POSIX_TIMEOUTS
-
 } //namespace interprocess {
 } //namespace boost {

Modified: branches/release/boost/interprocess/sync/posix/interprocess_semaphore.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/interprocess_semaphore.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/interprocess_semaphore.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/pthread_helpers.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/ptime_to_timespec.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp (original)
+++ branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/scoped_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/scoped_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/scoped_lock.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/sharable_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/sharable_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/sharable_lock.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/sync/upgradable_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/upgradable_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/upgradable_lock.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/windows_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/windows_shared_memory.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2005-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2008. 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: branches/release/boost/intrusive/circular_list_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/circular_list_algorithms.hpp (original)
+++ branches/release/boost/intrusive/circular_list_algorithms.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -54,6 +54,27 @@
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;
 
+ //! <b>Effects</b>: Constructs an non-used list element, so that
+ //! inited(this_node) == true
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void init(node_ptr this_node)
+ {
+ NodeTraits::set_next(this_node, 0);
+ NodeTraits::set_previous(this_node, 0);
+ }
+
+ //! <b>Effects</b>: Returns true is "this_node" is in a non-used state
+ //! as if it was initialized by the "init" function.
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static bool inited(const_node_ptr this_node)
+ { return !NodeTraits::get_next(this_node); }
+
    //! <b>Effects</b>: Constructs an empty list, making this_node the only
    //! node of the circular list:
    //! <tt>NodeTraits::get_next(this_node) == NodeTraits::get_previous(this_node)
@@ -62,11 +83,12 @@
    //! <b>Complexity</b>: Constant
    //!
    //! <b>Throws</b>: Nothing.
- static void init(node_ptr this_node)
+ static void init_header(node_ptr this_node)
    {
       NodeTraits::set_next(this_node, this_node);
       NodeTraits::set_previous(this_node, this_node);
- }
+ }
+
 
    //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
    //!
@@ -76,8 +98,11 @@
    //! <b>Complexity</b>: Constant
    //!
    //! <b>Throws</b>: Nothing.
- static bool unique(const_node_ptr this_node)
- { return NodeTraits::get_next(this_node) == this_node; }
+ static bool unique(const_node_ptr this_node)
+ {
+ node_ptr next = NodeTraits::get_next(this_node);
+ return !next || next == this_node;
+ }
 
    //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
    //!
@@ -107,11 +132,16 @@
    //! <b>Throws</b>: Nothing.
    static node_ptr unlink(node_ptr this_node)
    {
- node_ptr next(NodeTraits::get_next(this_node));
- node_ptr prev(NodeTraits::get_previous(this_node));
- NodeTraits::set_next(prev, next);
- NodeTraits::set_previous(next, prev);
- return next;
+ if(NodeTraits::get_next(this_node)){
+ node_ptr next(NodeTraits::get_next(this_node));
+ node_ptr prev(NodeTraits::get_previous(this_node));
+ NodeTraits::set_next(prev, next);
+ NodeTraits::set_previous(next, prev);
+ return next;
+ }
+ else{
+ return this_node;
+ }
    }
 
    //! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
@@ -124,10 +154,9 @@
    static void unlink(node_ptr b, node_ptr e)
    {
       if (b != e) {
- node_ptr prev(NodeTraits::get_previous(b));
- node_ptr next(NodeTraits::get_next(e));
- NodeTraits::set_previous(next, prev);
- NodeTraits::set_next(prev, next);
+ node_ptr prevb(NodeTraits::get_previous(b));
+ NodeTraits::set_previous(e, prevb);
+ NodeTraits::set_next(prevb, e);
       }
    }
 
@@ -229,6 +258,17 @@
    public:
    static void swap_nodes(node_ptr this_node, node_ptr other_node)
    {
+ if (other_node == this_node)
+ return;
+ bool this_inited = inited(this_node);
+ bool other_inited = inited(other_node);
+ if(this_inited){
+ init_header(this_node);
+ }
+ if(other_inited){
+ init_header(other_node);
+ }
+
       node_ptr next_this(NodeTraits::get_next(this_node));
       node_ptr prev_this(NodeTraits::get_previous(this_node));
       node_ptr next_other(NodeTraits::get_next(other_node));
@@ -238,6 +278,13 @@
       swap_next(prev_this, prev_other);
       swap_next(this_node, other_node);
       swap_prev(this_node, other_node);
+
+ if(this_inited){
+ init(other_node);
+ }
+ if(other_inited){
+ init(this_node);
+ }
    }
 
    //! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
@@ -254,8 +301,8 @@
    {
       if (b != e) {
          node_ptr prev_p(NodeTraits::get_previous(p));
- node_ptr prev_e(NodeTraits::get_previous(e));
          node_ptr prev_b(NodeTraits::get_previous(b));
+ node_ptr prev_e(NodeTraits::get_previous(e));
          NodeTraits::set_next(prev_e, p);
          NodeTraits::set_previous(p, prev_e);
          NodeTraits::set_next(prev_b, e);
@@ -308,6 +355,47 @@
          f = n;
       }
    }
+
+ //! <b>Effects</b>: Moves the node p n positions towards the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of moved positions.
+ static void move_backwards(node_ptr p, std::size_t n)
+ {
+ //Null shift, nothing to do
+ if(!n) return;
+ node_ptr first = NodeTraits::get_next(p);
+ //size() == 0 or 1, nothing to do
+ if(first == NodeTraits::get_previous(p)) return;
+ unlink(p);
+ //Now get the new first node
+ while(n--){
+ first = NodeTraits::get_next(first);
+ }
+ link_before(first, p);
+ }
+
+ //! <b>Effects</b>: Moves the node p n positions towards the beginning of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of moved positions.
+ static void move_forward(node_ptr p, std::size_t n)
+ {
+ //Null shift, nothing to do
+ if(!n) return;
+ node_ptr last = NodeTraits::get_previous(p);
+ //size() == 0 or 1, nothing to do
+ if(last == NodeTraits::get_next(p)) return;
+
+ unlink(p);
+ //Now get the new last node
+ while(n--){
+ last = NodeTraits::get_previous(last);
+ }
+ link_after(last, p);
+ }
 };
 
 } //namespace intrusive

Modified: branches/release/boost/intrusive/circular_slist_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/circular_slist_algorithms.hpp (original)
+++ branches/release/boost/intrusive/circular_slist_algorithms.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -16,6 +16,8 @@
 
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
+#include <boost/intrusive/detail/common_slist_algorithms.hpp>
+#include <boost/intrusive/detail/assert.hpp>
 #include <cstddef>
 
 namespace boost {
@@ -25,7 +27,7 @@
 //! forming a circular singly linked list. An empty circular list is formed by a node
 //! whose pointer to the next node points to itself.
 //!
-//! circular_slist_algorithms is configured with a NodeTraits class, which capsulates the
+//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the
 //! information about the node to be manipulated. NodeTraits must support the
 //! following interface:
 //!
@@ -44,22 +46,98 @@
 //! <tt>static void set_next(node_ptr n, node_ptr next);</tt>
 template<class NodeTraits>
 class circular_slist_algorithms
+ /// @cond
+ : public detail::common_slist_algorithms<NodeTraits>
+ /// @endcond
 {
+ /// @cond
+ typedef detail::common_slist_algorithms<NodeTraits> base_t;
+ /// @endcond
    public:
    typedef typename NodeTraits::node_ptr node_ptr;
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;
 
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! <b>Effects</b>: Constructs an non-used list element, putting the next
+ //! pointer to null:
+ //! <tt>NodeTraits::get_next(this_node) == 0
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void init(node_ptr this_node);
+
    //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
    //!
- //! <b>Effects</b>: Returns the previous node of this_node in the circular list.
+ //! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
+ //! or it's a not inserted node:
+ //! <tt>return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
    //!
- //! <b>Complexity</b>: Linear to the number of elements in the circular list.
+ //! <b>Complexity</b>: Constant
    //!
    //! <b>Throws</b>: Nothing.
- static node_ptr get_previous_node(node_ptr this_node)
- { return get_previous_node(this_node, this_node); }
+ static bool unique(const_node_ptr this_node);
 
+ //! <b>Effects</b>: Returns true is "this_node" has the same state as
+ //! if it was inited using "init(node_ptr)"
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static bool inited(const_node_ptr this_node);
+
+ //! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list.
+ //!
+ //! <b>Effects</b>: Unlinks the next node of prev_node from the circular list.
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void unlink_after(node_ptr prev_node);
+
+ //! <b>Requires</b>: prev_node and last_node must be in a circular list
+ //! or be an empty circular list.
+ //!
+ //! <b>Effects</b>: Unlinks the range (prev_node, last_node) from the circular list.
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void unlink_after(node_ptr prev_node, node_ptr last_node);
+
+ //! <b>Requires</b>: prev_node must be a node of a circular list.
+ //!
+ //! <b>Effects</b>: Links this_node after prev_node in the circular list.
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void link_after(node_ptr prev_node, node_ptr this_node);
+
+ //! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
+ //! and p must be a node of a different circular list.
+ //!
+ //! <b>Effects</b>: Removes the nodes from (b, e] range from their circular list and inserts
+ //! them after p in p's circular list.
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void transfer_after(node_ptr p, node_ptr b, node_ptr e);
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! <b>Effects</b>: Constructs an empty list, making this_node the only
+ //! node of the circular list:
+ //! <tt>NodeTraits::get_next(this_node) == this_node</tt>.
+ //!
+ //! <b>Complexity</b>: Constant
+ //!
+ //! <b>Throws</b>: Nothing.
+ static void init_header(node_ptr this_node)
+ { NodeTraits::set_next(this_node, this_node); }
 
    //! <b>Requires</b>: this_node and prev_init_node must be in the same circular list.
    //!
@@ -71,15 +149,17 @@
    //!
    //! <b>Throws</b>: Nothing.
    static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node)
- {
- node_ptr p = prev_init_node;
- for( node_ptr p_next
- ; this_node != (p_next = NodeTraits::get_next(p))
- ; p = p_next){
- //empty
- }
- return p;
- }
+ { return base_t::get_previous_node(prev_init_node, this_node); }
+
+ //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
+ //!
+ //! <b>Effects</b>: Returns the previous node of this_node in the circular list.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the circular list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static node_ptr get_previous_node(node_ptr this_node)
+ { return base_t::get_previous_node(this_node, this_node); }
 
    //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
    //!
@@ -113,28 +193,6 @@
       return p;
    }
 
- //! <b>Effects</b>: Constructs an empty list, making this_node the only
- //! node of the circular list:
- //! <tt>NodeTraits::get_next(this_node) == NodeTraits::get_previous(this_node)
- //! == this_node</tt>.
- //!
- //! <b>Complexity</b>: Constant
- //!
- //! <b>Throws</b>: Nothing.
- static void init(node_ptr this_node)
- { NodeTraits::set_next(this_node, this_node); }
-
- //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
- //!
- //! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
- //! <tt>return NodeTraits::get_next(this_node) == this_node</tt>
- //!
- //! <b>Complexity</b>: Constant
- //!
- //! <b>Throws</b>: Nothing.
- static bool unique(const_node_ptr this_node)
- { return NodeTraits::get_next(this_node) == this_node; }
-
    //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
    //!
    //! <b>Effects</b>: Returns the number of nodes in a circular list. If the circular list
@@ -154,34 +212,7 @@
       return result;
    }
 
- //! <b>Requires</b>: prev_node must be in a circular list or be an empty circular list.
- //!
- //! <b>Effects</b>: Unlinks the next node of prev_node from the circular list.
- //!
- //! <b>Complexity</b>: Constant
- //!
- //! <b>Throws</b>: Nothing.
- static void unlink_after(node_ptr prev_node)
- {
- node_ptr this_node(NodeTraits::get_next(prev_node));
- NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node));
- NodeTraits::set_next(this_node, this_node);
- }
-
- //! <b>Requires</b>: nxt_node must be in a circular list or be an empty circular list.
- //!
- //! <b>Effects</b>: Unlinks the previous node of nxt_node from the circular list.
- //!
- //! <b>Complexity</b>: Linear to the elements in the circular list.
- //!
- //! <b>Throws</b>: Nothing.
- static void unlink_before(node_ptr nxt_node)
- {
- node_ptr prev_to_erase(get_previous_previous_node(nxt_node));
- unlink_after(prev_to_erase);
- }
-
- //! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
+ //! <b>Requires</b>: this_node must be in a circular list, be an empty circular list or be inited.
    //!
    //! <b>Effects</b>: Unlinks the node from the circular list.
    //!
@@ -189,20 +220,9 @@
    //!
    //! <b>Throws</b>: Nothing.
    static void unlink(node_ptr this_node)
- { unlink_after(get_previous_node(this_node)); }
-
- //! <b>Requires</b>: prev_node must be a node of a circular list.
- //!
- //! <b>Effects</b>: Links this_node after prev_node in the circular list.
- //!
- //! <b>Complexity</b>: Constant
- //!
- //! <b>Throws</b>: Nothing.
- static void link_after(node_ptr prev_node, node_ptr this_node)
    {
- node_ptr this_nxt = NodeTraits::get_next(prev_node);
- NodeTraits::set_next(this_node, this_nxt);
- NodeTraits::set_next(prev_node, this_node);
+ if(NodeTraits::get_next(this_node))
+ base_t::unlink_after(get_previous_node(this_node));
    }
 
    //! <b>Requires</b>: nxt_node must be a node of a circular list.
@@ -213,7 +233,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    static void link_before (node_ptr nxt_node, node_ptr this_node)
- { link_after(get_previous_node(nxt_node), this_node); }
+ { base_t::link_after(get_previous_node(nxt_node), this_node); }
 
    //! <b>Requires</b>: this_node and other_node must be nodes inserted
    //! in circular lists or be empty circular lists.
@@ -229,8 +249,17 @@
    {
       if (other_node == this_node)
          return;
- bool empty1 = unique(this_node);
- bool empty2 = unique(other_node);
+ bool this_inited = base_t::inited(this_node);
+ bool other_inited = base_t::inited(other_node);
+ if(this_inited){
+ base_t::init_header(this_node);
+ }
+ if(other_inited){
+ base_t::init_header(other_node);
+ }
+
+ bool empty1 = base_t::unique(this_node);
+ bool empty2 = base_t::unique(other_node);
       node_ptr prev_this (get_previous_node(this_node));
       node_ptr prev_other(get_previous_node(other_node));
 
@@ -240,26 +269,12 @@
       NodeTraits::set_next(other_node, this_next);
       NodeTraits::set_next(empty1 ? other_node : prev_this, other_node);
       NodeTraits::set_next(empty2 ? this_node : prev_other, this_node);
- }
 
- //! <b>Requires</b>: b and e must be nodes of the same circular list or an empty range.
- //! and p must be a node of a different circular list.
- //!
- //! <b>Effects</b>: Removes the nodes from [b, e) range from their circular list and inserts
- //! them after p in p's circular list.
- //!
- //! <b>Complexity</b>: Constant
- //!
- //! <b>Throws</b>: Nothing.
- static void transfer_after(node_ptr p, node_ptr b, node_ptr e)
- {
- if (p != b && p != 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);
+ if(this_inited){
+ base_t::init(other_node);
+ }
+ if(other_inited){
+ base_t::init(this_node);
       }
    }
 
@@ -275,8 +290,109 @@
          node_ptr nxt(NodeTraits::get_next(i));
          if (nxt == e)
             break;
- transfer_after(e, i, nxt);
+ base_t::transfer_after(e, i, nxt);
+ }
+ }
+
+ //! <b>Effects</b>: Moves the node p n positions towards the end of the list.
+ //!
+ //! <b>Returns</b>: The previous node of p after the function if there has been any movement,
+ //! Null if n leads to no movement.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
+ static node_ptr move_backwards(node_ptr p, std::size_t n)
+ {
+ //Null shift, nothing to do
+ if(!n) return 0;
+ node_ptr first = NodeTraits::get_next(p);
+
+ //count() == 1 or 2, nothing to do
+ if(NodeTraits::get_next(first) == p)
+ return 0;
+
+ bool end_found = false;
+ node_ptr new_last(0);
+
+ //Now find the new last node according to the shift count.
+ //If we find p before finding the new last node
+ //unlink p, shortcut the search now that we know the size of the list
+ //and continue.
+ for(std::size_t i = 1; i <= n; ++i){
+ new_last = first;
+ first = NodeTraits::get_next(first);
+ if(first == p){
+ //Shortcut the shift with the modulo of the size of the list
+ n %= i;
+ if(!n)
+ return 0;
+ i = 0;
+ //Unlink p and continue the new first node search
+ first = NodeTraits::get_next(p);
+ base_t::unlink_after(new_last);
+ end_found = true;
+ }
       }
+
+ //If the p has not been found in the previous loop, find it
+ //starting in the new first node and unlink it
+ if(!end_found){
+ base_t::unlink_after(base_t::get_previous_node(first, p));
+ }
+
+ //Now link p after the new last node
+ base_t::link_after(new_last, p);
+ return new_last;
+ }
+
+ //! <b>Effects</b>: Moves the node p n positions towards the beginning of the list.
+ //!
+ //! <b>Returns</b>: The previous node of p after the function if there has been any movement,
+ //! Null if n leads equals to no movement.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
+ static node_ptr move_forward(node_ptr p, std::size_t n)
+ {
+ //Null shift, nothing to do
+ if(!n) return 0;
+ node_ptr first = node_traits::get_next(p);
+
+ //count() == 1 or 2, nothing to do
+ if(node_traits::get_next(first) == p) return 0;
+
+ //Iterate until p is found to know where the current last node is.
+ //If the shift count is less than the size of the list, we can also obtain
+ //the position of the new last node after the shift.
+ node_ptr old_last(first), next_to_it, new_last(p);
+ std::size_t distance = 1;
+ while(p != (next_to_it = node_traits::get_next(old_last))){
+ if(++distance > n)
+ new_last = node_traits::get_next(new_last);
+ old_last = next_to_it;
+ }
+ //If the shift was bigger or equal than the size, obtain the equivalent
+ //forward shifts and find the new last node.
+ if(distance <= n){
+ //Now find the equivalent forward shifts.
+ //Shortcut the shift with the modulo of the size of the list
+ std::size_t new_before_last_pos = (distance - (n % distance))% distance;
+ //If the shift is a multiple of the size there is nothing to do
+ if(!new_before_last_pos) return 0;
+
+ for( new_last = p
+ ; new_before_last_pos--
+ ; new_last = node_traits::get_next(new_last)){
+ //empty
+ }
+ }
+
+ //Now unlink p and link it after the new last node
+ base_t::unlink_after(old_last);
+ base_t::link_after(new_last, p);
+ return new_last;
    }
 };
 

Modified: branches/release/boost/intrusive/detail/tree_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/tree_algorithms.hpp (original)
+++ branches/release/boost/intrusive/detail/tree_algorithms.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -137,9 +137,9 @@
    { return uncast(header); }
 
    //! <b>Requires</b>: node is a node of the tree or an node initialized
- //! by init(...).
+ //! by init(...) or init_node.
    //!
- //! <b>Effects</b>: Returns true if the node is initialized by init().
+ //! <b>Effects</b>: Returns true if the node is initialized by init() or init_node().
    //!
    //! <b>Complexity</b>: Constant time.
    //!

Modified: branches/release/boost/intrusive/detail/utilities.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/utilities.hpp (original)
+++ branches/release/boost/intrusive/detail/utilities.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -498,7 +498,8 @@
 
 inline float fast_log2 (float val)
 {
- boost::uint32_t * const exp_ptr = reinterpret_cast <boost::uint32_t *>(&val);
+ boost::uint32_t * exp_ptr =
+ static_cast<boost::uint32_t *>(static_cast<void*>(&val));
    boost::uint32_t x = *exp_ptr;
    const int log_2 = (int)(((x >> 23) & 255) - 128);
    x &= ~(255 << 23);

Modified: branches/release/boost/intrusive/hashtable.hpp
==============================================================================
--- branches/release/boost/intrusive/hashtable.hpp (original)
+++ branches/release/boost/intrusive/hashtable.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -747,7 +747,7 @@
             }
             BOOST_INTRUSIVE_CATCH(...){
                this->clear_and_dispose(disposer);
- BOOST_RETHROW;
+ BOOST_INTRUSIVE_RETHROW;
             }
             BOOST_INTRUSIVE_CATCH_END
          }

Modified: branches/release/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- branches/release/boost/intrusive/intrusive_fwd.hpp (original)
+++ branches/release/boost/intrusive/intrusive_fwd.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -69,6 +69,8 @@
    , class O1 = none
    , class O2 = none
    , class O3 = none
+ , class O4 = none
+ , class O5 = none
>
 class slist;
 

Modified: branches/release/boost/intrusive/list.hpp
==============================================================================
--- branches/release/boost/intrusive/list.hpp (original)
+++ branches/release/boost/intrusive/list.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -208,7 +208,7 @@
       : data_(v_traits)
    {
       this->priv_size_traits().set_size(size_type(0));
- node_algorithms::init(this->get_root_node());
+ node_algorithms::init_header(this->get_root_node());
    }
 
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
@@ -224,7 +224,7 @@
       : data_(v_traits)
    {
       this->priv_size_traits().set_size(size_type(0));
- node_algorithms::init(this->get_root_node());
+ node_algorithms::init_header(this->get_root_node());
       this->insert(this->end(), b, e);
    }
 
@@ -258,7 +258,7 @@
    {
       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));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
       node_algorithms::link_before(this->get_root_node(), to_insert);
       this->priv_size_traits().increment();
    }
@@ -277,7 +277,7 @@
    {
       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));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
       node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
       this->priv_size_traits().increment();
    }
@@ -290,14 +290,8 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
- void pop_back()
- {
- node_ptr to_erase = node_traits::get_previous(this->get_root_node());
- node_algorithms::unlink(to_erase);
- this->priv_size_traits().decrement();
- if(safemode_or_autounlink)
- node_algorithms::init(to_erase);
- }
+ void pop_back()
+ { return this->pop_back_and_dispose(detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -329,14 +323,8 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
- void pop_front()
- {
- node_ptr to_erase = node_traits::get_next(this->get_root_node());
- node_algorithms::unlink(to_erase);
- this->priv_size_traits().decrement();
- if(safemode_or_autounlink)
- node_algorithms::init(to_erase);
- }
+ void pop_front()
+ { return this->pop_front_and_dispose(detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -406,7 +394,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const
- { return cbegin(); }
+ { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
    //!
@@ -430,7 +418,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return cend(); }
+ { return this->cend(); }
 
    //! <b>Effects</b>: Returns a constant iterator to the end of the list.
    //!
@@ -447,7 +435,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reverse_iterator rbegin()
- { return reverse_iterator(end()); }
+ { return reverse_iterator(this->end()); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
    //! of the reversed list.
@@ -456,7 +444,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin() const
- { return crbegin(); }
+ { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
    //! of the reversed list.
@@ -483,7 +471,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const
- { return crend(); }
+ { return this->crend(); }
 
    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
    //! of the reversed list.
@@ -492,7 +480,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator crend() const
- { return const_reverse_iterator(begin()); }
+ { return const_reverse_iterator(this->begin()); }
 
    //! <b>Precondition</b>: end_iterator must be a valid end iterator
    //! of list.
@@ -503,7 +491,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    static list_impl &container_from_end_iterator(iterator end_iterator)
- { return priv_container_from_end_iterator(end_iterator); }
+ { return list_impl::priv_container_from_end_iterator(end_iterator); }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //! of list.
@@ -514,7 +502,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    static const list_impl &container_from_end_iterator(const_iterator end_iterator)
- { return priv_container_from_end_iterator(end_iterator); }
+ { return list_impl::priv_container_from_end_iterator(end_iterator); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the list.
    //!
@@ -540,7 +528,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    bool empty() const
- { return node_algorithms::unique(this->get_root_node()); }
+ { return node_algorithms::unique(this->get_root_node()); }
 
    //! <b>Effects</b>: Swaps the elements of x and *this.
    //!
@@ -569,21 +557,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void shift_backwards(size_type n = 1)
- {
- //Null shift, nothing to do
- if(!n) return;
- node_ptr root = this->get_root_node();
- node_ptr last = node_traits::get_previous(root);
- //size() == 0 or 1, nothing to do
- if(last == node_traits::get_next(root)) return;
-
- node_algorithms::unlink(root);
- //Now get the new last node
- while(n--){
- last = node_traits::get_previous(last);
- }
- node_algorithms::link_after(last, root);
- }
+ { node_algorithms::move_forward(this->get_root_node(), n); }
 
    //! <b>Effects</b>: Moves forward all the elements, so that the second
    //! element becomes the first, the third becomes the second...
@@ -595,20 +569,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void shift_forward(size_type n = 1)
- {
- //Null shift, nothing to do
- if(!n) return;
- node_ptr root = this->get_root_node();
- node_ptr first = node_traits::get_next(root);
- //size() == 0 or 1, nothing to do
- if(first == node_traits::get_previous(root)) return;
- node_algorithms::unlink(root);
- //Now get the new first node
- while(n--){
- first = node_traits::get_next(first);
- }
- node_algorithms::link_before(first, root);
- }
+ { node_algorithms::move_backwards(this->get_root_node(), n); }
 
    //! <b>Effects</b>: Erases the element pointed by i of the list.
    //! No destructors are called.
@@ -623,16 +584,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
    iterator erase(iterator i)
- {
- iterator erase = i;
- ++i;
- node_ptr to_erase = erase.pointed_node();
- node_algorithms::unlink(to_erase);
- this->priv_size_traits().decrement();
- if(safemode_or_autounlink)
- node_algorithms::init(to_erase);
- return i;
- }
+ { return this->erase_and_dispose(i, detail::null_disposer()); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
    //!
@@ -652,10 +604,7 @@
    iterator erase(iterator b, iterator e)
    {
       if(safemode_or_autounlink || constant_time_size){
- while(b != e){
- b = this->erase(b);
- }
- return b;
+ return this->erase_and_dispose(b, e, detail::null_disposer());
       }
       else{
          node_algorithms::unlink(b.pointed_node(), e.pointed_node());
@@ -680,14 +629,13 @@
    template <class Disposer>
    iterator erase_and_dispose(iterator i, Disposer disposer)
    {
- iterator erase = i;
+ node_ptr to_erase(i.pointed_node());
       ++i;
- node_ptr to_erase = erase.pointed_node();
       node_algorithms::unlink(to_erase);
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
- disposer(get_real_value_traits().to_value_ptr(to_erase));
+ disposer(this->get_real_value_traits().to_value_ptr(to_erase));
       return i;
    }
 
@@ -708,10 +656,17 @@
    template <class Disposer>
    iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
    {
- while(b != e){
- b = this->erase_and_dispose(b, disposer);
+ node_ptr bp(b.pointed_node()), ep(e.pointed_node());
+ node_algorithms::unlink(bp, ep);
+ while(bp != ep){
+ node_ptr to_erase(bp);
+ bp = node_traits::get_next(bp);
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(get_real_value_traits().to_value_ptr(to_erase));
+ this->priv_size_traits().decrement();
       }
- return b;
+ return e;
    }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -726,10 +681,10 @@
    void clear()
    {
       if(safemode_or_autounlink){
- this->erase(this->begin(), this->end());
+ this->clear_and_dispose(detail::null_disposer());
       }
       else{
- node_algorithms::init(this->get_root_node());
+ node_algorithms::init_header(this->get_root_node());
          this->priv_size_traits().set_size(size_type(0));
       }
    }
@@ -747,7 +702,18 @@
    //! <b>Note</b>: Invalidates the iterators to the erased elements.
    template <class Disposer>
    void clear_and_dispose(Disposer disposer)
- { this->erase_and_dispose(this->begin(), this->end(), disposer); }
+ {
+ iterator it(this->begin()), itend(this->end());
+ while(it != itend){
+ node_ptr to_erase(it.pointed_node());
+ ++it;
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(get_real_value_traits().to_value_ptr(to_erase));
+ }
+ node_algorithms::init_header(this->get_root_node());
+ this->priv_size_traits().set_size(0);
+ }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -792,9 +758,9 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    iterator insert(iterator p, reference value)
    {
- node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
+ node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
       node_algorithms::link_before(p.pointed_node(), to_insert);
       this->priv_size_traits().increment();
       return iterator(to_insert, this);
@@ -921,19 +887,10 @@
    //! list. Iterators of this list and all the references are not invalidated.
    void splice(iterator p, list_impl&x, iterator start, iterator end)
    {
- if(start != end){
- if(constant_time_size){
- size_traits &thist = this->priv_size_traits();
- size_traits &xt = x.priv_size_traits();
- size_type increment = std::distance(start, end);
- node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
- thist.set_size(thist.get_size() + increment);
- xt.set_size(xt.get_size() - increment);
- }
- else{
- node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
- }
- }
+ if(constant_time_size)
+ this->splice(p, x, start, end, std::distance(start, end));
+ else
+ this->splice(p, x, start, end, 1);//distance is a dummy value
    }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -978,7 +935,7 @@
    //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
    //! is the list's size.
    void sort()
- { sort(std::less<value_type>()); }
+ { this->sort(std::less<value_type>()); }
 
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak ordering
    //!
@@ -1031,7 +988,7 @@
    //!
    //! <b>Note</b>: Iterators and references are not invalidated
    void merge(list_impl& x)
- { merge(x, std::less<value_type>()); }
+ { this->merge(x, std::less<value_type>()); }
 
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
    //! ordering and both *this and x must be sorted according to that ordering
@@ -1050,9 +1007,9 @@
    template<class Predicate>
    void merge(list_impl& x, Predicate p)
    {
- iterator e = this->end();
- iterator bx = x.begin();
- iterator ex = x.end();
+ iterator e(this->end());
+ iterator bx(x.begin());
+ iterator ex(x.end());
 
       for (iterator b = this->begin(); b != e; ++b) {
          size_type n(0);
@@ -1087,7 +1044,7 @@
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
    void remove(const_reference value)
- { remove_if(detail::equal_to_value<const_reference>(value)); }
+ { this->remove_if(detail::equal_to_value<const_reference>(value)); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1102,7 +1059,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class Disposer>
    void remove_and_dispose(const_reference value, Disposer disposer)
- { remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
+ { this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
 
    //! <b>Effects</b>: Removes all the elements for which a specified
    //! predicate is satisfied. No destructors are called.
@@ -1115,7 +1072,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class Pred>
    void remove_if(Pred pred)
- { remove_and_dispose_if(pred, detail::null_disposer()); }
+ { this->remove_and_dispose_if(pred, detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1132,17 +1089,15 @@
    template<class Pred, class Disposer>
    void remove_and_dispose_if(Pred pred, Disposer disposer)
    {
- iterator first = begin();
- iterator last = end();
- while(first != last) {
- iterator next = first;
- ++next;
- if(pred(*first)){
- pointer p = first.operator->();
- this->erase(first);
- disposer(p);
+ iterator cur(this->begin());
+ iterator last(this->end());
+ while(cur != last) {
+ if(pred(*cur)){
+ cur = this->erase_and_dispose(cur, disposer);
+ }
+ else{
+ ++cur;
          }
- first = next;
       }
    }
 
@@ -1156,7 +1111,7 @@
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
    void unique()
- { unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
+ { this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
 
    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
    //! elements that satisfy some binary predicate from the list.
@@ -1170,7 +1125,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class BinaryPredicate>
    void unique(BinaryPredicate pred)
- { unique_and_dispose(pred, detail::null_disposer()); }
+ { this->unique_and_dispose(pred, detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1186,7 +1141,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class Disposer>
    void unique_and_dispose(Disposer disposer)
- { unique_and_dispose(std::equal_to<value_type>(), disposer); }
+ { this->unique_and_dispose(std::equal_to<value_type>(), disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1203,18 +1158,19 @@
    template<class BinaryPredicate, class Disposer>
    void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
    {
- if(!this->empty()){
- iterator first = begin();
- iterator after = first;
+ iterator itend(this->end());
+ iterator cur(this->begin());
+
+ if(cur != itend){
+ iterator after(cur);
          ++after;
- while(after != this->end()){
- if(pred(*first, *after)){
- pointer p = after.operator->();
- after = erase(after);
- disposer(p);
+ while(after != itend){
+ if(pred(*cur, *after)){
+ after = this->erase_and_dispose(after, disposer);
             }
             else{
- first = after++;
+ cur = after;
+ ++after;
             }
          }
       }
@@ -1234,7 +1190,7 @@
    static iterator s_iterator_to(reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
- BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(value)));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
       return iterator(real_value_traits::to_node_ptr(value), 0);
    }
 
@@ -1252,7 +1208,7 @@
    static const_iterator s_iterator_to(const_reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
- BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(const_cast<reference> (value))));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
       return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), 0);
    }
 
@@ -1266,8 +1222,8 @@
    //!
    //! <b>Note</b>: Iterators and references are not invalidated.
    iterator iterator_to(reference value)
- {
- BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(value)));
+ {
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
       return iterator(real_value_traits::to_node_ptr(value), this);
    }
 
@@ -1281,8 +1237,8 @@
    //!
    //! <b>Note</b>: Iterators and references are not invalidated.
    const_iterator iterator_to(const_reference value) const
- {
- BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(real_value_traits::to_node_ptr(const_cast<reference> (value))));
+ {
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
       return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), this);
    }
 

Modified: branches/release/boost/intrusive/options.hpp
==============================================================================
--- branches/release/boost/intrusive/options.hpp (original)
+++ branches/release/boost/intrusive/options.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -318,10 +318,8 @@
 /// @endcond
 };
 
-//!This option setter specifies the type of
-//!a void pointer. This will instruct the hook
-//!to use this type of pointer instead of the
-//!default one
+//!This option setter specifies the link mode
+//!(normal_link, safe_link or auto_unlink)
 template<link_mode_type LinkType>
 struct link_mode
 {
@@ -334,10 +332,8 @@
 /// @endcond
 };
 
-//!This option setter specifies the type of
-//!a void pointer. This will instruct the hook
-//!to use this type of pointer instead of the
-//!default one
+//!This option setter specifies if the hook
+//!should be optimized for size instead of for speed.
 template<bool Enabled>
 struct optimize_size
 {
@@ -350,6 +346,34 @@
 /// @endcond
 };
 
+//!This option setter specifies if the list container should
+//!use a linear implementation instead of a circular one.
+template<bool Enabled>
+struct linear
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool linear = Enabled;
+ };
+/// @endcond
+};
+
+//!This option setter specifies if the list container should
+//!use a linear implementation instead of a circular one.
+template<bool Enabled>
+struct cache_last
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool cache_last = Enabled;
+ };
+/// @endcond
+};
+
 //!This option setter specifies the bucket traits
 //!class for unordered associative containers. When this option is specified,
 //!instead of using the default bucket traits, a user defined holder will be defined
@@ -475,6 +499,7 @@
       , tag<default_tag>
       , optimize_size<false>
       , store_hash<false>
+ , linear<false>
>::type
 {};
 

Modified: branches/release/boost/intrusive/slist.hpp
==============================================================================
--- branches/release/boost/intrusive/slist.hpp (original)
+++ branches/release/boost/intrusive/slist.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -21,13 +21,15 @@
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/slist_hook.hpp>
 #include <boost/intrusive/circular_slist_algorithms.hpp>
+#include <boost/intrusive/linear_slist_algorithms.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/options.hpp>
 #include <iterator>
 #include <functional>
 #include <algorithm>
-#include <cstddef>
+#include <cstddef> //std::size_t
+#include <utility> //std::pair
 
 namespace boost {
 namespace intrusive {
@@ -46,12 +48,27 @@
 struct get_default_slist_hook
 { typedef typename T::default_slist_hook type; };
 
-template <class ValueTraits, class SizeType, bool ConstantTimeSize>
+template <class ValueTraits, class SizeType, bool ConstantTimeSize, bool Linear, bool CacheLast>
 struct slistopt
 {
    typedef ValueTraits value_traits;
    typedef SizeType size_type;
- static const bool constant_time_size = ConstantTimeSize;
+ static const bool constant_time_size = ConstantTimeSize;
+ static const bool linear = Linear;
+ static const bool cache_last = CacheLast;
+};
+
+template<class Node, class NodePtr, bool>
+struct root_plus_last
+{
+ Node root_;
+ NodePtr last_;
+};
+
+template<class Node, class NodePtr>
+struct root_plus_last<Node, NodePtr, false>
+{
+ Node root_;
 };
 
 template <class T>
@@ -66,7 +83,9 @@
>::type
>
       , constant_time_size<true>
+ , linear<false>
       , size_type<std::size_t>
+ , cache_last<false>
>::type
 {};
 
@@ -86,15 +105,15 @@
 //!
 //! The container supports the following options:
 //! \c base_hook<>/member_hook<>/value_traits<>,
-//! \c constant_time_size<> and \c size_type<>.
+//! \c constant_time_size<>, \c size_type<>,
+//! \c linear<> and \c cache_last<>.
 //!
 //! The iterators of slist are forward iterators. slist provides a static
 //! function called "previous" to compute the previous iterator of a given iterator.
 //! This function has linear complexity. To improve the usability esp. with
 //! the '*_after' functions, ++end() == begin() and previous(begin()) == end()
-//! are defined. In addition, whenever you have an end iterator, 'after this
-//! iterator' means 'at the beginning of the list'. To improve the self-documentation
-//! a "before_begin()" function is defined, returning the end() iterator.
+//! are defined. An new special function "before_begin()" is defined, which returns
+//! an iterator that points one less the beginning of the list: ++before_begin() == begin()
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
 template<class T, class ...Options>
 #else
@@ -129,10 +148,16 @@
       <pointer, node>::type node_ptr;
    typedef typename boost::pointer_to_other
       <pointer, const node>::type const_node_ptr;
- typedef circular_slist_algorithms<node_traits> node_algorithms;
+ typedef typename detail::if_c
+ < Config::linear
+ , linear_slist_algorithms<node_traits>
+ , circular_slist_algorithms<node_traits>
+ >::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 linear = Config::linear;
+ static const bool cache_last = Config::cache_last;
 
    /// @cond
    private:
@@ -152,6 +177,16 @@
 
    //Constant-time size is incompatible with auto-unlink hooks!
    BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
+ //Linear singly linked lists are incompatible with auto-unlink hooks!
+ BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink)));
+ //A list with cached last node is incompatible with auto-unlink hooks!
+ BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink)));
+
+ node_ptr get_end_node()
+ { return node_ptr(linear ? 0 : this->get_root_node()); }
+
+ const_node_ptr get_end_node() const
+ { return const_node_ptr(linear ? 0 : this->get_root_node()); }
 
    node_ptr get_root_node()
    { return node_ptr(&data_.root_plus_size_.root_); }
@@ -159,16 +194,49 @@
    const_node_ptr get_root_node() const
    { return const_node_ptr(&data_.root_plus_size_.root_); }
 
+ node_ptr get_last_node()
+ { return this->get_last_node(detail::bool_<cache_last>()); }
+
+ const_node_ptr get_last_node() const
+ { return this->get_last_node(detail::bool_<cache_last>()); }
+
+ void set_last_node(node_ptr n)
+ { return this->set_last_node(n, detail::bool_<cache_last>()); }
+
+ node_ptr get_last_node(detail::bool_<false>)
+ { return node_ptr(0); }
+
+ const_node_ptr get_last_node(detail::bool_<false>) const
+ { return const_node_ptr(0); }
+
+ void set_last_node(node_ptr, detail::bool_<false>)
+ {}
+
+ node_ptr get_last_node(detail::bool_<true>)
+ { return node_ptr(data_.root_plus_size_.last_); }
+
+ const_node_ptr get_last_node(detail::bool_<true>) const
+ { return const_node_ptr(data_.root_plus_size_.last_); }
+
+ void set_last_node(node_ptr n, detail::bool_<true>)
+ { data_.root_plus_size_.last_ = n; }
+
    static node_ptr uncast(const_node_ptr ptr)
+ { return node_ptr(const_cast<node*>(detail::get_pointer(ptr))); }
+
+ void set_default_constructed_state()
    {
- return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
+ node_algorithms::init_header(this->get_root_node());
+ this->priv_size_traits().set_size(size_type(0));
+ if(cache_last){
+ this->set_last_node(this->get_root_node());
+ }
    }
 
    struct root_plus_size
       : public size_traits
- {
- node root_;
- };
+ , public root_plus_last<node, node_ptr, cache_last>
+ {};
 
    struct data_t
       : public slist_impl::value_traits
@@ -218,10 +286,7 @@
    //! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
    slist_impl(const value_traits &v_traits = value_traits())
       : data_(v_traits)
- {
- this->priv_size_traits().set_size(size_type(0));
- node_algorithms::init(this->get_root_node());
- }
+ { this->set_default_constructed_state(); }
 
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
    //!
@@ -235,9 +300,8 @@
    slist_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
       : data_(v_traits)
    {
- this->priv_size_traits().set_size(size_type(0));
- node_algorithms::init(this->get_root_node());
- insert_after(before_begin(), b, e);
+ this->set_default_constructed_state();
+ this->insert_after(this->before_begin(), b, e);
    }
 
    //! <b>Effects</b>: If it's a safe-mode
@@ -263,11 +327,10 @@
    void clear()
    {
       if(safemode_or_autounlink){
- this->erase_after(this->before_begin(), this->end());
+ this->clear_and_dispose(detail::null_disposer());
       }
       else{
- node_algorithms::init(this->get_root_node());
- this->priv_size_traits().set_size(size_type(0));
+ this->set_default_constructed_state();
       }
    }
 
@@ -283,7 +346,17 @@
    //! <b>Note</b>: Invalidates the iterators to the erased elements.
    template <class Disposer>
    void clear_and_dispose(Disposer disposer)
- { this->erase_after_and_dispose(this->before_begin(), this->end(), disposer); }
+ {
+ iterator it(this->begin()), itend(this->end());
+ while(it != itend){
+ node_ptr to_erase(it.pointed_node());
+ ++it;
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(get_real_value_traits().to_value_ptr(to_erase));
+ }
+ this->set_default_constructed_state();
+ }
 
    //! <b>Requires</b>: value must be an lvalue.
    //!
@@ -299,11 +372,33 @@
    {
       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));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ if(cache_last){
+ if(this->empty()){
+ this->set_last_node(to_insert);
+ }
+ }
       node_algorithms::link_after(this->get_root_node(), to_insert);
       this->priv_size_traits().increment();
    }
 
+ //! <b>Requires</b>: value must be an lvalue.
+ //!
+ //! <b>Effects</b>: Inserts the value in the back of the list.
+ //! No copy constructors are called.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references.
+ //! This function is only available is cache_last<> is true.
+ void push_back(reference value)
+ {
+ BOOST_STATIC_ASSERT((cache_last != 0));
+ this->insert_after(iterator(this->get_last_node(), this), value);
+ }
+
    //! <b>Effects</b>: Erases the first element of the list.
    //! No destructors are called.
    //!
@@ -313,13 +408,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the erased element.
    void pop_front()
- {
- node_ptr to_erase = node_traits::get_next(this->get_root_node());
- node_algorithms::unlink_after(this->get_root_node());
- this->priv_size_traits().decrement();
- if(safemode_or_autounlink)
- node_algorithms::init(to_erase);
- }
+ { return this->pop_front_and_dispose(detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -335,8 +424,16 @@
    void pop_front_and_dispose(Disposer disposer)
    {
       node_ptr to_erase = node_traits::get_next(this->get_root_node());
- this->pop_front();
+ node_algorithms::unlink_after(this->get_root_node());
+ this->priv_size_traits().decrement();
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
       disposer(get_real_value_traits().to_value_ptr(to_erase));
+ if(cache_last){
+ if(this->empty()){
+ this->set_last_node(this->get_root_node());
+ }
+ }
    }
 
    //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -345,7 +442,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    reference front()
- { return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
+ { return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
 
    //! <b>Effects</b>: Returns a const_reference to the first element of the list.
    //!
@@ -353,7 +450,35 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reference front() const
- { return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
+ { return *this->get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
+
+ //! <b>Effects</b>: Returns a reference to the last element of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references.
+ //! This function is only available is cache_last<> is true.
+ reference back()
+ {
+ BOOST_STATIC_ASSERT((cache_last != 0));
+ return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
+ }
+
+ //! <b>Effects</b>: Returns a const_reference to the last element of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references.
+ //! This function is only available is cache_last<> is true.
+ const_reference back() const
+ {
+ BOOST_STATIC_ASSERT((cache_last != 0));
+ return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
+ }
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the list.
    //!
@@ -377,7 +502,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cbegin() const
- { return const_iterator (node_traits::get_next(this->get_root_node()), this); }
+ { return const_iterator(node_traits::get_next(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
    //!
@@ -385,7 +510,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator end()
- { return iterator (this->get_root_node(), this); }
+ { return iterator(this->get_end_node(), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
    //!
@@ -393,7 +518,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return const_iterator (uncast(this->get_root_node()), this); }
+ { return const_iterator(uncast(this->get_end_node()), this); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the list.
    //!
@@ -401,7 +526,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cend() const
- { return const_iterator (uncast(this->get_root_node()), this); }
+ { return this->end(); }
 
    //! <b>Effects</b>: Returns an iterator that points to a position
    //! before the first element. Equivalent to "end()"
@@ -410,7 +535,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator before_begin()
- { return end(); }
+ { return iterator(this->get_root_node(), this); }
 
    //! <b>Effects</b>: Returns an iterator that points to a position
    //! before the first element. Equivalent to "end()"
@@ -419,7 +544,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator before_begin() const
- { return end(); }
+ { return const_iterator(uncast(this->get_root_node()), this); }
 
    //! <b>Effects</b>: Returns an iterator that points to a position
    //! before the first element. Equivalent to "end()"
@@ -428,7 +553,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator cbefore_begin() const
- { return end(); }
+ { return this->before_begin(); }
 
    //! <b>Precondition</b>: end_iterator must be a valid end iterator
    //! of slist.
@@ -439,7 +564,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    static slist_impl &container_from_end_iterator(iterator end_iterator)
- { return priv_container_from_end_iterator(end_iterator); }
+ { return slist_impl::priv_container_from_end_iterator(end_iterator); }
 
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //! of slist.
@@ -450,7 +575,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    static const slist_impl &container_from_end_iterator(const_iterator end_iterator)
- { return priv_container_from_end_iterator(end_iterator); }
+ { return slist_impl::priv_container_from_end_iterator(end_iterator); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the list.
    //!
@@ -482,12 +607,18 @@
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Linear to the number of elements of both lists.
+ //! <b>Complexity</b>: Linear to the number of elements of both lists.
+ //! Constant-time if linear<> and/or cache_last<> options are used.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void swap(slist_impl& other)
    {
- node_algorithms::swap_nodes(this->get_root_node(), other.get_root_node());
+ if(cache_last){
+ this->priv_swap_cache_last(other);
+ }
+ else{
+ this->priv_swap_lists(this->get_root_node(), other.get_root_node(), detail::bool_<linear>());
+ }
       if(constant_time_size){
          size_type backup = this->priv_size_traits().get_size();
          this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -505,45 +636,7 @@
    //!
    //! <b>Note</b>: Iterators Does not affect the validity of iterators and references.
    void shift_backwards(size_type n = 1)
- {
- //Null shift, nothing to do
- if(!n) return;
- node_ptr root = this->get_root_node();
- node_ptr first = node_traits::get_next(root);
-
- //size() == 0 or 1, nothing to do
- if(node_traits::get_next(first) == root) return;
-
- //Iterate until the root node is found to know where the current last node is.
- //If the shift count is less than the size of the list, we can also obtain
- //the position of the new last node after the shift.
- node_ptr old_last(first), next_to_it, new_last(root);
- size_type distance = 1;
- while(root != (next_to_it = node_traits::get_next(old_last))){
- if(++distance > n)
- new_last = node_traits::get_next(new_last);
- old_last = next_to_it;
- }
- //If the shift was bigger or equal than the size, obtain the equivalent
- //forward shifts and find the new last node.
- if(distance <= n){
- //Now find the equivalent forward shifts.
- //Shorcut the shift with the modulo of the size of the list
- size_type new_before_last_pos = (distance - (n % distance))% distance;
- //If the shift is a multiple of the size there is nothing to do
- if(!new_before_last_pos) return;
-
- for( new_last = root
- ; new_before_last_pos--
- ; new_last = node_traits::get_next(new_last)){
- //empty
- }
- }
-
- //Now unlink the root node and link it after the new last node
- node_algorithms::unlink_after(old_last);
- node_algorithms::link_after(new_last, root);
- }
+ { this->priv_shift_backwards(n, detail::bool_<linear>()); }
 
    //! <b>Effects</b>: Moves forward all the elements, so that the second
    //! element becomes the first, the third becomes the second...
@@ -555,45 +648,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    void shift_forward(size_type n = 1)
- {
- //Null shift, nothing to do
- if(!n) return;
- node_ptr root = this->get_root_node();
- node_ptr first = node_traits::get_next(root);
-
- //size() == 0 or 1, nothing to do
- if(node_traits::get_next(first) == root) return;
-
- bool end_found = false;
- node_ptr new_last(0);
-
- //Now find the new last node according to the shift count.
- //If we find the root node before finding the new last node
- //unlink the root, shortcut the search now that we know the size of the list
- //and continue.
- for(size_type i = 1; i <= n; ++i){
- new_last = first;
- first = node_traits::get_next(first);
- if(first == root){
- //Shorcut the shift with the modulo of the size of the list
- n %= i;
- i = 0;
- //Unlink the root node and continue the new first node search
- first = node_traits::get_next(first);
- node_algorithms::unlink_after(new_last);
- end_found = true;
- }
- }
-
- //If the root node has not been found in the previous loop, find it
- //starting in the new first node and unlink it
- if(!end_found){
- node_algorithms::unlink_after(node_algorithms::get_previous_node(first, root));
- }
-
- //Now link the root node after the new last node
- node_algorithms::link_after(new_last, root);
- }
+ { this->priv_shift_forward(n, detail::bool_<linear>()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -610,18 +665,18 @@
    //! <b>Throws</b>: If cloner throws.
    template <class Cloner, class Disposer>
    void clone_from(const slist_impl &src, Cloner cloner, Disposer disposer)
- {
+ {
       this->clear_and_dispose(disposer);
       BOOST_INTRUSIVE_TRY{
- iterator prev = this->before_begin();
+ iterator prev(this->before_begin());
          const_iterator b(src.begin()), e(src.end());
- for(; b != e; ++b, ++prev){
- this->insert_after(prev, *cloner(*b));
+ for(; b != e; ++b){
+ prev = this->insert_after(prev, *cloner(*b));
          }
       }
       BOOST_INTRUSIVE_CATCH(...){
          this->clear_and_dispose(disposer);
- BOOST_RETHROW;
+ BOOST_INTRUSIVE_RETHROW;
       }
       BOOST_INTRUSIVE_CATCH_END
    }
@@ -643,8 +698,12 @@
    {
       node_ptr n = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- node_algorithms::link_after(prev_p.pointed_node(), n);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ node_ptr prev_n(prev_p.pointed_node());
+ node_algorithms::link_after(prev_n, n);
+ if(cache_last && (this->get_last_node() == prev_n)){
+ this->set_last_node(n);
+ }
       this->priv_size_traits().increment();
       return iterator (n, this);
    }
@@ -665,7 +724,7 @@
    void insert_after(iterator prev_p, Iterator first, Iterator last)
    {
       for (; first != last; ++first)
- prev_p = insert_after(prev_p, *first);
+ prev_p = this->insert_after(prev_p, *first);
    }
 
    //! <b>Requires</b>: value must be an lvalue and p must point to an element
@@ -676,11 +735,12 @@
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Linear to the number of elements before p.
+ //! <b>Complexity</b>: Linear to the number of elements before p.
+ //! Constant-time if cache_last<> is true and p == end().
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    iterator insert(iterator p, reference value)
- { return insert_after(this->previous(p), value); }
+ { return this->insert_after(this->previous(p), value); }
 
    //! <b>Requires</b>: Dereferencing iterator must yield
    //! an lvalue of type value_type and p must point to an element
@@ -693,11 +753,12 @@
    //!
    //! <b>Complexity</b>: Linear to the number of elements inserted plus linear
    //! to the elements before b.
+ //! Linear to the number of elements to insert if cache_last<> option is true and p == end().
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    template<class Iterator>
    void insert(iterator p, Iterator b, Iterator e)
- { return insert_after(this->previous(p), b, e); }
+ { return this->insert_after(this->previous(p), b, e); }
 
    //! <b>Effects</b>: Erases the element after the element pointed by prev of
    //! the list. No destructors are called.
@@ -712,16 +773,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
    iterator erase_after(iterator prev)
- {
- iterator it(prev); ++it;
- node_ptr to_erase(it.pointed_node());
- node_algorithms::unlink_after(prev.pointed_node());
- this->priv_size_traits().decrement();
- iterator ret(++prev);
- if(safemode_or_autounlink)
- node_algorithms::init(to_erase);
- return ret;
- }
+ { return this->erase_after_and_dispose(prev, detail::null_disposer()); }
 
    //! <b>Effects</b>: Erases the range (before_first, last) from
    //! the list. No destructors are called.
@@ -731,18 +783,12 @@
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Lineal to the elements (last - before_first).
+ //! <b>Complexity</b>: Lineal to the elements (last - before_first + 1).
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
    iterator erase_after(iterator before_first, iterator last)
- {
- iterator first;
- while(++(first = before_first) != last){
- this->erase_after(before_first);
- }
- return last;
- }
+ { return this->erase_after_and_dispose(before_first, last, detail::null_disposer()); }
 
    //! <b>Effects</b>: Erases the element pointed by i of the list.
    //! No destructors are called.
@@ -775,7 +821,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased elements.
    iterator erase(iterator first, iterator last)
- { return erase_after(this->previous(first), last); }
+ { return this->erase_after(this->previous(first), last); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -794,11 +840,20 @@
    template<class Disposer>
    iterator erase_after_and_dispose(iterator prev, Disposer disposer)
    {
- iterator it(prev); ++it;
+ iterator it(prev);
+ ++it;
       node_ptr to_erase(it.pointed_node());
- iterator ret(this->erase_after(prev));
+ ++it;
+ node_ptr prev_n(prev.pointed_node());
+ node_algorithms::unlink_after(prev_n);
+ if(cache_last && (to_erase == this->get_last_node())){
+ this->set_last_node(prev_n);
+ }
+ this->priv_size_traits().decrement();
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
       disposer(get_real_value_traits().to_value_ptr(to_erase));
- return ret;
+ return it;
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -818,9 +873,19 @@
    template<class Disposer>
    iterator erase_after_and_dispose(iterator before_first, iterator last, Disposer disposer)
    {
- iterator first;
- while(++(first = before_first) != last){
- this->erase_after_and_dispose(before_first, disposer);
+ node_ptr bfp(before_first.pointed_node()), lp(last.pointed_node());
+ node_ptr fp(node_traits::get_next(bfp));
+ node_algorithms::unlink_after(bfp, lp);
+ while(fp != lp){
+ node_ptr to_erase(fp);
+ fp = node_traits::get_next(fp);
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(get_real_value_traits().to_value_ptr(to_erase));
+ this->priv_size_traits().decrement();
+ }
+ if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){
+ this->set_last_node(bfp);
       }
       return last;
    }
@@ -863,7 +928,7 @@
    //! erased elements.
    template<class Disposer>
    iterator erase_and_dispose(iterator first, iterator last, Disposer disposer)
- { return erase_after_and_dispose(this->previous(first), last, disposer); }
+ { return this->erase_after_and_dispose(this->previous(first), last, disposer); }
 
    //! <b>Requires</b>: Dereferencing iterator must yield
    //! an lvalue of type value_type.
@@ -884,7 +949,7 @@
    void assign(Iterator b, Iterator e)
    {
       this->clear();
- this->insert_after(before_begin(), b, e);
+ this->insert_after(this->before_begin(), b, e);
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -921,18 +986,21 @@
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Linear to the elements contained in x
+ //! <b>Complexity</b>: Linear to the elements contained in x.
+ //! Constant-time if cache_last<> option is true.
    //!
    //! <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(iterator prev, slist_impl &x)
    {
       if (!x.empty()){
- iterator last_x(x.previous(x.end()));
- node_algorithms::transfer_after
- ( prev.pointed_node()
- , x.end().pointed_node()
- , last_x.pointed_node());
+ 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());
+ if(cache_last && node_traits::get_next(prev_n) == this->get_end_node()){
+ this->set_last_node(last_x_n);
+ }
+ 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;
@@ -955,15 +1023,12 @@
    //!
    //! <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 splice_after(iterator prev, slist_impl &x, iterator prev_ele)
+ void splice_after(iterator prev_pos, slist_impl &x, iterator prev_ele)
    {
- iterator nxt = prev_ele;
- ++nxt;
- if (nxt != prev && prev_ele != prev){
- node_algorithms::transfer_after
- (prev.pointed_node(), prev_ele.pointed_node(), nxt.pointed_node());
- this->priv_size_traits().increment();
- x.priv_size_traits().decrement();
+ iterator elem = prev_ele;
+ ++elem;
+ if (elem != prev_pos && prev_ele != prev_pos){
+ this->splice_after(prev_pos, x, prev_ele, elem, 1);
       }
    }
 
@@ -984,19 +1049,11 @@
    //! list. Iterators of this list and all the references are not invalidated.
    void splice_after(iterator prev_pos, slist_impl &x, iterator before_first, iterator before_last)
    {
- if (before_first != before_last){
- if(constant_time_size){
- size_type increment = std::distance(before_first, before_last);
- node_algorithms::transfer_after
- (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
- this->priv_size_traits().set_size(this->priv_size_traits().get_size() + increment);
- x.priv_size_traits().set_size(x.priv_size_traits().get_size() - increment);
- }
- else{
- node_algorithms::transfer_after
- (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
- }
- }
+ if(constant_time_size)
+ this->splice_after(prev_pos, x, before_first, before_last, std::distance(before_first, before_last));
+ else
+ this->priv_splice_after
+ (prev_pos.pointed_node(), x, before_first.pointed_node(), before_last.pointed_node());
    }
 
    //! <b>Requires</b>: prev_pos must be a dereferenceable iterator in *this or be
@@ -1016,17 +1073,13 @@
    void splice_after(iterator prev_pos, slist_impl &x, iterator before_first, iterator before_last, difference_type n)
    {
       if(n){
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_first, before_last) == n);
+ this->priv_splice_after
+ (prev_pos.pointed_node(), x, before_first.pointed_node(), before_last.pointed_node());
          if(constant_time_size){
- BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_first, before_last) == n);
- node_algorithms::transfer_after
- (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
             this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n);
             x.priv_size_traits().set_size(x.priv_size_traits().get_size() - n);
          }
- else{
- node_algorithms::transfer_after
- (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
- }
       }
    }
 
@@ -1044,11 +1097,13 @@
    //!
    //! <b>Complexity</b>: Linear to the elements contained in x plus linear to
    //! the elements before it.
+ //! Linear to the elements before it if cache_last<> option is true.
+ //! Constant-time if cache_last<> option is true and it == end().
    //!
    //! <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(iterator it, slist_impl &x)
- { return splice_after(this->previous(it), x); }
+ { return this->splice_after(this->previous(it), x); }
 
    //! <b>Requires</b>: it p must be a valid iterator of *this.
    //! elem must point to an element contained in list
@@ -1060,11 +1115,12 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the elements before pos and before elem.
+ //! Linear to the elements before elem if cache_last<> option is true and pos == end().
    //!
    //! <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 splice(iterator pos, slist_impl &x, iterator elem)
- { return splice_after(this->previous(pos), x, this->previous(elem)); }
+ { return this->splice_after(this->previous(pos), x, x.previous(elem)); }
 
    //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
    //! and first and last belong to x and first and last a valid range on x.
@@ -1075,13 +1131,16 @@
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Linear to the sum of elements before pos, first, and last.
- //! Plus linear to the number of elements transferred if constant_time_size is true.
+ //! <b>Complexity</b>: Linear to the sum of elements before pos, first, and last
+ //! plus linear to the number of elements transferred if constant_time_size is true.
+ //! Linear to the sum of elements before first, and last
+ //! plus linear to the number of elements transferred if constant_time_size is true
+ //! if cache_last<> is true and pos == end()
    //!
    //! <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 splice(iterator pos, slist_impl &x, iterator first, iterator last)
- { return splice_after(this->previous(pos), x, this->previous(first), this->previous(last)); }
+ { return this->splice_after(this->previous(pos), x, x.previous(first), x.previous(last)); }
 
    //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
    //! and first and last belong to x and first and last a valid range on x.
@@ -1094,11 +1153,13 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the sum of elements before pos, first, and last.
+ //! Linear to the sum of elements before first and last
+ //! if cache_last<> is true and pos == end().
    //!
    //! <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 splice(iterator pos, slist_impl &x, iterator first, iterator last, difference_type n)
- { return splice_after(this->previous(pos), x, this->previous(first), this->previous(last), n); }
+ { return this->splice_after(this->previous(pos), x, x.previous(first), x.previous(last), n); }
 
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
@@ -1133,12 +1194,12 @@
                (last_inserted.pointed_node(), carry.end().pointed_node());
             iterator last_element(p, this);
             if(constant_time_size){
- counter[i].splice_after( counter[i].end(), carry
+ counter[i].splice_after( counter[i].before_begin(), carry
                                       , carry.before_begin(), last_element
                                       , carry.size());
             }
             else{
- counter[i].splice_after( counter[i].end(), carry
+ counter[i].splice_after( counter[i].before_begin(), carry
                                       , carry.before_begin(), last_element);
             }
             if(i == fill)
@@ -1153,11 +1214,11 @@
             (last_inserted.pointed_node(), counter[--fill].end().pointed_node());
          iterator last_element(p, this);
          if(constant_time_size){
- this->splice_after( end(), counter[fill], counter[fill].before_begin()
+ this->splice_after( before_begin(), counter[fill], counter[fill].before_begin()
                               , last_element, counter[fill].size());
          }
          else{
- this->splice_after( end(), counter[fill], counter[fill].before_begin()
+ this->splice_after( before_begin(), counter[fill], counter[fill].before_begin()
                               , last_element);
          }
       }
@@ -1201,14 +1262,14 @@
    template<class Predicate>
    iterator merge(slist_impl& x, Predicate p)
    {
- iterator a(before_begin()), e(end()), ax(x.before_begin());
+ iterator a(before_begin()), e(end()), ax(x.before_begin()), ex(x.end());
       iterator last_inserted(e);
       iterator a_next;
       while(++(a_next = a) != e && !x.empty()) {
          iterator ix(ax);
          iterator cx;
          size_type n(0);
- while(++(cx = ix) != ax && p(*cx, *a_next)){
+ while(++(cx = ix) != ex && p(*cx, *a_next)){
             ++ix; ++n;
          }
          if(ax != ix){
@@ -1235,7 +1296,7 @@
    //!
    //! <b>Note</b>: Iterators and references are not invalidated
    void merge(slist_impl& x)
- { this->merge(x, std::less<value_type>()); }
+ { this->merge(x, std::less<value_type>()); }
 
    //! <b>Effects</b>: Reverses the order of elements in the list.
    //!
@@ -1244,8 +1305,13 @@
    //! <b>Complexity</b>: This function is linear to the contained elements.
    //!
    //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
- { node_algorithms::reverse(this->get_root_node()); }
+ void reverse()
+ {
+ if(cache_last && !this->empty()){
+ this->set_last_node(node_traits::get_next(this->get_root_node()));
+ }
+ this->priv_reverse(detail::bool_<linear>());
+ }
 
    //! <b>Effects</b>: Removes all the elements that compare equal to value.
    //! No destructors are called.
@@ -1258,7 +1324,7 @@
    //! and iterators to elements that are not removed remain valid. This function is
    //! linear time: it performs exactly size() comparisons for equality.
    void remove(const_reference value)
- { remove_if(detail::equal_to_value<const_reference>(value)); }
+ { this->remove_if(detail::equal_to_value<const_reference>(value)); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1273,7 +1339,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class Disposer>
    void remove_and_dispose(const_reference value, Disposer disposer)
- { remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
+ { this->remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
 
    //! <b>Effects</b>: Removes all the elements for which a specified
    //! predicate is satisfied. No destructors are called.
@@ -1286,7 +1352,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class Pred>
    void remove_if(Pred pred)
- { remove_and_dispose_if(pred, detail::null_disposer()); }
+ { this->remove_and_dispose_if(pred, detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1303,18 +1369,20 @@
    template<class Pred, class Disposer>
    void remove_and_dispose_if(Pred pred, Disposer disposer)
    {
- iterator bcur(this->before_begin()), cur, e(this->end());
+ iterator bcur(this->before_begin()), cur(this->begin()), e(this->end());
       
- while(++(cur = bcur) != e){
+ while(cur != e){
          if (pred(*cur)){
- pointer p = cur.operator->();
- this->erase_after(bcur);
- disposer(p);
+ cur = this->erase_after_and_dispose(bcur, disposer);
          }
          else{
- ++bcur;
+ bcur = cur;
+ ++cur;
          }
       }
+ if(cache_last){
+ this->set_last_node(bcur.pointed_node());
+ }
    }
 
    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1327,7 +1395,7 @@
    //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
    //! and iterators to elements that are not removed remain valid.
    void unique()
- { unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
+ { this->unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
 
    //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
    //! elements that satisfy some binary predicate from the list.
@@ -1341,7 +1409,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class BinaryPredicate>
    void unique(BinaryPredicate pred)
- { unique_and_dispose(pred, detail::null_disposer()); }
+ { this->unique_and_dispose(pred, detail::null_disposer()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1357,7 +1425,7 @@
    //! and iterators to elements that are not removed remain valid.
    template<class Disposer>
    void unique_and_dispose(Disposer disposer)
- { unique(std::equal_to<value_type>(), disposer); }
+ { this->unique(std::equal_to<value_type>(), disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1374,21 +1442,23 @@
    template<class BinaryPredicate, class Disposer>
    void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
    {
- iterator end_n(end());
- iterator cur(begin());
- iterator cur_next;
-
- if (cur != end_n) {
- while(++(cur_next = cur) != end_n) {
- if (pred(*cur, *cur_next)){
- pointer p = cur_next.operator->();
- this->erase_after(cur);
- disposer(p);
+ iterator end_n(this->end());
+ iterator bcur(this->begin());
+ if(bcur != end_n){
+ iterator cur(bcur);
+ ++cur;
+ while(cur != end_n) {
+ if (pred(*bcur, *cur)){
+ cur = this->erase_after_and_dispose(bcur, disposer);
             }
             else{
+ bcur = cur;
                ++cur;
             }
          }
+ if(cache_last){
+ this->set_last_node(bcur.pointed_node());
+ }
       }
    }
 
@@ -1406,7 +1476,7 @@
    static iterator s_iterator_to(reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
- BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(value)));
+ //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
       return iterator (value_traits::to_node_ptr(value), 0);
    }
 
@@ -1424,7 +1494,7 @@
    static const_iterator s_iterator_to(const_reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
- BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(const_cast<reference> (value))));
+ //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
       return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
    }
 
@@ -1438,8 +1508,8 @@
    //!
    //! <b>Note</b>: Iterators and references are not invalidated.
    iterator iterator_to(reference value)
- {
- BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(value)));
+ {
+ //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
       return iterator (value_traits::to_node_ptr(value), this);
    }
 
@@ -1453,8 +1523,8 @@
    //!
    //! <b>Note</b>: Iterators and references are not invalidated.
    const_iterator iterator_to(const_reference value) const
- {
- BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(value_traits::to_node_ptr(const_cast<reference> (value))));
+ {
+ //BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
       return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this);
    }
 
@@ -1464,12 +1534,16 @@
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Linear to the number of elements before i.
+ //! <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
- (before_begin().pointed_node(), i.pointed_node()), 0);
+ (this->before_begin().pointed_node(), i.pointed_node()), this);
    }
 
    //! <b>Returns</b>: The const_iterator to the element before i in the list.
@@ -1479,18 +1553,117 @@
    //! <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 i) const
    {
+ if(cache_last && (i.pointed_node() == this->get_end_node())){
+ return iterator(uncast(this->get_last_node()), this);
+ }
       return const_iterator
          (node_algorithms::get_previous_node
- (before_begin().pointed_node(), i.pointed_node()), 0);
+ (this->before_begin().pointed_node(), i.pointed_node()), this);
    }
 
    private:
+ void priv_splice_after(node_ptr prev_pos_n, slist_impl &x, node_ptr before_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);
+ }
+ if(node_traits::get_next(before_last_n) == x.get_end_node()){
+ x.set_last_node(before_first_n);
+ }
+ }
+ node_algorithms::transfer_after(prev_pos_n, before_first_n, before_last_n);
+ }
+
+ void priv_reverse(detail::bool_<false>)
+ { node_algorithms::reverse(this->get_root_node()); }
+
+ void priv_reverse(detail::bool_<true>)
+ {
+ node_ptr new_first = node_algorithms::reverse
+ (node_traits::get_next(this->get_root_node()));
+ node_traits::set_next(this->get_root_node(), new_first);
+ }
+
+ void priv_shift_backwards(size_type n, detail::bool_<false>)
+ {
+ node_ptr last = node_algorithms::move_forward(this->get_root_node(), (std::size_t)n);
+ if(cache_last && last){
+ this->set_last_node(last);
+ }
+ }
+
+ void priv_shift_backwards(size_type n, detail::bool_<true>)
+ {
+ std::pair<node_ptr, node_ptr> ret(
+ node_algorithms::move_first_n_forward
+ (node_traits::get_next(this->get_root_node()), (std::size_t)n));
+ if(ret.first){
+ node_traits::set_next(this->get_root_node(), ret.first);
+ if(cache_last){
+ this->set_last_node(ret.second);
+ }
+ }
+ }
+
+ void priv_shift_forward(size_type n, detail::bool_<false>)
+ {
+ node_ptr last = node_algorithms::move_backwards(this->get_root_node(), (std::size_t)n);
+ if(cache_last && last){
+ this->set_last_node(last);
+ }
+ }
+
+ void priv_shift_forward(size_type n, detail::bool_<true>)
+ {
+ std::pair<node_ptr, node_ptr> ret(
+ node_algorithms::move_first_n_backwards
+ (node_traits::get_next(this->get_root_node()), (std::size_t)n));
+ if(ret.first){
+ node_traits::set_next(this->get_root_node(), ret.first);
+ if(cache_last){
+ this->set_last_node(ret.second);
+ }
+ }
+ }
+
+ void priv_swap_cache_last(slist_impl &other)
+ {
+ node_ptr other_last(other.get_last_node());
+ node_ptr this_last(this->get_last_node());
+ node_ptr other_bfirst(other.get_root_node());
+ node_ptr this_bfirst(this->get_root_node());
+ node_algorithms::transfer_after(this_bfirst, other_bfirst, other_last);
+ node_algorithms::transfer_after(other_bfirst, other_last != other_bfirst? other_last : this_bfirst, this_last);
+ node_ptr tmp(this->get_last_node());
+ this->set_last_node(other.get_last_node());
+ other.set_last_node(tmp);
+ if(this->get_last_node() == other_bfirst){
+ this->set_last_node(this_bfirst);
+ }
+ if(other.get_last_node() == this_bfirst){
+ other.set_last_node(other_bfirst);
+ }
+ }
+
+ //circular version
+ static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<false>)
+ { node_algorithms::swap_nodes(this_node, other_node); }
+
+ //linear version
+ static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<true>)
+ { node_algorithms::swap_trailing_nodes(this_node, other_node); }
+
    static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
    {
+ //Obtaining the container from the end iterator is not possible with linear
+ //singly linked lists (because "end" is represented by the null pointer)
+ BOOST_STATIC_ASSERT(!linear);
       root_plus_size *r = detail::parent_from_member<root_plus_size, node>
- ( detail::get_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
+ ( detail::get_pointer(end_iterator.pointed_node()), (&root_plus_size::root_));
       data_t *d = detail::parent_from_member<data_t, root_plus_size>
          ( r, &data_t::root_plus_size_);
       slist_impl *s = detail::parent_from_member<slist_impl, data_t>(d, &slist_impl::data_);
@@ -1620,13 +1793,13 @@
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
 template<class T, class ...Options>
 #else
-template<class T, class O1 = none, class O2 = none, class O3 = none>
+template<class T, class O1 = none, class O2 = none, class O3 = none, class O4 = none, class O5 = none>
 #endif
 struct make_slist
 {
    /// @cond
    typedef typename pack_options
- < slist_defaults<T>, O1, O2, O3>::type packed_options;
+ < slist_defaults<T>, O1, O2, O3, O4, O5>::type packed_options;
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
    typedef slist_impl
@@ -1635,6 +1808,8 @@
          < value_traits
          , typename packed_options::size_type
          , packed_options::constant_time_size
+ , packed_options::linear
+ , packed_options::cache_last
>
> implementation_defined;
    /// @endcond
@@ -1643,12 +1818,12 @@
 
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3>
+template<class T, class O1, class O2, class O3, class O4, class O5>
 class slist
- : public make_slist<T, O1, O2, O3>::type
+ : public make_slist<T, O1, O2, O3, O4, O5>::type
 {
    typedef typename make_slist
- <T, O1, O2, O3>::type Base;
+ <T, O1, O2, O3, O4, O5>::type Base;
    typedef typename Base::real_value_traits real_value_traits;
    //Assert if passed value traits are compatible with the type
    BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));

Modified: branches/release/boost/intrusive/slist_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/slist_hook.hpp (original)
+++ branches/release/boost/intrusive/slist_hook.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -19,6 +19,7 @@
 #include <boost/intrusive/detail/utilities.hpp>
 #include <boost/intrusive/detail/slist_node.hpp>
 #include <boost/intrusive/circular_slist_algorithms.hpp>
+#include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/detail/generic_hook.hpp>
 
@@ -31,6 +32,7 @@
 {
    typedef circular_slist_algorithms<slist_node_traits<VoidPointer> > type;
 };
+
 /// @endcond
 
 //! Helper metafunction to define a \c slist_base_hook that yields to the same

Modified: branches/release/libs/interprocess/doc/Jamfile.v2
==============================================================================
--- branches/release/libs/interprocess/doc/Jamfile.v2 (original)
+++ branches/release/libs/interprocess/doc/Jamfile.v2 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -26,6 +26,7 @@
         <doxygen:param>HIDE_UNDOC_MEMBERS=YES
         <doxygen:param>EXTRACT_PRIVATE=NO
         <doxygen:param>EXPAND_ONLY_PREDEF=YES
+ <doxygen:param>PREDEFINED=BOOST_INTERPROCESS_DOXYGEN_INVOKED
         <xsl:param>"boost.doxygen.reftitle=Boost.Interprocess Reference"
    ;
 

Modified: branches/release/libs/interprocess/doc/html/reference.css
==============================================================================
--- branches/release/libs/interprocess/doc/html/reference.css (original)
+++ branches/release/libs/interprocess/doc/html/reference.css 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,3 +1,11 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
 PRE.synopsis {
   background-color: #e0ffff;
   border: thin solid blue;

Modified: branches/release/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- branches/release/libs/interprocess/doc/interprocess.qbk (original)
+++ branches/release/libs/interprocess/doc/interprocess.qbk 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -6418,7 +6418,7 @@
    [classref boost::interprocess::named_mutex named_mutex].
 
 * Reduced template bloat for node and adaptive allocators extracting node
- implementation to a class taht only depends on the memory algorithm, instead of
+ implementation to a class that only depends on the memory algorithm, instead of
    the segment manager + node size + node number...
 
 * Fixed bug in `mapped_region` in UNIX when mapping address was provided but

Modified: branches/release/libs/interprocess/proj/conceptgcc/MakeAll
==============================================================================
--- branches/release/libs/interprocess/proj/conceptgcc/MakeAll (original)
+++ branches/release/libs/interprocess/proj/conceptgcc/MakeAll 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,35 +1,35 @@
-
-#ifndef CC
-CC=i686-pc-cygwin-conceptg++.exe
-#endif
-
-BOOST_ROOT=../../../..
-
-INTERPROCESS_CPP := $(wildcard ../../src/*.cpp)
-INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP))
-
-INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
-INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/conceptgcc/test_%.out, $(INTERPROCESSTEST_CPP))
-
-INTERPROCESSDOC_CPP := $(wildcard ../../example/*.cpp)
-INTERPROCESSDOC_OUT := $(patsubst ../../example/%.cpp, ../../bin/conceptgcc/ex_%.out, $(INTERPROCESSDOC_CPP))
-
-LIBDIR:= ../../../../stage/lib
-
-.PHONY: createdir clean
-
-all: createdir $(INTERPROCESSTEST_OUT) $(INTERPROCESSDOC_OUT)
- @cd .
-
-createdir:
- @mkdir -p ../../bin/conceptgcc
-
-../../bin/conceptgcc/test_%.out: ../../test/%.cpp
- $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
-
-../../bin/conceptgcc/ex_%.out: ../../example/%.cpp
- $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
-
-clean:
- rm -f *.o
- rm -f ../../bin/conceptgcc/*
+
+#ifndef CC
+CC=i686-pc-cygwin-conceptg++.exe
+#endif
+
+BOOST_ROOT=../../../..
+
+INTERPROCESS_CPP := $(wildcard ../../src/*.cpp)
+INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP))
+
+INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
+INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/conceptgcc/test_%.out, $(INTERPROCESSTEST_CPP))
+
+INTERPROCESSDOC_CPP := $(wildcard ../../example/*.cpp)
+INTERPROCESSDOC_OUT := $(patsubst ../../example/%.cpp, ../../bin/conceptgcc/ex_%.out, $(INTERPROCESSDOC_CPP))
+
+LIBDIR:= ../../../../stage/lib
+
+.PHONY: createdir clean
+
+all: createdir $(INTERPROCESSTEST_OUT) $(INTERPROCESSDOC_OUT)
+ @cd .
+
+createdir:
+ @mkdir -p ../../bin/conceptgcc
+
+../../bin/conceptgcc/test_%.out: ../../test/%.cpp
+ $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
+
+../../bin/conceptgcc/ex_%.out: ../../example/%.cpp
+ $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
+
+clean:
+ rm -f *.o
+ rm -f ../../bin/conceptgcc/*

Modified: branches/release/libs/interprocess/proj/cygwin/MakeAll
==============================================================================
--- branches/release/libs/interprocess/proj/cygwin/MakeAll (original)
+++ branches/release/libs/interprocess/proj/cygwin/MakeAll 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,33 +1,33 @@
-
-ifndef CC
-CC=g++
-endif
-
-BOOST_ROOT=../../../..
-
-INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
-INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/cygwin/test_%.out, $(INTERPROCESSTEST_CPP))
-
-#INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
-#INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/cygwin/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
-
-LIBDIR:= ../../../../stage/lib
-
-.PHONY: createdir clean
-
-all: createdir $(INTERPROCESSEXAMPLE_OUT) $(INTERPROCESSTEST_OUT)
- @cd .
-
-createdir:
- @mkdir -p ../../bin/cygwin
-
-../../bin/cygwin/test_%.out: ../../test/%.cpp
- $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@
-
-#../../bin/cygwin/ex_%.out: ../../example/%.cpp
-# $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@
-
-
-clean:
- rm -f *.o
- rm -f ../../bin/cygwin/*
+
+ifndef CC
+CC=g++
+endif
+
+BOOST_ROOT=../../../..
+
+INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
+INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/cygwin/test_%.out, $(INTERPROCESSTEST_CPP))
+
+#INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
+#INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/cygwin/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
+
+LIBDIR:= ../../../../stage/lib
+
+.PHONY: createdir clean
+
+all: createdir $(INTERPROCESSEXAMPLE_OUT) $(INTERPROCESSTEST_OUT)
+ @cd .
+
+createdir:
+ @mkdir -p ../../bin/cygwin
+
+../../bin/cygwin/test_%.out: ../../test/%.cpp
+ $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@
+
+#../../bin/cygwin/ex_%.out: ../../example/%.cpp
+# $(CC) -g $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-gcc-mt -I$(BOOST_ROOT) -lstdc++ -o $@
+
+
+clean:
+ rm -f *.o
+ rm -f ../../bin/cygwin/*

Modified: branches/release/libs/interprocess/proj/linux/MakeAll
==============================================================================
--- branches/release/libs/interprocess/proj/linux/MakeAll (original)
+++ branches/release/libs/interprocess/proj/linux/MakeAll 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,32 +1,32 @@
-
-ifndef CC
-CC=g++
-endif
-
-BOOST_ROOT=../../../..
-BOOST_LIBS=/usr/local/lib
-
-
-INTERPROCESS_CPP := $(wildcard ../../test/*.cpp)
-INTERPROCESS_OUT := $(patsubst ../../test/%.cpp, ../../bin/linux/test_%.out, $(INTERPROCESS_CPP))
-
-INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
-INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/linux/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
-
-.PHONY: createdir clean
-
-all: createdir $(INTERPROCESS_OUT) $(INTERPROCESSEXAMPLE_OUT)
- @cd .
-
-createdir:
- @mkdir -p ../../bin/linux
-
-../../bin/linux/test_%.out: ../../test/%.cpp
- $(CC) $< -Wall -pedantic -g -pthread -DBOOST_DATE_TIME_NO_LIB -lstdc++ -lrt -lboost_thread-gcc-mt -I$(BOOST_ROOT) -L$(BOOST_LIBS) -o $@
-
-../../bin/linux/ex_%.out: ../../example/%.cpp
- $(CC) $< -Wall -pedantic -g -pthread -DBOOST_DATE_TIME_NO_LIB -lstdc++ -lrt -lboost_thread-gcc-mt -I$(BOOST_ROOT) -L$(BOOST_LIBS) -o $@
-
-clean:
- rm -f *.o
- rm -f ../../bin/linux/*
+
+ifndef CC
+CC=g++
+endif
+
+BOOST_ROOT=../../../..
+BOOST_LIBS=/usr/local/lib
+
+
+INTERPROCESS_CPP := $(wildcard ../../test/*.cpp)
+INTERPROCESS_OUT := $(patsubst ../../test/%.cpp, ../../bin/linux/test_%.out, $(INTERPROCESS_CPP))
+
+INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
+INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/linux/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
+
+.PHONY: createdir clean
+
+all: createdir $(INTERPROCESS_OUT) $(INTERPROCESSEXAMPLE_OUT)
+ @cd .
+
+createdir:
+ @mkdir -p ../../bin/linux
+
+../../bin/linux/test_%.out: ../../test/%.cpp
+ $(CC) $< -Wall -pedantic -g -pthread -DBOOST_DATE_TIME_NO_LIB -lstdc++ -lrt -lboost_thread-gcc-mt -I$(BOOST_ROOT) -L$(BOOST_LIBS) -o $@
+
+../../bin/linux/ex_%.out: ../../example/%.cpp
+ $(CC) $< -Wall -pedantic -g -pthread -DBOOST_DATE_TIME_NO_LIB -lstdc++ -lrt -lboost_thread-gcc-mt -I$(BOOST_ROOT) -L$(BOOST_LIBS) -o $@
+
+clean:
+ rm -f *.o
+ rm -f ../../bin/linux/*

Modified: branches/release/libs/interprocess/proj/mingw/MakeAll
==============================================================================
--- branches/release/libs/interprocess/proj/mingw/MakeAll (original)
+++ branches/release/libs/interprocess/proj/mingw/MakeAll 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,35 +1,35 @@
-
-ifndef CC
-CC=g++
-endif
-
-BOOST_ROOT=../../../..
-
-INTERPROCESS_CPP := $(wildcard ../../src/*.cpp)
-INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP))
-
-INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
-INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/mingw/test_%.out, $(INTERPROCESSTEST_CPP))
-
-INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
-INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/mingw/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
-
-LIBDIR:= ../../../../stage/lib
-
-.PHONY: createdir clean
-
-all: createdir $(INTERPROCESSTEST_OUT) $(INTERPROCESSEXAMPLE_OUT)
- @cd .
-
-createdir:
- @mkdir -p ../../bin/mingw
-
-../../bin/mingw/test_%.out: ../../test/%.cpp
- $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
-
-../../bin/mingw/ex_%.out: ../../example/%.cpp
- $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
-
-clean:
- rm -f *.o
- rm -f ../../bin/mingw/*
+
+ifndef CC
+CC=g++
+endif
+
+BOOST_ROOT=../../../..
+
+INTERPROCESS_CPP := $(wildcard ../../src/*.cpp)
+INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP))
+
+INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
+INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/mingw/test_%.out, $(INTERPROCESSTEST_CPP))
+
+INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
+INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/mingw/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
+
+LIBDIR:= ../../../../stage/lib
+
+.PHONY: createdir clean
+
+all: createdir $(INTERPROCESSTEST_OUT) $(INTERPROCESSEXAMPLE_OUT)
+ @cd .
+
+createdir:
+ @mkdir -p ../../bin/mingw
+
+../../bin/mingw/test_%.out: ../../test/%.cpp
+ $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR) -lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
+
+../../bin/mingw/ex_%.out: ../../example/%.cpp
+ $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -L$(LIBDIR)-lboost_thread-mgw-mt -I$(BOOST_ROOT) -lstdc++ -o $@
+
+clean:
+ rm -f *.o
+ rm -f ../../bin/mingw/*

Modified: branches/release/libs/interprocess/proj/qnx/MakeAll
==============================================================================
--- branches/release/libs/interprocess/proj/qnx/MakeAll (original)
+++ branches/release/libs/interprocess/proj/qnx/MakeAll 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,33 +1,33 @@
-
-ifndef CC
-CC=g++
-endif
-
-BOOST_ROOT=../../../..
-
-INTERPROCESS_CPP := $(wildcard ../../src/*.cpp)
-INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP))
-
-INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
-INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/qnx/test_%.out, $(INTERPROCESSTEST_CPP))
-
-INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
-INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/qnx/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
-
-.PHONY: createdir clean
-
-all: createdir $(INTERPROCESSTEST_OUT) $(INTERPROCESSEXAMPLE_OUT)
- @cd .
-
-createdir:
- @mkdir -p ../../bin/qnx
-
-../../bin/qnx/test_%.out: ../../test/%.cpp
- $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@
-
-../../bin/qnx/ex_%.out: ../../example/%.cpp
- $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@
-
-clean:
- rm -f *.o
- rm -f ../../bin/qnx/*
+
+ifndef CC
+CC=g++
+endif
+
+BOOST_ROOT=../../../..
+
+INTERPROCESS_CPP := $(wildcard ../../src/*.cpp)
+INTERPROCESS_OBJ := $(patsubst ../../src/%.cpp, lib_%.o, $(INTERPROCESS_CPP))
+
+INTERPROCESSTEST_CPP := $(wildcard ../../test/*.cpp)
+INTERPROCESSTEST_OUT := $(patsubst ../../test/%.cpp, ../../bin/qnx/test_%.out, $(INTERPROCESSTEST_CPP))
+
+INTERPROCESSEXAMPLE_CPP := $(wildcard ../../example/*.cpp)
+INTERPROCESSEXAMPLE_OUT := $(patsubst ../../example/%.cpp, ../../bin/qnx/ex_%.out, $(INTERPROCESSEXAMPLE_CPP))
+
+.PHONY: createdir clean
+
+all: createdir $(INTERPROCESSTEST_OUT) $(INTERPROCESSEXAMPLE_OUT)
+ @cd .
+
+createdir:
+ @mkdir -p ../../bin/qnx
+
+../../bin/qnx/test_%.out: ../../test/%.cpp
+ $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@
+
+../../bin/qnx/ex_%.out: ../../example/%.cpp
+ $(CC) $< -Wall -DBOOST_DATE_TIME_NO_LIB -lboost_thread-gcc-mt-s -I$(BOOST_ROOT) -o $@
+
+clean:
+ rm -f *.o
+ rm -f ../../bin/qnx/*

Deleted: branches/release/libs/interprocess/proj/to-do.txt
==============================================================================
--- branches/release/libs/interprocess/proj/to-do.txt 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
+++ (empty file)
@@ -1,73 +0,0 @@
--> Implement zero_memory flag for allocation_command
-
--> Add explanations about system libraries (-lrt) or options (-pthread) to be added
- to the command line.
-
--> The general allocation funtion can be improved with some fixed size allocation bins.
-
--> Update the documentation about memory algorithms with explanations about new functions.
-
--> Adapt error reporting to TR1 system exceptions
-
--> Improve exception messages
-
--> Movability of containers should depend on the no-throw guarantee of allocators copy constructor
-
--> Check self-assignment for vectors
-
--> Detect POD data in vector/deque to use memcpy and minimize code.
-
--> Update writing a new memory allocator explaining new functions (like alignment)
-
--> private node allocators could take the number of nodes as a runtime parameter.
-
--> Explain how to build intrusive indexes.
-
--> Add intrusive index types as available indexes.
-
--> Add maximum alignment allocation limit in PageSize bytes. Otherwise, we can't
- guarantee alignment for process-shared allocations.
-
--> Add default algorithm and index types. The user does not need to know how are
- they implemented.
-
--> Add private mapping to managed classes.
-
--> Add unique_ptr documentation.
-
--> Pass max size check in allocation to node pools
-
--> Add atomic_func explanation in docs
-
--> Once shrink to fit indexes is implemented test all memory has been deallocated
- in tests to detect leaks/implementation failures.
-
--> Improve allocate_many functions to allocate all the nodes forming a singly
- linked list of nodes.
-
--> rbtree_algorithms can be improved wrt the balanced tree. When erasing the old
- node and inserting the new (expanded or shrunk) check if the position should
- be the same. If so, avoid erase() + insert() and just update the size.
-
--> Use in-place expansion capabilities to shrink_to_fit and reserve functions
- from iunordered_index.
-
--> Refactor pool allocators to extract common operations
-
--> Shrink in place interface is not adequate for with objects that don't have
- a trivial destructor: how many destructors can we call before deallocating
- the memory? Options:
- 1. Call destructors in the low-level shrink function (but this might lead to
- deadlock)
- 2. Offer a function to know how much can we shrink (but destructor + shrinking
- would not be atomic so we must guarantee that shrinking will succeed).
-
--> Optimize copy_n with std::copy in vector. Revise other functions to improve optimizations
-
--> Keep an eye on container iterator constness issue to bring Interprocess containers up-to-date.
-
--> change unique_ptr to avoid using compressed_pair
-
--> Improve unique_ptr test to test move assignment and other goodies like assigment from null
-
--> barrier_test fails on MacOS X on PowerPC.
\ No newline at end of file

Modified: branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln
==============================================================================
--- branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln (original)
+++ branches/release/libs/interprocess/proj/vc7ide/Interprocess.sln 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,847 +1,847 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_memory_mapping_test", "shared_memory_mappable_test.vcproj", "{5CE18C83-6025-36FE-A4F7-BA09176D3A11}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_memory_test", "shared_memory_test.vcproj", "{5E2838CC-0916-8F4E-A4F7-93506BA0D310}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_ptr_test", "shared_ptr_test.vcproj", "{5371C383-6092-1238-A877-BAEB37867609}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist_test", "slist_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_test", "string_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D4A792607}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tree_test", "tree_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upgradable_mutex_test", "upgradable_mutex.vcproj", "{4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_buffer_test", "user_buffer_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792603}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vectorstream_test", "vectorstream_test.vcproj", "{58CCE183-6032-12FE-A4F7-BA893A767601}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_test", "vector_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_condition_test", "named_condition_test.vcproj", "{58CC2563-6092-48FE-FAF7-BA046A792658}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_mutexA", "doc_anonymous_mutexA.vcproj", "{58C1B183-9026-4E63-12F2-005412200054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_mutexB", "doc_anonymous_mutexB.vcproj", "{58C1B183-9026-4E63-12F2-005202441254}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_mutex", "doc_named_mutex.vcproj", "{58C181B3-9516-463E-2F12-122155400054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_conditionA", "doc_anonymous_conditionA.vcproj", "{5C1B8183-0296-4F83-1F22-001005220544}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_conditionB", "doc_anonymous_conditionB.vcproj", "{58C1FE83-2906-E643-2F12-024410052254}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_conditionA", "doc_named_conditionA.vcproj", "{58EB1CB3-1354-364E-12F2-154356612054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_conditionB", "doc_named_conditionB.vcproj", "{58181CB3-5134-634E-12F2-155435622054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_semaphoreA", "doc_anonymous_semaphoreA.vcproj", "{5CB81183-29FB-F843-24FF-022050100544}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_semaphoreB", "doc_anonymous_semaphoreB.vcproj", "{58FBE8C3-9026-FAB2-E643-000522441254}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_upgradable_mutex_test", "named_upgradable_mutex.vcproj", "{48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_upgradable_mutexA", "doc_anonymous_upgradable_mutexA.vcproj", "{5C18831B-F162-FA96-E6C3-FA5122040054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_upgradable_mutexB", "doc_anonymous_upgradable_mutexB.vcproj", "{5C1B1043-1EFF-2793-4E63-245241283054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_message_queueA", "doc_message_queueA.vcproj", "{51B189C3-4E63-9026-12F2-12200AF54054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_message_queueB", "doc_message_queueB.vcproj", "{5C1B1813-12C2-0296-4E63-244549126520}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_cont", "doc_cont.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792653}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_contA", "doc_contA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792652}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_contB", "doc_contB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792651}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory", "doc_shared_memory.vcproj", "{58CCE183-6032-12FE-4FC7-83A79F760B61}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_test", "unique_ptr_test.vcproj", "{571C3383-6092-A877-1238-B3786BAE7605}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_containers", "doc_move_containers.vcproj", "{58C1B183-0296-EA42-EF04-005120054104}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map_index_allocation_test", "map_index_allocation_test.vcproj", "{588CCD13-2962-83FE-F4B7-92230DB73629}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_map_index_allocation_test", "flat_map_index_allocation_test.vcproj", "{51D8E9C3-2D65-48FE-3AA7-7922C0E36329}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iset_index_allocation_test", "iset_index_allocation_test.vcproj", "{58BD1CC3-6972-F3F7-84BE-0DB736035922}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iunordered_set_index_allocation_test", "iunordered_set_index_allocation_test.vcproj", "{5BD1C7C3-3F7F-6972-84BE-B731D9236035}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory2", "doc_shared_memory2.vcproj", "{58CE1D83-F31E-4FD7-6132-8A79F6307B61}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_mapping2", "doc_file_mapping2.vcproj", "{5CE19883-F413-7EFD-6342-B79639F7B611}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_mapping", "doc_file_mapping.vcproj", "{58DE18C3-3261-2F3E-FD47-83760B9FA761}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_map", "doc_map.vcproj", "{59CEC183-8192-8F6D-4FB7-BA260A79D352}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows_shared_memory_test", "windows_shared_memory_test.vcproj", "{E385C28C-0691-4FA7-F48E-935BA0D06310}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows_shared_memory_mapping_test", "windows_shared_memory_mapping_test.vcproj", "{518CE8C3-6512-FA75-46EF-B917A3A116D1}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "managed_windows_shared_memory_test", "managed_windows_shared_memory.vcproj", "{5D18CE83-1926-7AE4-FE94-B606D9B23131}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_pool_test", "adaptive_pool_test.vcproj", "{58CE1D84-1962-4FE9-BA0D-A4F7973A4652}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cached_adaptive_pool_test", "cached_adaptive_pool_test.vcproj", "{5188E3CE-2964-F43E-FB87-B037AC692D59}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "private_adaptive_pool_test", "private_adaptive_pool_test.vcproj", "{5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_allocator", "doc_allocator.vcproj", "{581B1C83-4E12-9526-020F-012482540054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_node_allocator", "doc_node_allocator.vcproj", "{51B17C83-E172-5396-0FA2-825472008554}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_private_node_allocator", "doc_private_node_allocator.vcproj", "{2B75C833-17D2-4956-A23F-820854254175}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_cached_node_allocator", "doc_cached_node_allocator.vcproj", "{283AD375-7D12-5866-23BF-854308651275}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_adaptive_pool", "doc_adaptive_pool.vcproj", "{57C832B1-17D2-9537-FA12-827220448554}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_cached_adaptive_pool", "doc_cached_adaptive_pool.vcproj", "{536C8251-7E12-9537-A1E2-822073258554}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_private_adaptive_pool", "doc_private_adaptive_pool.vcproj", "{83258CB1-127E-9375-F872-8324A1054454}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_raw_allocation", "doc_managed_raw_allocation.vcproj", "{5198EFC3-2731-F34E-4FD8-1859AC94F761}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_aligned_allocation", "doc_managed_aligned_allocation.vcproj", "{58DE18C3-3261-2F3E-FD47-83760B9FA761}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_interprocesslib", "interprocesslib.vcproj", "{FFAA56F1-32EC-4B22-B6BD-95A311A67C35}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_windows_shared_memory", "doc_windows_shared_memory.vcproj", "{5E17C9C3-1362-2E1E-C84F-8A76B6739F21}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_windows_shared_memory2", "doc_windows_shared_memory2.vcproj", "{5E1D6C83-31DE-4F6F-6132-87A9FB663041}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_node_pool_test", "adaptive_node_pool_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "node_pool_test", "node_pool_test.vcproj", "{8A519DC3-6092-A4FE-F748-BA91328D6522}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deque_test", "deque_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792655}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "barrier_test", "barrier_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792661}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bufferstream_test", "bufferstream_test.vcproj", "{58C183CE-6203-FE12-A237-BA8976695960}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cached_node_allocator_test", "cached_node_allocator_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792659}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "private_node_allocator_test", "private_node_allocator_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792620}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "node_allocator_test", "node_allocator_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792622}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_mutex_test", "named_mutex_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792625}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_recursive_mutex_test", "named_recursive_mutex_test.vcproj", "{5C83CE18-4F48-A7FE-6092-B7920AD3A624}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_semaphore_test", "named_semaphore_test.vcproj", "{58CCE283-1609-48FE-A4F7-BA0D3A793523}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_heap_memory", "doc_managed_heap_memory.vcproj", "{58CCE183-6092-48FE-A4FC-BA0D3A792647}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocexcept_test", "allocexcept_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792662}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condition_test", "condition_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792658}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "data_test", "data_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792657}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_bufferstream", "doc_bufferstream.vcproj", "{58C1B183-9026-4E12-00F2-001200540054}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_intrusive", "doc_intrusive.vcproj", "{5E18CC83-6092-48FE-A677-B832A0D3A650}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_messageA", "doc_ipc_messageA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792649}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_messageB", "doc_ipc_messageB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792648}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_mapped_file", "doc_managed_mapped_file.vcproj", "{58CCE183-5091-48FE-A4FC-BA0D3A792446}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_allocA", "doc_named_allocA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792645}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_allocB", "doc_named_allocB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792644}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_offset_ptr", "doc_offset_ptr.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792643}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_scoped_ptr", "doc_scoped_ptr.vcproj", "{58CC8E13-0962-8F4E-77A6-BD3A6832A042}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_vectorstream", "doc_vectorstream.vcproj", "{58C1B183-9260-4E8F-F200-000000000041}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_where_allocate", "doc_where_allocate.vcproj", "{58CCE183-6092-48FE-A677-BA0D3A832640}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file_mapping_test", "file_mapping_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792638}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792637}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intrusive_ptr_test", "intrusive_ptr_test.vcproj", "{5821C383-6092-12FE-A877-BA0D33467633}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792632}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "managed_mapped_file_test", "managed_mapped_file_test.vcproj", "{5CCE1883-0926-F7A4-8FE4-BA0606D92331}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mapped_file_test", "mapped_file_test.vcproj", "{5C6D9CE1-2609-F7A4-8FE4-BA0883602330}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memory_algorithm_test", "memory_algorithm_test.vcproj", "{58E18CC3-6092-8F4E-A3E7-A792230D3629}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "message_queue_test", "message_queue.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792628}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutex_test", "mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A27}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_index_test", "null_index_test.vcproj", "{0000058C-0000-0000-0000-000000000021}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recursive_mutex_test", "recursive_mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A14}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "semaphore_test", "semaphore_test.vcproj", "{5CE28C83-48FE-1676-4FA7-B50D3A76A013}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_multiple_allocation", "doc_managed_multiple_allocation.vcproj", "{818C43EE-3561-F3AE-4FD7-8A2076E76A31}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_allocation_command", "doc_managed_allocation_command.vcproj", "{5189DEA3-3261-F33E-47ED-83BC69F66061}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_construction_info", "doc_managed_construction_info.vcproj", "{5C82D1D3-3861-3AF1-03EF-89AED4716761}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_ptr_explicit", "doc_shared_ptr_explicit.vcproj", "{4E887AC3-F8EA-6923-A744-C264A398C913}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_unique_ptr", "doc_unique_ptr.vcproj", "{589C2EB3-8A57-1862-F4EA-A6B14C7329A3}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_ptr", "doc_shared_ptr.vcproj", "{51CE89A3-6092-F4EA-48A7-B4B9AC326093}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "managed_shared_memory_test", "managed_shared_memory.vcproj", "{58DF28E3-0926-F47A-E28A-B03A4D619631}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_grow", "doc_managed_grow.vcproj", "{818C43EE-3561-F3AE-4FD7-8A2076E76A31}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "offset_ptr_test", "offset_ptr_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.ActiveCfg = Debug|Win32
- {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.Build.0 = Debug|Win32
- {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Release.ActiveCfg = Release|Win32
- {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Release.Build.0 = Release|Win32
- {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Debug.ActiveCfg = Debug|Win32
- {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Debug.Build.0 = Debug|Win32
- {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Release.ActiveCfg = Release|Win32
- {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Release.Build.0 = Release|Win32
- {5371C383-6092-1238-A877-BAEB37867609}.Debug.ActiveCfg = Debug|Win32
- {5371C383-6092-1238-A877-BAEB37867609}.Debug.Build.0 = Debug|Win32
- {5371C383-6092-1238-A877-BAEB37867609}.Release.ActiveCfg = Release|Win32
- {5371C383-6092-1238-A877-BAEB37867609}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
- {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Debug.ActiveCfg = Debug|Win32
- {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Debug.Build.0 = Debug|Win32
- {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Release.ActiveCfg = Release|Win32
- {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Release.Build.0 = Release|Win32
- {58CCE183-6032-12FE-A4F7-BA893A767601}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6032-12FE-A4F7-BA893A767601}.Debug.Build.0 = Debug|Win32
- {58CCE183-6032-12FE-A4F7-BA893A767601}.Release.ActiveCfg = Release|Win32
- {58CCE183-6032-12FE-A4F7-BA893A767601}.Release.Build.0 = Release|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
- {58CC2563-6092-48FE-FAF7-BA046A792658}.Debug.ActiveCfg = Debug|Win32
- {58CC2563-6092-48FE-FAF7-BA046A792658}.Debug.Build.0 = Debug|Win32
- {58CC2563-6092-48FE-FAF7-BA046A792658}.Release.ActiveCfg = Release|Win32
- {58CC2563-6092-48FE-FAF7-BA046A792658}.Release.Build.0 = Release|Win32
- {58C1B183-9026-4E63-12F2-005412200054}.Debug.ActiveCfg = Debug|Win32
- {58C1B183-9026-4E63-12F2-005412200054}.Debug.Build.0 = Debug|Win32
- {58C1B183-9026-4E63-12F2-005412200054}.Release.ActiveCfg = Release|Win32
- {58C1B183-9026-4E63-12F2-005412200054}.Release.Build.0 = Release|Win32
- {58C1B183-9026-4E63-12F2-005202441254}.Debug.ActiveCfg = Debug|Win32
- {58C1B183-9026-4E63-12F2-005202441254}.Debug.Build.0 = Debug|Win32
- {58C1B183-9026-4E63-12F2-005202441254}.Release.ActiveCfg = Release|Win32
- {58C1B183-9026-4E63-12F2-005202441254}.Release.Build.0 = Release|Win32
- {58C181B3-9516-463E-2F12-122155400054}.Debug.ActiveCfg = Debug|Win32
- {58C181B3-9516-463E-2F12-122155400054}.Debug.Build.0 = Debug|Win32
- {58C181B3-9516-463E-2F12-122155400054}.Release.ActiveCfg = Release|Win32
- {58C181B3-9516-463E-2F12-122155400054}.Release.Build.0 = Release|Win32
- {5C1B8183-0296-4F83-1F22-001005220544}.Debug.ActiveCfg = Debug|Win32
- {5C1B8183-0296-4F83-1F22-001005220544}.Debug.Build.0 = Debug|Win32
- {5C1B8183-0296-4F83-1F22-001005220544}.Release.ActiveCfg = Release|Win32
- {5C1B8183-0296-4F83-1F22-001005220544}.Release.Build.0 = Release|Win32
- {58C1FE83-2906-E643-2F12-024410052254}.Debug.ActiveCfg = Debug|Win32
- {58C1FE83-2906-E643-2F12-024410052254}.Debug.Build.0 = Debug|Win32
- {58C1FE83-2906-E643-2F12-024410052254}.Release.ActiveCfg = Release|Win32
- {58C1FE83-2906-E643-2F12-024410052254}.Release.Build.0 = Release|Win32
- {58EB1CB3-1354-364E-12F2-154356612054}.Debug.ActiveCfg = Debug|Win32
- {58EB1CB3-1354-364E-12F2-154356612054}.Debug.Build.0 = Debug|Win32
- {58EB1CB3-1354-364E-12F2-154356612054}.Release.ActiveCfg = Release|Win32
- {58EB1CB3-1354-364E-12F2-154356612054}.Release.Build.0 = Release|Win32
- {58181CB3-5134-634E-12F2-155435622054}.Debug.ActiveCfg = Debug|Win32
- {58181CB3-5134-634E-12F2-155435622054}.Debug.Build.0 = Debug|Win32
- {58181CB3-5134-634E-12F2-155435622054}.Release.ActiveCfg = Release|Win32
- {58181CB3-5134-634E-12F2-155435622054}.Release.Build.0 = Release|Win32
- {5CB81183-29FB-F843-24FF-022050100544}.Debug.ActiveCfg = Debug|Win32
- {5CB81183-29FB-F843-24FF-022050100544}.Debug.Build.0 = Debug|Win32
- {5CB81183-29FB-F843-24FF-022050100544}.Release.ActiveCfg = Release|Win32
- {5CB81183-29FB-F843-24FF-022050100544}.Release.Build.0 = Release|Win32
- {58FBE8C3-9026-FAB2-E643-000522441254}.Debug.ActiveCfg = Debug|Win32
- {58FBE8C3-9026-FAB2-E643-000522441254}.Debug.Build.0 = Debug|Win32
- {58FBE8C3-9026-FAB2-E643-000522441254}.Release.ActiveCfg = Release|Win32
- {58FBE8C3-9026-FAB2-E643-000522441254}.Release.Build.0 = Release|Win32
- {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Debug.ActiveCfg = Debug|Win32
- {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Debug.Build.0 = Debug|Win32
- {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Release.ActiveCfg = Release|Win32
- {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Release.Build.0 = Release|Win32
- {5C18831B-F162-FA96-E6C3-FA5122040054}.Debug.ActiveCfg = Debug|Win32
- {5C18831B-F162-FA96-E6C3-FA5122040054}.Debug.Build.0 = Debug|Win32
- {5C18831B-F162-FA96-E6C3-FA5122040054}.Release.ActiveCfg = Release|Win32
- {5C18831B-F162-FA96-E6C3-FA5122040054}.Release.Build.0 = Release|Win32
- {5C1B1043-1EFF-2793-4E63-245241283054}.Debug.ActiveCfg = Debug|Win32
- {5C1B1043-1EFF-2793-4E63-245241283054}.Debug.Build.0 = Debug|Win32
- {5C1B1043-1EFF-2793-4E63-245241283054}.Release.ActiveCfg = Release|Win32
- {5C1B1043-1EFF-2793-4E63-245241283054}.Release.Build.0 = Release|Win32
- {51B189C3-4E63-9026-12F2-12200AF54054}.Debug.ActiveCfg = Debug|Win32
- {51B189C3-4E63-9026-12F2-12200AF54054}.Debug.Build.0 = Debug|Win32
- {51B189C3-4E63-9026-12F2-12200AF54054}.Release.ActiveCfg = Release|Win32
- {51B189C3-4E63-9026-12F2-12200AF54054}.Release.Build.0 = Release|Win32
- {5C1B1813-12C2-0296-4E63-244549126520}.Debug.ActiveCfg = Debug|Win32
- {5C1B1813-12C2-0296-4E63-244549126520}.Debug.Build.0 = Debug|Win32
- {5C1B1813-12C2-0296-4E63-244549126520}.Release.ActiveCfg = Release|Win32
- {5C1B1813-12C2-0296-4E63-244549126520}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Release.Build.0 = Release|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.Build.0 = Debug|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.ActiveCfg = Release|Win32
- {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.Build.0 = Release|Win32
- {571C3383-6092-A877-1238-B3786BAE7605}.Debug.ActiveCfg = Debug|Win32
- {571C3383-6092-A877-1238-B3786BAE7605}.Debug.Build.0 = Debug|Win32
- {571C3383-6092-A877-1238-B3786BAE7605}.Release.ActiveCfg = Release|Win32
- {571C3383-6092-A877-1238-B3786BAE7605}.Release.Build.0 = Release|Win32
- {58C1B183-0296-EA42-EF04-005120054104}.Debug.ActiveCfg = Debug|Win32
- {58C1B183-0296-EA42-EF04-005120054104}.Debug.Build.0 = Debug|Win32
- {58C1B183-0296-EA42-EF04-005120054104}.Release.ActiveCfg = Release|Win32
- {58C1B183-0296-EA42-EF04-005120054104}.Release.Build.0 = Release|Win32
- {588CCD13-2962-83FE-F4B7-92230DB73629}.Debug.ActiveCfg = Debug|Win32
- {588CCD13-2962-83FE-F4B7-92230DB73629}.Debug.Build.0 = Debug|Win32
- {588CCD13-2962-83FE-F4B7-92230DB73629}.Release.ActiveCfg = Release|Win32
- {588CCD13-2962-83FE-F4B7-92230DB73629}.Release.Build.0 = Release|Win32
- {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Debug.ActiveCfg = Debug|Win32
- {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Debug.Build.0 = Debug|Win32
- {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Release.ActiveCfg = Release|Win32
- {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Release.Build.0 = Release|Win32
- {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Debug.ActiveCfg = Debug|Win32
- {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Debug.Build.0 = Debug|Win32
- {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Release.ActiveCfg = Release|Win32
- {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Release.Build.0 = Release|Win32
- {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Debug.ActiveCfg = Debug|Win32
- {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Debug.Build.0 = Debug|Win32
- {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Release.ActiveCfg = Release|Win32
- {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Release.Build.0 = Release|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Debug.ActiveCfg = Debug|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Debug.Build.0 = Debug|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Release.ActiveCfg = Release|Win32
- {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Release.Build.0 = Release|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Debug.ActiveCfg = Debug|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Debug.Build.0 = Debug|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Release.ActiveCfg = Release|Win32
- {5CE19883-F413-7EFD-6342-B79639F7B611}.Release.Build.0 = Release|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.ActiveCfg = Debug|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.Build.0 = Debug|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.ActiveCfg = Release|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.Build.0 = Release|Win32
- {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Debug.ActiveCfg = Debug|Win32
- {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Debug.Build.0 = Debug|Win32
- {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Release.ActiveCfg = Release|Win32
- {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Release.Build.0 = Release|Win32
- {E385C28C-0691-4FA7-F48E-935BA0D06310}.Debug.ActiveCfg = Debug|Win32
- {E385C28C-0691-4FA7-F48E-935BA0D06310}.Debug.Build.0 = Debug|Win32
- {E385C28C-0691-4FA7-F48E-935BA0D06310}.Release.ActiveCfg = Release|Win32
- {E385C28C-0691-4FA7-F48E-935BA0D06310}.Release.Build.0 = Release|Win32
- {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Debug.ActiveCfg = Debug|Win32
- {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Debug.Build.0 = Debug|Win32
- {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Release.ActiveCfg = Release|Win32
- {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Release.Build.0 = Release|Win32
- {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Debug.ActiveCfg = Debug|Win32
- {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Debug.Build.0 = Debug|Win32
- {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Release.ActiveCfg = Release|Win32
- {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Release.Build.0 = Release|Win32
- {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Debug.ActiveCfg = Debug|Win32
- {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Debug.Build.0 = Debug|Win32
- {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Release.ActiveCfg = Release|Win32
- {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Release.Build.0 = Release|Win32
- {5188E3CE-2964-F43E-FB87-B037AC692D59}.Debug.ActiveCfg = Debug|Win32
- {5188E3CE-2964-F43E-FB87-B037AC692D59}.Debug.Build.0 = Debug|Win32
- {5188E3CE-2964-F43E-FB87-B037AC692D59}.Release.ActiveCfg = Release|Win32
- {5188E3CE-2964-F43E-FB87-B037AC692D59}.Release.Build.0 = Release|Win32
- {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Debug.ActiveCfg = Debug|Win32
- {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Debug.Build.0 = Debug|Win32
- {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Release.ActiveCfg = Release|Win32
- {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Release.Build.0 = Release|Win32
- {581B1C83-4E12-9526-020F-012482540054}.Debug.ActiveCfg = Debug|Win32
- {581B1C83-4E12-9526-020F-012482540054}.Debug.Build.0 = Debug|Win32
- {581B1C83-4E12-9526-020F-012482540054}.Release.ActiveCfg = Release|Win32
- {581B1C83-4E12-9526-020F-012482540054}.Release.Build.0 = Release|Win32
- {51B17C83-E172-5396-0FA2-825472008554}.Debug.ActiveCfg = Debug|Win32
- {51B17C83-E172-5396-0FA2-825472008554}.Debug.Build.0 = Debug|Win32
- {51B17C83-E172-5396-0FA2-825472008554}.Release.ActiveCfg = Release|Win32
- {51B17C83-E172-5396-0FA2-825472008554}.Release.Build.0 = Release|Win32
- {2B75C833-17D2-4956-A23F-820854254175}.Debug.ActiveCfg = Debug|Win32
- {2B75C833-17D2-4956-A23F-820854254175}.Debug.Build.0 = Debug|Win32
- {2B75C833-17D2-4956-A23F-820854254175}.Release.ActiveCfg = Release|Win32
- {2B75C833-17D2-4956-A23F-820854254175}.Release.Build.0 = Release|Win32
- {283AD375-7D12-5866-23BF-854308651275}.Debug.ActiveCfg = Debug|Win32
- {283AD375-7D12-5866-23BF-854308651275}.Debug.Build.0 = Debug|Win32
- {283AD375-7D12-5866-23BF-854308651275}.Release.ActiveCfg = Release|Win32
- {283AD375-7D12-5866-23BF-854308651275}.Release.Build.0 = Release|Win32
- {57C832B1-17D2-9537-FA12-827220448554}.Debug.ActiveCfg = Debug|Win32
- {57C832B1-17D2-9537-FA12-827220448554}.Debug.Build.0 = Debug|Win32
- {57C832B1-17D2-9537-FA12-827220448554}.Release.ActiveCfg = Release|Win32
- {57C832B1-17D2-9537-FA12-827220448554}.Release.Build.0 = Release|Win32
- {536C8251-7E12-9537-A1E2-822073258554}.Debug.ActiveCfg = Debug|Win32
- {536C8251-7E12-9537-A1E2-822073258554}.Debug.Build.0 = Debug|Win32
- {536C8251-7E12-9537-A1E2-822073258554}.Release.ActiveCfg = Release|Win32
- {536C8251-7E12-9537-A1E2-822073258554}.Release.Build.0 = Release|Win32
- {83258CB1-127E-9375-F872-8324A1054454}.Debug.ActiveCfg = Debug|Win32
- {83258CB1-127E-9375-F872-8324A1054454}.Debug.Build.0 = Debug|Win32
- {83258CB1-127E-9375-F872-8324A1054454}.Release.ActiveCfg = Release|Win32
- {83258CB1-127E-9375-F872-8324A1054454}.Release.Build.0 = Release|Win32
- {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Debug.ActiveCfg = Debug|Win32
- {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Debug.Build.0 = Debug|Win32
- {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Release.ActiveCfg = Release|Win32
- {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Release.Build.0 = Release|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.ActiveCfg = Debug|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.Build.0 = Debug|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.ActiveCfg = Release|Win32
- {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.Build.0 = Release|Win32
- {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Debug.ActiveCfg = Debug|Win32
- {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Debug.Build.0 = Debug|Win32
- {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Release.ActiveCfg = Release|Win32
- {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Release.Build.0 = Release|Win32
- {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Debug.ActiveCfg = Debug|Win32
- {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Debug.Build.0 = Debug|Win32
- {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Release.ActiveCfg = Release|Win32
- {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Release.Build.0 = Release|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Debug.ActiveCfg = Debug|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Debug.Build.0 = Debug|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Release.ActiveCfg = Release|Win32
- {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Release.Build.0 = Release|Win32
- {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
- {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
- {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
- {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
- {8A519DC3-6092-A4FE-F748-BA91328D6522}.Debug.ActiveCfg = Debug|Win32
- {8A519DC3-6092-A4FE-F748-BA91328D6522}.Debug.Build.0 = Debug|Win32
- {8A519DC3-6092-A4FE-F748-BA91328D6522}.Release.ActiveCfg = Release|Win32
- {8A519DC3-6092-A4FE-F748-BA91328D6522}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Release.Build.0 = Release|Win32
- {58C183CE-6203-FE12-A237-BA8976695960}.Debug.ActiveCfg = Debug|Win32
- {58C183CE-6203-FE12-A237-BA8976695960}.Debug.Build.0 = Debug|Win32
- {58C183CE-6203-FE12-A237-BA8976695960}.Release.ActiveCfg = Release|Win32
- {58C183CE-6203-FE12-A237-BA8976695960}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Release.Build.0 = Release|Win32
- {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Debug.ActiveCfg = Debug|Win32
- {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Debug.Build.0 = Debug|Win32
- {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Release.ActiveCfg = Release|Win32
- {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Release.Build.0 = Release|Win32
- {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Debug.ActiveCfg = Debug|Win32
- {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Debug.Build.0 = Debug|Win32
- {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Release.ActiveCfg = Release|Win32
- {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Release.Build.0 = Release|Win32
- {58C1B183-9026-4E12-00F2-001200540054}.Debug.ActiveCfg = Debug|Win32
- {58C1B183-9026-4E12-00F2-001200540054}.Debug.Build.0 = Debug|Win32
- {58C1B183-9026-4E12-00F2-001200540054}.Release.ActiveCfg = Release|Win32
- {58C1B183-9026-4E12-00F2-001200540054}.Release.Build.0 = Release|Win32
- {5E18CC83-6092-48FE-A677-B832A0D3A650}.Debug.ActiveCfg = Debug|Win32
- {5E18CC83-6092-48FE-A677-B832A0D3A650}.Debug.Build.0 = Debug|Win32
- {5E18CC83-6092-48FE-A677-B832A0D3A650}.Release.ActiveCfg = Release|Win32
- {5E18CC83-6092-48FE-A677-B832A0D3A650}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Release.Build.0 = Release|Win32
- {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Debug.Build.0 = Debug|Win32
- {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Release.ActiveCfg = Release|Win32
- {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Release.Build.0 = Release|Win32
- {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Debug.ActiveCfg = Debug|Win32
- {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Debug.Build.0 = Debug|Win32
- {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Release.ActiveCfg = Release|Win32
- {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Release.Build.0 = Release|Win32
- {58C1B183-9260-4E8F-F200-000000000041}.Debug.ActiveCfg = Debug|Win32
- {58C1B183-9260-4E8F-F200-000000000041}.Debug.Build.0 = Debug|Win32
- {58C1B183-9260-4E8F-F200-000000000041}.Release.ActiveCfg = Release|Win32
- {58C1B183-9260-4E8F-F200-000000000041}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A677-BA0D3A832640}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A677-BA0D3A832640}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A677-BA0D3A832640}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A677-BA0D3A832640}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.Build.0 = Release|Win32
- {5821C383-6092-12FE-A877-BA0D33467633}.Debug.ActiveCfg = Debug|Win32
- {5821C383-6092-12FE-A877-BA0D33467633}.Debug.Build.0 = Debug|Win32
- {5821C383-6092-12FE-A877-BA0D33467633}.Release.ActiveCfg = Release|Win32
- {5821C383-6092-12FE-A877-BA0D33467633}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
- {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Debug.ActiveCfg = Debug|Win32
- {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Debug.Build.0 = Debug|Win32
- {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Release.ActiveCfg = Release|Win32
- {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Release.Build.0 = Release|Win32
- {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Debug.ActiveCfg = Debug|Win32
- {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Debug.Build.0 = Debug|Win32
- {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Release.ActiveCfg = Release|Win32
- {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Release.Build.0 = Release|Win32
- {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Debug.ActiveCfg = Debug|Win32
- {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Debug.Build.0 = Debug|Win32
- {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Release.ActiveCfg = Release|Win32
- {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Release.Build.0 = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Debug.ActiveCfg = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Debug.Build.0 = Debug|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Release.ActiveCfg = Release|Win32
- {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Release.Build.0 = Release|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A27}.Debug.ActiveCfg = Debug|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A27}.Debug.Build.0 = Debug|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A27}.Release.ActiveCfg = Release|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A27}.Release.Build.0 = Release|Win32
- {0000058C-0000-0000-0000-000000000021}.Debug.ActiveCfg = Debug|Win32
- {0000058C-0000-0000-0000-000000000021}.Debug.Build.0 = Debug|Win32
- {0000058C-0000-0000-0000-000000000021}.Release.ActiveCfg = Release|Win32
- {0000058C-0000-0000-0000-000000000021}.Release.Build.0 = Release|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.ActiveCfg = Debug|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.Build.0 = Debug|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.ActiveCfg = Release|Win32
- {83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.Build.0 = Release|Win32
- {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.ActiveCfg = Debug|Win32
- {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.Build.0 = Debug|Win32
- {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.ActiveCfg = Release|Win32
- {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.Build.0 = Release|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.ActiveCfg = Debug|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.Build.0 = Debug|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.ActiveCfg = Release|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.Build.0 = Release|Win32
- {5189DEA3-3261-F33E-47ED-83BC69F66061}.Debug.ActiveCfg = Debug|Win32
- {5189DEA3-3261-F33E-47ED-83BC69F66061}.Debug.Build.0 = Debug|Win32
- {5189DEA3-3261-F33E-47ED-83BC69F66061}.Release.ActiveCfg = Release|Win32
- {5189DEA3-3261-F33E-47ED-83BC69F66061}.Release.Build.0 = Release|Win32
- {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Debug.ActiveCfg = Debug|Win32
- {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Debug.Build.0 = Debug|Win32
- {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Release.ActiveCfg = Release|Win32
- {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Release.Build.0 = Release|Win32
- {4E887AC3-F8EA-6923-A744-C264A398C913}.Debug.ActiveCfg = Debug|Win32
- {4E887AC3-F8EA-6923-A744-C264A398C913}.Debug.Build.0 = Debug|Win32
- {4E887AC3-F8EA-6923-A744-C264A398C913}.Release.ActiveCfg = Release|Win32
- {4E887AC3-F8EA-6923-A744-C264A398C913}.Release.Build.0 = Release|Win32
- {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Debug.ActiveCfg = Debug|Win32
- {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Debug.Build.0 = Debug|Win32
- {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Release.ActiveCfg = Release|Win32
- {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Release.Build.0 = Release|Win32
- {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Debug.ActiveCfg = Debug|Win32
- {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Debug.Build.0 = Debug|Win32
- {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Release.ActiveCfg = Release|Win32
- {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Release.Build.0 = Release|Win32
- {58DF28E3-0926-F47A-E28A-B03A4D619631}.Debug.ActiveCfg = Debug|Win32
- {58DF28E3-0926-F47A-E28A-B03A4D619631}.Debug.Build.0 = Debug|Win32
- {58DF28E3-0926-F47A-E28A-B03A4D619631}.Release.ActiveCfg = Release|Win32
- {58DF28E3-0926-F47A-E28A-B03A4D619631}.Release.Build.0 = Release|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.ActiveCfg = Debug|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.Build.0 = Debug|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.ActiveCfg = Release|Win32
- {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.Build.0 = Release|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
- {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_memory_mapping_test", "shared_memory_mappable_test.vcproj", "{5CE18C83-6025-36FE-A4F7-BA09176D3A11}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_memory_test", "shared_memory_test.vcproj", "{5E2838CC-0916-8F4E-A4F7-93506BA0D310}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_ptr_test", "shared_ptr_test.vcproj", "{5371C383-6092-1238-A877-BAEB37867609}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist_test", "slist_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_test", "string_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D4A792607}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tree_test", "tree_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upgradable_mutex_test", "upgradable_mutex.vcproj", "{4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "user_buffer_test", "user_buffer_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792603}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vectorstream_test", "vectorstream_test.vcproj", "{58CCE183-6032-12FE-A4F7-BA893A767601}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_test", "vector_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_condition_test", "named_condition_test.vcproj", "{58CC2563-6092-48FE-FAF7-BA046A792658}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_mutexA", "doc_anonymous_mutexA.vcproj", "{58C1B183-9026-4E63-12F2-005412200054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_mutexB", "doc_anonymous_mutexB.vcproj", "{58C1B183-9026-4E63-12F2-005202441254}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_mutex", "doc_named_mutex.vcproj", "{58C181B3-9516-463E-2F12-122155400054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_conditionA", "doc_anonymous_conditionA.vcproj", "{5C1B8183-0296-4F83-1F22-001005220544}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_conditionB", "doc_anonymous_conditionB.vcproj", "{58C1FE83-2906-E643-2F12-024410052254}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_conditionA", "doc_named_conditionA.vcproj", "{58EB1CB3-1354-364E-12F2-154356612054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_conditionB", "doc_named_conditionB.vcproj", "{58181CB3-5134-634E-12F2-155435622054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_semaphoreA", "doc_anonymous_semaphoreA.vcproj", "{5CB81183-29FB-F843-24FF-022050100544}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_semaphoreB", "doc_anonymous_semaphoreB.vcproj", "{58FBE8C3-9026-FAB2-E643-000522441254}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_upgradable_mutex_test", "named_upgradable_mutex.vcproj", "{48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_upgradable_mutexA", "doc_anonymous_upgradable_mutexA.vcproj", "{5C18831B-F162-FA96-E6C3-FA5122040054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_upgradable_mutexB", "doc_anonymous_upgradable_mutexB.vcproj", "{5C1B1043-1EFF-2793-4E63-245241283054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_message_queueA", "doc_message_queueA.vcproj", "{51B189C3-4E63-9026-12F2-12200AF54054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_message_queueB", "doc_message_queueB.vcproj", "{5C1B1813-12C2-0296-4E63-244549126520}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_cont", "doc_cont.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792653}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_contA", "doc_contA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792652}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_contB", "doc_contB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792651}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory", "doc_shared_memory.vcproj", "{58CCE183-6032-12FE-4FC7-83A79F760B61}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_test", "unique_ptr_test.vcproj", "{571C3383-6092-A877-1238-B3786BAE7605}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_containers", "doc_move_containers.vcproj", "{58C1B183-0296-EA42-EF04-005120054104}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map_index_allocation_test", "map_index_allocation_test.vcproj", "{588CCD13-2962-83FE-F4B7-92230DB73629}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_map_index_allocation_test", "flat_map_index_allocation_test.vcproj", "{51D8E9C3-2D65-48FE-3AA7-7922C0E36329}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iset_index_allocation_test", "iset_index_allocation_test.vcproj", "{58BD1CC3-6972-F3F7-84BE-0DB736035922}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iunordered_set_index_allocation_test", "iunordered_set_index_allocation_test.vcproj", "{5BD1C7C3-3F7F-6972-84BE-B731D9236035}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_memory2", "doc_shared_memory2.vcproj", "{58CE1D83-F31E-4FD7-6132-8A79F6307B61}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_mapping2", "doc_file_mapping2.vcproj", "{5CE19883-F413-7EFD-6342-B79639F7B611}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_mapping", "doc_file_mapping.vcproj", "{58DE18C3-3261-2F3E-FD47-83760B9FA761}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_map", "doc_map.vcproj", "{59CEC183-8192-8F6D-4FB7-BA260A79D352}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows_shared_memory_test", "windows_shared_memory_test.vcproj", "{E385C28C-0691-4FA7-F48E-935BA0D06310}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windows_shared_memory_mapping_test", "windows_shared_memory_mapping_test.vcproj", "{518CE8C3-6512-FA75-46EF-B917A3A116D1}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "managed_windows_shared_memory_test", "managed_windows_shared_memory.vcproj", "{5D18CE83-1926-7AE4-FE94-B606D9B23131}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_pool_test", "adaptive_pool_test.vcproj", "{58CE1D84-1962-4FE9-BA0D-A4F7973A4652}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cached_adaptive_pool_test", "cached_adaptive_pool_test.vcproj", "{5188E3CE-2964-F43E-FB87-B037AC692D59}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "private_adaptive_pool_test", "private_adaptive_pool_test.vcproj", "{5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_allocator", "doc_allocator.vcproj", "{581B1C83-4E12-9526-020F-012482540054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_node_allocator", "doc_node_allocator.vcproj", "{51B17C83-E172-5396-0FA2-825472008554}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_private_node_allocator", "doc_private_node_allocator.vcproj", "{2B75C833-17D2-4956-A23F-820854254175}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_cached_node_allocator", "doc_cached_node_allocator.vcproj", "{283AD375-7D12-5866-23BF-854308651275}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_adaptive_pool", "doc_adaptive_pool.vcproj", "{57C832B1-17D2-9537-FA12-827220448554}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_cached_adaptive_pool", "doc_cached_adaptive_pool.vcproj", "{536C8251-7E12-9537-A1E2-822073258554}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_private_adaptive_pool", "doc_private_adaptive_pool.vcproj", "{83258CB1-127E-9375-F872-8324A1054454}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_raw_allocation", "doc_managed_raw_allocation.vcproj", "{5198EFC3-2731-F34E-4FD8-1859AC94F761}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_aligned_allocation", "doc_managed_aligned_allocation.vcproj", "{58DE18C3-3261-2F3E-FD47-83760B9FA761}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_interprocesslib", "interprocesslib.vcproj", "{FFAA56F1-32EC-4B22-B6BD-95A311A67C35}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_windows_shared_memory", "doc_windows_shared_memory.vcproj", "{5E17C9C3-1362-2E1E-C84F-8A76B6739F21}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_windows_shared_memory2", "doc_windows_shared_memory2.vcproj", "{5E1D6C83-31DE-4F6F-6132-87A9FB663041}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_node_pool_test", "adaptive_node_pool_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "node_pool_test", "node_pool_test.vcproj", "{8A519DC3-6092-A4FE-F748-BA91328D6522}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deque_test", "deque_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792655}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "barrier_test", "barrier_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792661}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bufferstream_test", "bufferstream_test.vcproj", "{58C183CE-6203-FE12-A237-BA8976695960}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cached_node_allocator_test", "cached_node_allocator_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792659}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "private_node_allocator_test", "private_node_allocator_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792620}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "node_allocator_test", "node_allocator_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792622}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_mutex_test", "named_mutex_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792625}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_recursive_mutex_test", "named_recursive_mutex_test.vcproj", "{5C83CE18-4F48-A7FE-6092-B7920AD3A624}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "named_semaphore_test", "named_semaphore_test.vcproj", "{58CCE283-1609-48FE-A4F7-BA0D3A793523}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_heap_memory", "doc_managed_heap_memory.vcproj", "{58CCE183-6092-48FE-A4FC-BA0D3A792647}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocexcept_test", "allocexcept_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792662}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "condition_test", "condition_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792658}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "data_test", "data_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792657}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_bufferstream", "doc_bufferstream.vcproj", "{58C1B183-9026-4E12-00F2-001200540054}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_intrusive", "doc_intrusive.vcproj", "{5E18CC83-6092-48FE-A677-B832A0D3A650}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_messageA", "doc_ipc_messageA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792649}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_ipc_messageB", "doc_ipc_messageB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792648}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_mapped_file", "doc_managed_mapped_file.vcproj", "{58CCE183-5091-48FE-A4FC-BA0D3A792446}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_allocA", "doc_named_allocA.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792645}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_named_allocB", "doc_named_allocB.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792644}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_offset_ptr", "doc_offset_ptr.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792643}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_scoped_ptr", "doc_scoped_ptr.vcproj", "{58CC8E13-0962-8F4E-77A6-BD3A6832A042}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_vectorstream", "doc_vectorstream.vcproj", "{58C1B183-9260-4E8F-F200-000000000041}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_where_allocate", "doc_where_allocate.vcproj", "{58CCE183-6092-48FE-A677-BA0D3A832640}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file_mapping_test", "file_mapping_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792638}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792637}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intrusive_ptr_test", "intrusive_ptr_test.vcproj", "{5821C383-6092-12FE-A877-BA0D33467633}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792632}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "managed_mapped_file_test", "managed_mapped_file_test.vcproj", "{5CCE1883-0926-F7A4-8FE4-BA0606D92331}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mapped_file_test", "mapped_file_test.vcproj", "{5C6D9CE1-2609-F7A4-8FE4-BA0883602330}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memory_algorithm_test", "memory_algorithm_test.vcproj", "{58E18CC3-6092-8F4E-A3E7-A792230D3629}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "message_queue_test", "message_queue.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792628}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutex_test", "mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A27}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "null_index_test", "null_index_test.vcproj", "{0000058C-0000-0000-0000-000000000021}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "recursive_mutex_test", "recursive_mutex_test.vcproj", "{83581CCE-487E-3292-A4E7-BA07926D3A14}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "semaphore_test", "semaphore_test.vcproj", "{5CE28C83-48FE-1676-4FA7-B50D3A76A013}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_multiple_allocation", "doc_managed_multiple_allocation.vcproj", "{818C43EE-3561-F3AE-4FD7-8A2076E76A31}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_allocation_command", "doc_managed_allocation_command.vcproj", "{5189DEA3-3261-F33E-47ED-83BC69F66061}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_construction_info", "doc_managed_construction_info.vcproj", "{5C82D1D3-3861-3AF1-03EF-89AED4716761}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_ptr_explicit", "doc_shared_ptr_explicit.vcproj", "{4E887AC3-F8EA-6923-A744-C264A398C913}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_unique_ptr", "doc_unique_ptr.vcproj", "{589C2EB3-8A57-1862-F4EA-A6B14C7329A3}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_shared_ptr", "doc_shared_ptr.vcproj", "{51CE89A3-6092-F4EA-48A7-B4B9AC326093}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "managed_shared_memory_test", "managed_shared_memory.vcproj", "{58DF28E3-0926-F47A-E28A-B03A4D619631}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_grow", "doc_managed_grow.vcproj", "{818C43EE-3561-F3AE-4FD7-8A2076E76A31}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "offset_ptr_test", "offset_ptr_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.ActiveCfg = Debug|Win32
+ {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Debug.Build.0 = Debug|Win32
+ {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Release.ActiveCfg = Release|Win32
+ {5CE18C83-6025-36FE-A4F7-BA09176D3A11}.Release.Build.0 = Release|Win32
+ {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Debug.ActiveCfg = Debug|Win32
+ {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Debug.Build.0 = Debug|Win32
+ {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Release.ActiveCfg = Release|Win32
+ {5E2838CC-0916-8F4E-A4F7-93506BA0D310}.Release.Build.0 = Release|Win32
+ {5371C383-6092-1238-A877-BAEB37867609}.Debug.ActiveCfg = Debug|Win32
+ {5371C383-6092-1238-A877-BAEB37867609}.Debug.Build.0 = Debug|Win32
+ {5371C383-6092-1238-A877-BAEB37867609}.Release.ActiveCfg = Release|Win32
+ {5371C383-6092-1238-A877-BAEB37867609}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
+ {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Debug.ActiveCfg = Debug|Win32
+ {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Debug.Build.0 = Debug|Win32
+ {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Release.ActiveCfg = Release|Win32
+ {4E88C1C2-0961-F7A4-F48E-A6A7D3B06004}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792603}.Release.Build.0 = Release|Win32
+ {58CCE183-6032-12FE-A4F7-BA893A767601}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6032-12FE-A4F7-BA893A767601}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6032-12FE-A4F7-BA893A767601}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6032-12FE-A4F7-BA893A767601}.Release.Build.0 = Release|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
+ {58CC2563-6092-48FE-FAF7-BA046A792658}.Debug.ActiveCfg = Debug|Win32
+ {58CC2563-6092-48FE-FAF7-BA046A792658}.Debug.Build.0 = Debug|Win32
+ {58CC2563-6092-48FE-FAF7-BA046A792658}.Release.ActiveCfg = Release|Win32
+ {58CC2563-6092-48FE-FAF7-BA046A792658}.Release.Build.0 = Release|Win32
+ {58C1B183-9026-4E63-12F2-005412200054}.Debug.ActiveCfg = Debug|Win32
+ {58C1B183-9026-4E63-12F2-005412200054}.Debug.Build.0 = Debug|Win32
+ {58C1B183-9026-4E63-12F2-005412200054}.Release.ActiveCfg = Release|Win32
+ {58C1B183-9026-4E63-12F2-005412200054}.Release.Build.0 = Release|Win32
+ {58C1B183-9026-4E63-12F2-005202441254}.Debug.ActiveCfg = Debug|Win32
+ {58C1B183-9026-4E63-12F2-005202441254}.Debug.Build.0 = Debug|Win32
+ {58C1B183-9026-4E63-12F2-005202441254}.Release.ActiveCfg = Release|Win32
+ {58C1B183-9026-4E63-12F2-005202441254}.Release.Build.0 = Release|Win32
+ {58C181B3-9516-463E-2F12-122155400054}.Debug.ActiveCfg = Debug|Win32
+ {58C181B3-9516-463E-2F12-122155400054}.Debug.Build.0 = Debug|Win32
+ {58C181B3-9516-463E-2F12-122155400054}.Release.ActiveCfg = Release|Win32
+ {58C181B3-9516-463E-2F12-122155400054}.Release.Build.0 = Release|Win32
+ {5C1B8183-0296-4F83-1F22-001005220544}.Debug.ActiveCfg = Debug|Win32
+ {5C1B8183-0296-4F83-1F22-001005220544}.Debug.Build.0 = Debug|Win32
+ {5C1B8183-0296-4F83-1F22-001005220544}.Release.ActiveCfg = Release|Win32
+ {5C1B8183-0296-4F83-1F22-001005220544}.Release.Build.0 = Release|Win32
+ {58C1FE83-2906-E643-2F12-024410052254}.Debug.ActiveCfg = Debug|Win32
+ {58C1FE83-2906-E643-2F12-024410052254}.Debug.Build.0 = Debug|Win32
+ {58C1FE83-2906-E643-2F12-024410052254}.Release.ActiveCfg = Release|Win32
+ {58C1FE83-2906-E643-2F12-024410052254}.Release.Build.0 = Release|Win32
+ {58EB1CB3-1354-364E-12F2-154356612054}.Debug.ActiveCfg = Debug|Win32
+ {58EB1CB3-1354-364E-12F2-154356612054}.Debug.Build.0 = Debug|Win32
+ {58EB1CB3-1354-364E-12F2-154356612054}.Release.ActiveCfg = Release|Win32
+ {58EB1CB3-1354-364E-12F2-154356612054}.Release.Build.0 = Release|Win32
+ {58181CB3-5134-634E-12F2-155435622054}.Debug.ActiveCfg = Debug|Win32
+ {58181CB3-5134-634E-12F2-155435622054}.Debug.Build.0 = Debug|Win32
+ {58181CB3-5134-634E-12F2-155435622054}.Release.ActiveCfg = Release|Win32
+ {58181CB3-5134-634E-12F2-155435622054}.Release.Build.0 = Release|Win32
+ {5CB81183-29FB-F843-24FF-022050100544}.Debug.ActiveCfg = Debug|Win32
+ {5CB81183-29FB-F843-24FF-022050100544}.Debug.Build.0 = Debug|Win32
+ {5CB81183-29FB-F843-24FF-022050100544}.Release.ActiveCfg = Release|Win32
+ {5CB81183-29FB-F843-24FF-022050100544}.Release.Build.0 = Release|Win32
+ {58FBE8C3-9026-FAB2-E643-000522441254}.Debug.ActiveCfg = Debug|Win32
+ {58FBE8C3-9026-FAB2-E643-000522441254}.Debug.Build.0 = Debug|Win32
+ {58FBE8C3-9026-FAB2-E643-000522441254}.Release.ActiveCfg = Release|Win32
+ {58FBE8C3-9026-FAB2-E643-000522441254}.Release.Build.0 = Release|Win32
+ {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Debug.ActiveCfg = Debug|Win32
+ {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Debug.Build.0 = Debug|Win32
+ {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Release.ActiveCfg = Release|Win32
+ {48C1FBE8-F7A4-0961-48FE-7D93A63B0A04}.Release.Build.0 = Release|Win32
+ {5C18831B-F162-FA96-E6C3-FA5122040054}.Debug.ActiveCfg = Debug|Win32
+ {5C18831B-F162-FA96-E6C3-FA5122040054}.Debug.Build.0 = Debug|Win32
+ {5C18831B-F162-FA96-E6C3-FA5122040054}.Release.ActiveCfg = Release|Win32
+ {5C18831B-F162-FA96-E6C3-FA5122040054}.Release.Build.0 = Release|Win32
+ {5C1B1043-1EFF-2793-4E63-245241283054}.Debug.ActiveCfg = Debug|Win32
+ {5C1B1043-1EFF-2793-4E63-245241283054}.Debug.Build.0 = Debug|Win32
+ {5C1B1043-1EFF-2793-4E63-245241283054}.Release.ActiveCfg = Release|Win32
+ {5C1B1043-1EFF-2793-4E63-245241283054}.Release.Build.0 = Release|Win32
+ {51B189C3-4E63-9026-12F2-12200AF54054}.Debug.ActiveCfg = Debug|Win32
+ {51B189C3-4E63-9026-12F2-12200AF54054}.Debug.Build.0 = Debug|Win32
+ {51B189C3-4E63-9026-12F2-12200AF54054}.Release.ActiveCfg = Release|Win32
+ {51B189C3-4E63-9026-12F2-12200AF54054}.Release.Build.0 = Release|Win32
+ {5C1B1813-12C2-0296-4E63-244549126520}.Debug.ActiveCfg = Debug|Win32
+ {5C1B1813-12C2-0296-4E63-244549126520}.Debug.Build.0 = Debug|Win32
+ {5C1B1813-12C2-0296-4E63-244549126520}.Release.ActiveCfg = Release|Win32
+ {5C1B1813-12C2-0296-4E63-244549126520}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792653}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792652}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792651}.Release.Build.0 = Release|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6032-12FE-4FC7-83A79F760B61}.Release.Build.0 = Release|Win32
+ {571C3383-6092-A877-1238-B3786BAE7605}.Debug.ActiveCfg = Debug|Win32
+ {571C3383-6092-A877-1238-B3786BAE7605}.Debug.Build.0 = Debug|Win32
+ {571C3383-6092-A877-1238-B3786BAE7605}.Release.ActiveCfg = Release|Win32
+ {571C3383-6092-A877-1238-B3786BAE7605}.Release.Build.0 = Release|Win32
+ {58C1B183-0296-EA42-EF04-005120054104}.Debug.ActiveCfg = Debug|Win32
+ {58C1B183-0296-EA42-EF04-005120054104}.Debug.Build.0 = Debug|Win32
+ {58C1B183-0296-EA42-EF04-005120054104}.Release.ActiveCfg = Release|Win32
+ {58C1B183-0296-EA42-EF04-005120054104}.Release.Build.0 = Release|Win32
+ {588CCD13-2962-83FE-F4B7-92230DB73629}.Debug.ActiveCfg = Debug|Win32
+ {588CCD13-2962-83FE-F4B7-92230DB73629}.Debug.Build.0 = Debug|Win32
+ {588CCD13-2962-83FE-F4B7-92230DB73629}.Release.ActiveCfg = Release|Win32
+ {588CCD13-2962-83FE-F4B7-92230DB73629}.Release.Build.0 = Release|Win32
+ {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Debug.ActiveCfg = Debug|Win32
+ {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Debug.Build.0 = Debug|Win32
+ {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Release.ActiveCfg = Release|Win32
+ {51D8E9C3-2D65-48FE-3AA7-7922C0E36329}.Release.Build.0 = Release|Win32
+ {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Debug.ActiveCfg = Debug|Win32
+ {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Debug.Build.0 = Debug|Win32
+ {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Release.ActiveCfg = Release|Win32
+ {58BD1CC3-6972-F3F7-84BE-0DB736035922}.Release.Build.0 = Release|Win32
+ {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Debug.ActiveCfg = Debug|Win32
+ {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Debug.Build.0 = Debug|Win32
+ {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Release.ActiveCfg = Release|Win32
+ {5BD1C7C3-3F7F-6972-84BE-B731D9236035}.Release.Build.0 = Release|Win32
+ {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Debug.ActiveCfg = Debug|Win32
+ {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Debug.Build.0 = Debug|Win32
+ {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Release.ActiveCfg = Release|Win32
+ {58CE1D83-F31E-4FD7-6132-8A79F6307B61}.Release.Build.0 = Release|Win32
+ {5CE19883-F413-7EFD-6342-B79639F7B611}.Debug.ActiveCfg = Debug|Win32
+ {5CE19883-F413-7EFD-6342-B79639F7B611}.Debug.Build.0 = Debug|Win32
+ {5CE19883-F413-7EFD-6342-B79639F7B611}.Release.ActiveCfg = Release|Win32
+ {5CE19883-F413-7EFD-6342-B79639F7B611}.Release.Build.0 = Release|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.ActiveCfg = Debug|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.Build.0 = Debug|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.ActiveCfg = Release|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.Build.0 = Release|Win32
+ {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Debug.ActiveCfg = Debug|Win32
+ {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Debug.Build.0 = Debug|Win32
+ {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Release.ActiveCfg = Release|Win32
+ {59CEC183-8192-8F6D-4FB7-BA260A79D352}.Release.Build.0 = Release|Win32
+ {E385C28C-0691-4FA7-F48E-935BA0D06310}.Debug.ActiveCfg = Debug|Win32
+ {E385C28C-0691-4FA7-F48E-935BA0D06310}.Debug.Build.0 = Debug|Win32
+ {E385C28C-0691-4FA7-F48E-935BA0D06310}.Release.ActiveCfg = Release|Win32
+ {E385C28C-0691-4FA7-F48E-935BA0D06310}.Release.Build.0 = Release|Win32
+ {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Debug.ActiveCfg = Debug|Win32
+ {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Debug.Build.0 = Debug|Win32
+ {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Release.ActiveCfg = Release|Win32
+ {518CE8C3-6512-FA75-46EF-B917A3A116D1}.Release.Build.0 = Release|Win32
+ {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Debug.ActiveCfg = Debug|Win32
+ {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Debug.Build.0 = Debug|Win32
+ {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Release.ActiveCfg = Release|Win32
+ {5D18CE83-1926-7AE4-FE94-B606D9B23131}.Release.Build.0 = Release|Win32
+ {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Debug.ActiveCfg = Debug|Win32
+ {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Debug.Build.0 = Debug|Win32
+ {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Release.ActiveCfg = Release|Win32
+ {58CE1D84-1962-4FE9-BA0D-A4F7973A4652}.Release.Build.0 = Release|Win32
+ {5188E3CE-2964-F43E-FB87-B037AC692D59}.Debug.ActiveCfg = Debug|Win32
+ {5188E3CE-2964-F43E-FB87-B037AC692D59}.Debug.Build.0 = Debug|Win32
+ {5188E3CE-2964-F43E-FB87-B037AC692D59}.Release.ActiveCfg = Release|Win32
+ {5188E3CE-2964-F43E-FB87-B037AC692D59}.Release.Build.0 = Release|Win32
+ {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Debug.ActiveCfg = Debug|Win32
+ {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Debug.Build.0 = Debug|Win32
+ {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Release.ActiveCfg = Release|Win32
+ {5CE14C83-4962-8F5E-4FA7-B0D3A7B93635}.Release.Build.0 = Release|Win32
+ {581B1C83-4E12-9526-020F-012482540054}.Debug.ActiveCfg = Debug|Win32
+ {581B1C83-4E12-9526-020F-012482540054}.Debug.Build.0 = Debug|Win32
+ {581B1C83-4E12-9526-020F-012482540054}.Release.ActiveCfg = Release|Win32
+ {581B1C83-4E12-9526-020F-012482540054}.Release.Build.0 = Release|Win32
+ {51B17C83-E172-5396-0FA2-825472008554}.Debug.ActiveCfg = Debug|Win32
+ {51B17C83-E172-5396-0FA2-825472008554}.Debug.Build.0 = Debug|Win32
+ {51B17C83-E172-5396-0FA2-825472008554}.Release.ActiveCfg = Release|Win32
+ {51B17C83-E172-5396-0FA2-825472008554}.Release.Build.0 = Release|Win32
+ {2B75C833-17D2-4956-A23F-820854254175}.Debug.ActiveCfg = Debug|Win32
+ {2B75C833-17D2-4956-A23F-820854254175}.Debug.Build.0 = Debug|Win32
+ {2B75C833-17D2-4956-A23F-820854254175}.Release.ActiveCfg = Release|Win32
+ {2B75C833-17D2-4956-A23F-820854254175}.Release.Build.0 = Release|Win32
+ {283AD375-7D12-5866-23BF-854308651275}.Debug.ActiveCfg = Debug|Win32
+ {283AD375-7D12-5866-23BF-854308651275}.Debug.Build.0 = Debug|Win32
+ {283AD375-7D12-5866-23BF-854308651275}.Release.ActiveCfg = Release|Win32
+ {283AD375-7D12-5866-23BF-854308651275}.Release.Build.0 = Release|Win32
+ {57C832B1-17D2-9537-FA12-827220448554}.Debug.ActiveCfg = Debug|Win32
+ {57C832B1-17D2-9537-FA12-827220448554}.Debug.Build.0 = Debug|Win32
+ {57C832B1-17D2-9537-FA12-827220448554}.Release.ActiveCfg = Release|Win32
+ {57C832B1-17D2-9537-FA12-827220448554}.Release.Build.0 = Release|Win32
+ {536C8251-7E12-9537-A1E2-822073258554}.Debug.ActiveCfg = Debug|Win32
+ {536C8251-7E12-9537-A1E2-822073258554}.Debug.Build.0 = Debug|Win32
+ {536C8251-7E12-9537-A1E2-822073258554}.Release.ActiveCfg = Release|Win32
+ {536C8251-7E12-9537-A1E2-822073258554}.Release.Build.0 = Release|Win32
+ {83258CB1-127E-9375-F872-8324A1054454}.Debug.ActiveCfg = Debug|Win32
+ {83258CB1-127E-9375-F872-8324A1054454}.Debug.Build.0 = Debug|Win32
+ {83258CB1-127E-9375-F872-8324A1054454}.Release.ActiveCfg = Release|Win32
+ {83258CB1-127E-9375-F872-8324A1054454}.Release.Build.0 = Release|Win32
+ {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Debug.ActiveCfg = Debug|Win32
+ {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Debug.Build.0 = Debug|Win32
+ {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Release.ActiveCfg = Release|Win32
+ {5198EFC3-2731-F34E-4FD8-1859AC94F761}.Release.Build.0 = Release|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.ActiveCfg = Debug|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Debug.Build.0 = Debug|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.ActiveCfg = Release|Win32
+ {58DE18C3-3261-2F3E-FD47-83760B9FA761}.Release.Build.0 = Release|Win32
+ {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Debug.ActiveCfg = Debug|Win32
+ {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Debug.Build.0 = Debug|Win32
+ {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Release.ActiveCfg = Release|Win32
+ {FFAA56F1-32EC-4B22-B6BD-95A311A67C35}.Release.Build.0 = Release|Win32
+ {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Debug.ActiveCfg = Debug|Win32
+ {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Debug.Build.0 = Debug|Win32
+ {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Release.ActiveCfg = Release|Win32
+ {5E17C9C3-1362-2E1E-C84F-8A76B6739F21}.Release.Build.0 = Release|Win32
+ {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Debug.ActiveCfg = Debug|Win32
+ {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Debug.Build.0 = Debug|Win32
+ {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Release.ActiveCfg = Release|Win32
+ {5E1D6C83-31DE-4F6F-6132-87A9FB663041}.Release.Build.0 = Release|Win32
+ {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+ {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+ {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+ {CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+ {8A519DC3-6092-A4FE-F748-BA91328D6522}.Debug.ActiveCfg = Debug|Win32
+ {8A519DC3-6092-A4FE-F748-BA91328D6522}.Debug.Build.0 = Debug|Win32
+ {8A519DC3-6092-A4FE-F748-BA91328D6522}.Release.ActiveCfg = Release|Win32
+ {8A519DC3-6092-A4FE-F748-BA91328D6522}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792661}.Release.Build.0 = Release|Win32
+ {58C183CE-6203-FE12-A237-BA8976695960}.Debug.ActiveCfg = Debug|Win32
+ {58C183CE-6203-FE12-A237-BA8976695960}.Debug.Build.0 = Debug|Win32
+ {58C183CE-6203-FE12-A237-BA8976695960}.Release.ActiveCfg = Release|Win32
+ {58C183CE-6203-FE12-A237-BA8976695960}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792659}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792620}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792622}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792625}.Release.Build.0 = Release|Win32
+ {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Debug.ActiveCfg = Debug|Win32
+ {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Debug.Build.0 = Debug|Win32
+ {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Release.ActiveCfg = Release|Win32
+ {5C83CE18-4F48-A7FE-6092-B7920AD3A624}.Release.Build.0 = Release|Win32
+ {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Debug.ActiveCfg = Debug|Win32
+ {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Debug.Build.0 = Debug|Win32
+ {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Release.ActiveCfg = Release|Win32
+ {58CCE283-1609-48FE-A4F7-BA0D3A793523}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4FC-BA0D3A792647}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792662}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792658}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792657}.Release.Build.0 = Release|Win32
+ {58C1B183-9026-4E12-00F2-001200540054}.Debug.ActiveCfg = Debug|Win32
+ {58C1B183-9026-4E12-00F2-001200540054}.Debug.Build.0 = Debug|Win32
+ {58C1B183-9026-4E12-00F2-001200540054}.Release.ActiveCfg = Release|Win32
+ {58C1B183-9026-4E12-00F2-001200540054}.Release.Build.0 = Release|Win32
+ {5E18CC83-6092-48FE-A677-B832A0D3A650}.Debug.ActiveCfg = Debug|Win32
+ {5E18CC83-6092-48FE-A677-B832A0D3A650}.Debug.Build.0 = Debug|Win32
+ {5E18CC83-6092-48FE-A677-B832A0D3A650}.Release.ActiveCfg = Release|Win32
+ {5E18CC83-6092-48FE-A677-B832A0D3A650}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792649}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792648}.Release.Build.0 = Release|Win32
+ {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Debug.Build.0 = Debug|Win32
+ {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Release.ActiveCfg = Release|Win32
+ {58CCE183-5091-48FE-A4FC-BA0D3A792446}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792645}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792644}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792643}.Release.Build.0 = Release|Win32
+ {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Debug.ActiveCfg = Debug|Win32
+ {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Debug.Build.0 = Debug|Win32
+ {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Release.ActiveCfg = Release|Win32
+ {58CC8E13-0962-8F4E-77A6-BD3A6832A042}.Release.Build.0 = Release|Win32
+ {58C1B183-9260-4E8F-F200-000000000041}.Debug.ActiveCfg = Debug|Win32
+ {58C1B183-9260-4E8F-F200-000000000041}.Debug.Build.0 = Debug|Win32
+ {58C1B183-9260-4E8F-F200-000000000041}.Release.ActiveCfg = Release|Win32
+ {58C1B183-9260-4E8F-F200-000000000041}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A677-BA0D3A832640}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A677-BA0D3A832640}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A677-BA0D3A832640}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A677-BA0D3A832640}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792638}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.Build.0 = Release|Win32
+ {5821C383-6092-12FE-A877-BA0D33467633}.Debug.ActiveCfg = Debug|Win32
+ {5821C383-6092-12FE-A877-BA0D33467633}.Debug.Build.0 = Debug|Win32
+ {5821C383-6092-12FE-A877-BA0D33467633}.Release.ActiveCfg = Release|Win32
+ {5821C383-6092-12FE-A877-BA0D33467633}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
+ {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Debug.ActiveCfg = Debug|Win32
+ {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Debug.Build.0 = Debug|Win32
+ {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Release.ActiveCfg = Release|Win32
+ {5CCE1883-0926-F7A4-8FE4-BA0606D92331}.Release.Build.0 = Release|Win32
+ {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Debug.ActiveCfg = Debug|Win32
+ {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Debug.Build.0 = Debug|Win32
+ {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Release.ActiveCfg = Release|Win32
+ {5C6D9CE1-2609-F7A4-8FE4-BA0883602330}.Release.Build.0 = Release|Win32
+ {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Debug.ActiveCfg = Debug|Win32
+ {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Debug.Build.0 = Debug|Win32
+ {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Release.ActiveCfg = Release|Win32
+ {58E18CC3-6092-8F4E-A3E7-A792230D3629}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792628}.Release.Build.0 = Release|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A27}.Debug.ActiveCfg = Debug|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A27}.Debug.Build.0 = Debug|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A27}.Release.ActiveCfg = Release|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A27}.Release.Build.0 = Release|Win32
+ {0000058C-0000-0000-0000-000000000021}.Debug.ActiveCfg = Debug|Win32
+ {0000058C-0000-0000-0000-000000000021}.Debug.Build.0 = Debug|Win32
+ {0000058C-0000-0000-0000-000000000021}.Release.ActiveCfg = Release|Win32
+ {0000058C-0000-0000-0000-000000000021}.Release.Build.0 = Release|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.ActiveCfg = Debug|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A14}.Debug.Build.0 = Debug|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.ActiveCfg = Release|Win32
+ {83581CCE-487E-3292-A4E7-BA07926D3A14}.Release.Build.0 = Release|Win32
+ {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.ActiveCfg = Debug|Win32
+ {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.Build.0 = Debug|Win32
+ {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.ActiveCfg = Release|Win32
+ {5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.Build.0 = Release|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.ActiveCfg = Debug|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.Build.0 = Debug|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.ActiveCfg = Release|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.Build.0 = Release|Win32
+ {5189DEA3-3261-F33E-47ED-83BC69F66061}.Debug.ActiveCfg = Debug|Win32
+ {5189DEA3-3261-F33E-47ED-83BC69F66061}.Debug.Build.0 = Debug|Win32
+ {5189DEA3-3261-F33E-47ED-83BC69F66061}.Release.ActiveCfg = Release|Win32
+ {5189DEA3-3261-F33E-47ED-83BC69F66061}.Release.Build.0 = Release|Win32
+ {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Debug.ActiveCfg = Debug|Win32
+ {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Debug.Build.0 = Debug|Win32
+ {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Release.ActiveCfg = Release|Win32
+ {5C82D1D3-3861-3AF1-03EF-89AED4716761}.Release.Build.0 = Release|Win32
+ {4E887AC3-F8EA-6923-A744-C264A398C913}.Debug.ActiveCfg = Debug|Win32
+ {4E887AC3-F8EA-6923-A744-C264A398C913}.Debug.Build.0 = Debug|Win32
+ {4E887AC3-F8EA-6923-A744-C264A398C913}.Release.ActiveCfg = Release|Win32
+ {4E887AC3-F8EA-6923-A744-C264A398C913}.Release.Build.0 = Release|Win32
+ {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Debug.ActiveCfg = Debug|Win32
+ {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Debug.Build.0 = Debug|Win32
+ {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Release.ActiveCfg = Release|Win32
+ {589C2EB3-8A57-1862-F4EA-A6B14C7329A3}.Release.Build.0 = Release|Win32
+ {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Debug.ActiveCfg = Debug|Win32
+ {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Debug.Build.0 = Debug|Win32
+ {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Release.ActiveCfg = Release|Win32
+ {51CE89A3-6092-F4EA-48A7-B4B9AC326093}.Release.Build.0 = Release|Win32
+ {58DF28E3-0926-F47A-E28A-B03A4D619631}.Debug.ActiveCfg = Debug|Win32
+ {58DF28E3-0926-F47A-E28A-B03A4D619631}.Debug.Build.0 = Debug|Win32
+ {58DF28E3-0926-F47A-E28A-B03A4D619631}.Release.ActiveCfg = Release|Win32
+ {58DF28E3-0926-F47A-E28A-B03A4D619631}.Release.Build.0 = Release|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.ActiveCfg = Debug|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.Build.0 = Debug|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.ActiveCfg = Release|Win32
+ {818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.Build.0 = Release|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
+ {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal

Modified: branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj
==============================================================================
--- branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj (original)
+++ branches/release/libs/interprocess/proj/vc7ide/interprocesslib.vcproj 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -173,6 +173,9 @@
                                         RelativePath="..\..\..\..\boost\interprocess\allocators\detail\adaptive_node_pool.hpp">
                                 </File>
                                 <File
+ RelativePath="..\..\..\..\boost\interprocess\allocators\detail\allocator_common.hpp">
+ </File>
+ <File
                                         RelativePath="..\..\..\..\boost\interprocess\allocators\detail\node_pool.hpp">
                                 </File>
                                 <File
@@ -238,10 +241,6 @@
                                 RelativePath="..\..\..\..\boost\interprocess\sync\upgradable_lock.hpp">
                         </File>
                         <Filter
- Name="win32"
- Filter="">
- </Filter>
- <Filter
                                 Name="posix"
                                 Filter="">
                                 <File
@@ -575,6 +574,9 @@
                         <File
                                 RelativePath="..\..\test\util.hpp">
                         </File>
+ <File
+ RelativePath="..\..\test\vector_test.hpp">
+ </File>
                 </Filter>
                 <Filter
                         Name="Proj"

Modified: branches/release/libs/interprocess/test/Jamfile.v2
==============================================================================
--- branches/release/libs/interprocess/test/Jamfile.v2 (original)
+++ branches/release/libs/interprocess/test/Jamfile.v2 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -25,6 +25,8 @@
       : # additional args
       : # test-files
       : # requirements
+ <toolset>acc:<linkflags>-lrt
+ <toolset>acc-pa_risc:<linkflags>-lrt
       ] ;
    }
 

Modified: branches/release/libs/interprocess/test/adaptive_node_pool_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/adaptive_node_pool_test.cpp (original)
+++ branches/release/libs/interprocess/test/adaptive_node_pool_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -17,7 +17,7 @@
    typedef managed_shared_memory::segment_manager segment_manager;
 
    typedef detail::private_adaptive_node_pool
- <segment_manager, 4, 64, 64> node_pool_t;
+ <segment_manager, 4, 64, 64, 5> node_pool_t;
 
    if(!test::test_all_node_pool<node_pool_t>())
       return 1;

Modified: branches/release/libs/interprocess/test/adaptive_pool_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/adaptive_pool_test.cpp (original)
+++ branches/release/libs/interprocess/test/adaptive_pool_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -11,11 +11,13 @@
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/managed_shared_memory.hpp>
 #include <boost/interprocess/containers/list.hpp>
+#include <boost/interprocess/containers/vector.hpp>
 #include <boost/interprocess/allocators/adaptive_pool.hpp>
 #include "print_container.hpp"
 #include "dummy_test_allocator.hpp"
 #include "movable_int.hpp"
 #include "list_test.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
@@ -24,14 +26,36 @@
 typedef adaptive_pool
    <int, managed_shared_memory::segment_manager> shmem_node_allocator_t;
 
+typedef detail::adaptive_pool_v1
+ <int, managed_shared_memory::segment_manager> shmem_node_allocator_v1_t;
+
+//Explicit instantiations to catch compilation errors
+template class adaptive_pool<int, managed_shared_memory::segment_manager>;
+template class detail::adaptive_pool_v1<int, managed_shared_memory::segment_manager>;
+
 //Alias list types
 typedef list<int, shmem_node_allocator_t> MyShmList;
+typedef list<int, shmem_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, shmem_node_allocator_t> MyShmVector;
+typedef vector<int, shmem_node_allocator_v1_t> MyShmVectorV1;
+
 
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>())
       return 1;
 
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+
    return 0;
 }
 

Modified: branches/release/libs/interprocess/test/cached_adaptive_pool_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/cached_adaptive_pool_test.cpp (original)
+++ branches/release/libs/interprocess/test/cached_adaptive_pool_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -16,6 +16,7 @@
 #include "dummy_test_allocator.hpp"
 #include "movable_int.hpp"
 #include "list_test.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
@@ -25,14 +26,37 @@
    <int, managed_shared_memory::segment_manager>
    cached_node_allocator_t;
 
+typedef detail::cached_adaptive_pool_v1
+ <int, managed_shared_memory::segment_manager>
+ cached_node_allocator_v1_t;
+
+//Explicit instantiations to catch compilation errors
+template class cached_adaptive_pool<int, managed_shared_memory::segment_manager>;
+template class detail::cached_adaptive_pool_v1<int, managed_shared_memory::segment_manager>;
+
+
 //Alias list types
 typedef list<int, cached_node_allocator_t> MyShmList;
+typedef list<int, cached_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, cached_node_allocator_t> MyShmVector;
+typedef vector<int, cached_node_allocator_v1_t> MyShmVectorV1;
 
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>())
       return 1;
 
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
+
    return 0;
 }
 

Modified: branches/release/libs/interprocess/test/cached_node_allocator_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/cached_node_allocator_test.cpp (original)
+++ branches/release/libs/interprocess/test/cached_node_allocator_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2004-2007. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2004-2008. Distributed under the Boost
 // Software License, Version 1.0. (See accompanying file
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
@@ -16,23 +16,40 @@
 #include "dummy_test_allocator.hpp"
 #include "movable_int.hpp"
 #include "list_test.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
-//We will work with wide characters for shared memory objects
 //Alias a integer node allocator type
 typedef cached_node_allocator
    <int, managed_shared_memory::segment_manager>
    cached_node_allocator_t;
+typedef detail::cached_node_allocator_v1
+ <int, managed_shared_memory::segment_manager>
+ cached_node_allocator_v1_t;
+
+//Explicit instantiations to catch compilation errors
+template class cached_node_allocator<int, managed_shared_memory::segment_manager>;
+template class detail::cached_node_allocator_v1<int, managed_shared_memory::segment_manager>;
 
 //Alias list types
 typedef list<int, cached_node_allocator_t> MyShmList;
+typedef list<int, cached_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, cached_node_allocator_t> MyShmVector;
+typedef vector<int, cached_node_allocator_v1_t> MyShmVectorV1;
 
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>())
       return 1;
-
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
    return 0;
 }
 

Modified: branches/release/libs/interprocess/test/condition_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/condition_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/condition_test_template.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -139,7 +139,7 @@
 
     // Test timed_wait.
     while (data->notified != 3)
- data->condition.timed_wait(lock, ptime_delay(10));
+ data->condition.timed_wait(lock, ptime_delay(5));
     assert(lock ? true : false);
     assert(data->notified == 3);
     data->awoken++;
@@ -147,7 +147,7 @@
 
     // Test predicate timed_wait.
     cond_predicate pred(data->notified, 4);
- bool ret = data->condition.timed_wait(lock, ptime_delay(10), pred);
+ bool ret = data->condition.timed_wait(lock, ptime_delay(5), pred);
     assert(ret);(void)ret;
     assert(lock ? true : false);
     assert(pred());
@@ -177,7 +177,7 @@
 template <class Condition, class Mutex>
 void do_test_condition_notify_all()
 {
- const int NUMTHREADS = 5;
+ const int NUMTHREADS = 3;
    boost::thread_group threads;
    condition_test_data<Condition, Mutex> data;
 

Modified: branches/release/libs/interprocess/test/expand_bwd_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/expand_bwd_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/expand_bwd_test_template.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -76,7 +76,7 @@
 
 //Function to check if both sets are equal
 template <class Vector1, class Vector2>
-static bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
+bool CheckEqualVector(const Vector1 &vector1, const Vector2 &vector2)
 {
    if(vector1.size() != vector2.size())
       return false;
@@ -84,7 +84,7 @@
 }
 
 template<class Vector>
-static bool CheckUninitializedIsZero(const Vector & v)
+bool CheckUninitializedIsZero(const Vector & v)
 {
    typedef typename Vector::value_type value_type;
    typename Vector::size_type sz = v.size();

Modified: branches/release/libs/interprocess/test/file_mapping_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/file_mapping_test.cpp (original)
+++ branches/release/libs/interprocess/test/file_mapping_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -9,14 +9,16 @@
 //////////////////////////////////////////////////////////////////////////////
 
 #include <boost/interprocess/detail/config_begin.hpp>
-#include <fstream>
+#include <ios> //std::streamoff
+#include <fstream> //std::ofstream, std::ifstream
 #include <iostream>
+#include <ios>
 #include <boost/interprocess/file_mapping.hpp>
 #include <boost/interprocess/mapped_region.hpp>
-#include <memory>
-#include <cstdio>
-#include <string>
+#include <memory> //std::auto_ptr
+#include <stdexcept> //std::exception
 #include <cstdio> //std::remove
+#include <cstddef> //std::size_t
 #include "get_process_id_name.hpp"
 
 using namespace boost::interprocess;

Modified: branches/release/libs/interprocess/test/get_process_id_name.hpp
==============================================================================
--- branches/release/libs/interprocess/test/get_process_id_name.hpp (original)
+++ branches/release/libs/interprocess/test/get_process_id_name.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -12,9 +12,8 @@
 #define BOOST_INTERPROCESS_GET_PROCESS_ID_NAME_HPP
 
 #include <boost/config.hpp>
-#include <string>
-#include <algorithm>
-#include <sstream>
+#include <string> //std::string
+#include <sstream> //std::stringstream
 #include <boost/interprocess/detail/os_thread_functions.hpp>
 
 namespace boost{

Modified: branches/release/libs/interprocess/test/list_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/list_test.hpp (original)
+++ branches/release/libs/interprocess/test/list_test.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -39,7 +39,8 @@
          shmlist->push_back(move(move_me));
          stdlist->push_back(i);
       }
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
       return 0;
    }
 };
@@ -56,7 +57,8 @@
          shmlist->push_front(move(move_me));
          stdlist->push_front(i);
       }
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
       return 0;
    }
 };
@@ -69,7 +71,8 @@
    {
       shmlist->pop_back();
       stdlist->pop_back();
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
       return 0;
    }
 };
@@ -177,12 +180,14 @@
 
       shmlist->unique();
       stdlist->unique();
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
 
       if(copied_allocators_equal){
          shmlist->sort(std::greater<IntType>());
          stdlist->sort(std::greater<int>());
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
       }
 
       shmlist->resize(25);
@@ -191,7 +196,8 @@
       stdlist->resize(50);
       shmlist->resize(0);
       stdlist->resize(0);
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
 
       if(push_data_t::execute(max, shmlist, stdlist)){
          return 1;
@@ -209,7 +215,8 @@
          if(copied_allocators_equal){
             shmlist->splice(shmlist->begin(), othershmlist);
             stdlist->splice(stdlist->begin(), otherstdlist);
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
          }
 
          listsize = (int)shmlist->size();
@@ -225,15 +232,18 @@
          if(copied_allocators_equal){
             shmlist->sort(std::greater<IntType>());
             stdlist->sort(std::greater<int>());
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
 
             othershmlist.sort(std::greater<IntType>());
             otherstdlist.sort(std::greater<int>());
- if(!CheckEqualContainers(&othershmlist, &otherstdlist)) return 1;
+ if(!CheckEqualContainers(&othershmlist, &otherstdlist))
+ return 1;
 
             shmlist->merge(othershmlist, std::greater<IntType>());
             stdlist->merge(otherstdlist, std::greater<int>());
- if(!CheckEqualContainers(shmlist, stdlist)) return 1;
+ if(!CheckEqualContainers(shmlist, stdlist))
+ return 1;
          }
       }
 

Modified: branches/release/libs/interprocess/test/map_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/map_test.hpp (original)
+++ branches/release/libs/interprocess/test/map_test.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -296,6 +296,8 @@
       }
 
       //Now do count exercise
+ shmmap->erase(shmmap->begin(), shmmap->end());
+ shmmultimap->erase(shmmultimap->begin(), shmmultimap->end());
       shmmap->clear();
       shmmultimap->clear();
 

Modified: branches/release/libs/interprocess/test/memory_algorithm_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/memory_algorithm_test.cpp (original)
+++ branches/release/libs/interprocess/test/memory_algorithm_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -14,52 +14,74 @@
 #include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
 #include <boost/interprocess/indexes/null_index.hpp>
 #include <boost/interprocess/sync/mutex_family.hpp>
+#include <boost/interprocess/detail/type_traits.hpp>
 #include "memory_algorithm_test_template.hpp"
 #include <iostream>
 #include <string>
 #include "get_process_id_name.hpp"
 
+using namespace boost::interprocess;
+
+const int memsize = 16384;
+const char *const shMemName = test::get_process_id_name();
+
+int test_simple_seq_fit()
+{
+ //A shared memory with simple sequential fit algorithm
+ typedef basic_managed_shared_memory
+ <char
+ ,simple_seq_fit<mutex_family>
+ ,null_index
+ > my_managed_shared_memory;
+
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ my_managed_shared_memory segment(create_only, shMemName, memsize);
+
+ //Now take the segment manager and launch memory test
+ if(!test::test_all_allocation(*segment.get_segment_manager())){
+ return 1;
+ }
+ return 0;
+}
+
+template<std::size_t Alignment>
+int test_rbtree_best_fit()
+{
+ //A shared memory with red-black tree best fit algorithm
+ typedef basic_managed_shared_memory
+ <char
+ ,rbtree_best_fit<mutex_family, offset_ptr<void>, Alignment>
+ ,null_index
+ > my_managed_shared_memory;
+
+ //Create shared memory
+ shared_memory_object::remove(shMemName);
+ my_managed_shared_memory segment(create_only, shMemName, memsize);
+
+ //Now take the segment manager and launch memory test
+ if(!test::test_all_allocation(*segment.get_segment_manager())){
+ return 1;
+ }
+ return 0;
+}
+
 int main ()
 {
- using namespace boost::interprocess;
- const int memsize = 16384;
- const char *const shMemName = test::get_process_id_name();
-
- {
- //A shared memory with simple sequential fit algorithm
- typedef basic_managed_shared_memory
- <char
- ,simple_seq_fit<mutex_family>
- ,null_index
- > my_managed_shared_memory;
-
- //Create shared memory
- shared_memory_object::remove(shMemName);
- my_managed_shared_memory segment(create_only, shMemName, memsize);
-
- //Now take the segment manager and launch memory test
- if(!test::test_all_allocation(*segment.get_segment_manager())){
- return 1;
- }
- }
-
- {
- //A shared memory with red-black tree best fit algorithm
- typedef basic_managed_shared_memory
- <char
- ,rbtree_best_fit<mutex_family>
- ,null_index
- > my_managed_shared_memory;
-
- //Create shared memory
- shared_memory_object::remove(shMemName);
- my_managed_shared_memory segment(create_only, shMemName, memsize);
-
- //Now take the segment manager and launch memory test
- if(!test::test_all_allocation(*segment.get_segment_manager())){
- return 1;
- }
+ const std::size_t void_ptr_align = detail::alignment_of<void*>::value;
+ if(test_simple_seq_fit()){
+ return 1;
+ }
+ if(test_rbtree_best_fit<void_ptr_align>()){
+ return 1;
+ }
+ if(test_rbtree_best_fit<2*void_ptr_align>()){
+ return 1;
    }
+ if(test_rbtree_best_fit<4*void_ptr_align>()){
+ return 1;
+ }
+
    shared_memory_object::remove(shMemName);
    return 0;
 }

Modified: branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/memory_algorithm_test_template.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -16,7 +16,7 @@
 #include <iostream>
 #include <new>
 #include <utility>
-#include <cstring>
+#include <cstring> //std::memset
 #include <cstdio> //std::remove
 
 namespace boost { namespace interprocess { namespace test {
@@ -38,6 +38,8 @@
          void *ptr = a.allocate(i, std::nothrow);
          if(!ptr)
             break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
          buffers.push_back(ptr);
       }
 
@@ -94,6 +96,8 @@
       void *ptr = a.allocate(i*2, std::nothrow);
       if(!ptr)
          break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
       buffers.push_back(ptr);
    }
 
@@ -111,6 +115,7 @@
          if(received_size < std::size_t(i)){
             return false;
          }
+ std::memset(buffers[i], 0, a.size(buffers[i]));
       }
    }
    
@@ -139,6 +144,8 @@
       void *ptr = a.allocate(i, std::nothrow);
       if(!ptr)
          break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
       buffers.push_back(ptr);
    }
 
@@ -203,7 +210,7 @@
 
    //Now shrink to half
    for(int i = 0, max = (int)buffers.size()
- ;i < max
+ ; i < max
       ; ++i){
       std::size_t received_size;
       if(a.template allocation_command<char>
@@ -224,9 +231,10 @@
       ;i < max
       ;++i){
       std::size_t received_size;
+ std::size_t request_size = received_sizes[i];
       if(a.template allocation_command<char>
- ( expand_fwd | nothrow_allocation, received_sizes[i]
- , received_sizes[i], received_size, (char*)buffers[i]).first){
+ ( expand_fwd | nothrow_allocation, request_size
+ , request_size, received_size, (char*)buffers[i]).first){
          if(received_size != received_sizes[i]){
             return false;
          }
@@ -262,6 +270,8 @@
       void *ptr = a.allocate(i, std::nothrow);
       if(!ptr)
          break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
       buffers.push_back(ptr);
    }
 
@@ -327,19 +337,21 @@
 bool test_allocation_with_reuse(Allocator &a)
 {
    //We will repeat this test for different sized elements
- for(int size = 1; size < 20; ++size){
+ for(int sizeof_object = 1; sizeof_object < 20; ++sizeof_object){
       std::vector<void*> buffers;
 
       //Allocate buffers with extra memory
       for(int i = 0; true; ++i){
- void *ptr = a.allocate(i*size, std::nothrow);
+ void *ptr = a.allocate(i*sizeof_object, std::nothrow);
          if(!ptr)
             break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
          buffers.push_back(ptr);
       }
       
       //Now deallocate all except the latest
- //Now try to expand to the double of the size
+ //Now try to expand to the double of the sizeof_object
       for(int i = 0, max = (int)buffers.size() - 1
          ;i < max
          ;++i){
@@ -353,14 +365,18 @@
       //Now allocate with reuse
       std::size_t received_size = 0;
       for(int i = 0; true; ++i){
- std::pair<void*, bool> ret = a.template allocation_command<char>
- ( expand_bwd | nothrow_allocation, received_size/size*size + size
- , received_size/size*size+(i+1)*size*2, received_size, (char*)ptr);
+ std::size_t min_size = (received_size + 1);
+ std::size_t prf_size = (received_size + (i+1)*2);
+ std::pair<void*, bool> ret = a.raw_allocation_command
+ ( expand_bwd | nothrow_allocation, min_size
+ , prf_size, received_size, (char*)ptr, sizeof_object);
          if(!ret.first)
             break;
          //If we have memory, this must be a buffer reuse
          if(!ret.second)
             return 1;
+ if(received_size < min_size)
+ return 1;
          ptr = ret.first;
       }
       //There is only a single block so deallocate it
@@ -456,6 +472,8 @@
       void *ptr = a.allocate(i, std::nothrow);
       if(!ptr)
          break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 1, size);
       buffers.push_back(ptr);
    }
 
@@ -544,6 +562,8 @@
       void *ptr = a.allocate(i, std::nothrow);
       if(!ptr)
          break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
       buffers.push_back(ptr);
    }
 
@@ -564,7 +584,11 @@
    for(int j = 0, max = (int)buffers.size()
       ;j < max
       ;++j){
- int pos = (j%4)*((int)buffers.size())/4;
+ int pos = (j%5)*((int)buffers.size())/4;
+ if(pos == int(buffers.size()))
+ --pos;
+ a.deallocate(buffers[pos]);
+ buffers.erase(buffers.begin()+pos);
       std::size_t old_free = a.get_free_memory();
       a.shrink_to_fit();
       if(!a.check_sanity()) return false;
@@ -576,9 +600,6 @@
       if(!a.check_sanity()) return false;
       if(original_size != a.get_size()) return false;
       if(old_free != a.get_free_memory()) return false;
-
- a.deallocate(buffers[pos]);
- buffers.erase(buffers.begin()+pos);
    }
 
    //Now shrink it to the maximum
@@ -623,6 +644,8 @@
          void *ptr = a.allocate(i, std::nothrow);
          if(!ptr)
             break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
          if(!a.check_sanity())
             return false;
          buffers2.push_back(ptr);
@@ -736,6 +759,8 @@
          void *ptr = a.allocate(i, std::nothrow);
          if(!ptr)
             break;
+ std::size_t size = a.size(ptr);
+ std::memset(ptr, 0, size);
          buffers2.push_back(ptr);
       }
 
@@ -816,6 +841,57 @@
    return true;
 }
 
+//This test allocates multiple values until there is no more memory
+//and after that deallocates all in the inverse order
+template<class Allocator>
+bool test_many_deallocation(Allocator &a)
+{
+ typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
+ const std::size_t ArraySize = 11;
+ std::vector<multiallocation_iterator> buffers;
+ std::size_t requested_sizes[ArraySize];
+ for(std::size_t i = 0; i < ArraySize; ++i){
+ requested_sizes[i] = 4*i;
+ }
+ std::size_t free_memory = a.get_free_memory();
+
+ {
+ for(int i = 0; true; ++i){
+ multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
+ if(!it)
+ break;
+ buffers.push_back(it);
+ }
+ for(int i = 0, max = (int)buffers.size(); i != max; ++i){
+ a.deallocate_many(buffers[i]);
+ }
+ buffers.clear();
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+
+ {
+ for(int i = 0; true; ++i){
+ multiallocation_iterator it = a.allocate_many(i*4, ArraySize, std::nothrow);
+ if(!it)
+ break;
+ buffers.push_back(it);
+ }
+ for(int i = 0, max = (int)buffers.size(); i != max; ++i){
+ a.deallocate_many(buffers[i]);
+ }
+ buffers.clear();
+
+ bool ok = free_memory == a.get_free_memory() &&
+ a.all_memory_deallocated() && a.check_sanity();
+ if(!ok) return ok;
+ }
+
+ return true;
+}
+
+
 //This function calls all tests
 template<class Allocator>
 bool test_all_allocation(Allocator &a)
@@ -847,6 +923,12 @@
       return false;
    }
 
+ if(!test_many_deallocation(a)){
+ std::cout << "test_many_deallocation failed. Class: "
+ << typeid(a).name() << std::endl;
+ return false;
+ }
+
    std::cout << "Starting test_allocation_shrink. Class: "
              << typeid(a).name() << std::endl;
 

Modified: branches/release/libs/interprocess/test/mutex_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/mutex_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/mutex_test_template.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -123,7 +123,7 @@
       BOOST_INTERPROCES_CHECK(lock ? true : false);
       lock.unlock();
       BOOST_INTERPROCES_CHECK(!lock);
- boost::posix_time::ptime pt = delay(10*BaseSeconds, 0);
+ boost::posix_time::ptime pt = delay(3*BaseSeconds, 0);
       BOOST_INTERPROCES_CHECK(lock.timed_lock(pt));
       BOOST_INTERPROCES_CHECK(lock ? true : false);
    }
@@ -152,7 +152,7 @@
       }
       {
          //This should always lock
- boost::posix_time::ptime pt = delay(3*BaseSeconds);
+ boost::posix_time::ptime pt = delay(2*BaseSeconds);
          lock_type lock1(mx, pt);
          lock_type lock2(mx, pt);
       }
@@ -171,7 +171,7 @@
       boost::thread::sleep(xsecs(pdata->m_secs));
    }
    else{
- boost::thread::sleep(xsecs(3*BaseSeconds));
+ boost::thread::sleep(xsecs(2*BaseSeconds));
    }
 
    ++shared_val;
@@ -184,7 +184,7 @@
    data<M> *pdata = (data<M> *) arg;
    boost::interprocess::scoped_lock<M> l(sm, boost::interprocess::defer_lock);
    if (l.try_lock()){
- boost::thread::sleep(xsecs(3*BaseSeconds));
+ boost::thread::sleep(xsecs(2*BaseSeconds));
       ++shared_val;
       pdata->m_value = shared_val;
    }
@@ -198,7 +198,7 @@
    boost::interprocess::scoped_lock<M>
       l (sm, boost::interprocess::defer_lock);
    if (l.timed_lock(pt)){
- boost::thread::sleep(xsecs(3*BaseSeconds));
+ boost::thread::sleep(xsecs(2*BaseSeconds));
       ++shared_val;
       pdata->m_value = shared_val;
    }
@@ -223,13 +223,13 @@
    data<M> d1(1);
    data<M> d2(2);
 
- // Locker one launches, holds the lock for 3*BaseSeconds seconds.
+ // Locker one launches, holds the lock for 2*BaseSeconds seconds.
    boost::thread tm1(thread_adapter<M>(&lock_and_sleep, &d1, *pm1));
 
    //Wait 1*BaseSeconds
    boost::thread::sleep(xsecs(1*BaseSeconds));
 
- // Locker two launches, but it won't hold the lock for 3*BaseSeconds seconds.
+ // Locker two launches, but it won't hold the lock for 2*BaseSeconds seconds.
    boost::thread tm2(thread_adapter<M>(&lock_and_sleep, &d2, *pm2));
 
    //Wait completion
@@ -259,7 +259,7 @@
    data<M> d1(1);
    data<M> d2(2);
 
- // Locker one launches, holds the lock for 3*BaseSeconds seconds.
+ // Locker one launches, holds the lock for 2*BaseSeconds seconds.
    boost::thread tm1(thread_adapter<M>(&try_lock_and_sleep, &d1, *pm1));
 
    //Wait 1*BaseSeconds
@@ -293,16 +293,16 @@
       pm2 = &m2;
    }
 
- data<M> d1(1, 3*BaseSeconds);
- data<M> d2(2, 3*BaseSeconds);
+ data<M> d1(1, 2*BaseSeconds);
+ data<M> d2(2, 2*BaseSeconds);
 
- // Locker one launches, holds the lock for 3*BaseSeconds seconds.
+ // Locker one launches, holds the lock for 2*BaseSeconds seconds.
    boost::thread tm1(thread_adapter<M>(&timed_lock_and_sleep, &d1, *pm1));
 
    //Wait 1*BaseSeconds
    boost::thread::sleep(xsecs(1*BaseSeconds));
 
- // Locker two launches, holds the lock for 3*BaseSeconds seconds.
+ // Locker two launches, holds the lock for 2*BaseSeconds seconds.
    boost::thread tm2(thread_adapter<M>(&timed_lock_and_sleep, &d2, *pm2));
 
    //Wait completion
@@ -315,7 +315,7 @@
 }
 
 template <typename M>
-static inline void test_all_lock()
+inline void test_all_lock()
 {
    //Now generic interprocess_mutex tests
    std::cout << "test_lock<" << typeid(M).name() << ">" << std::endl;
@@ -327,7 +327,7 @@
 }
 
 template <typename M>
-static inline void test_all_recursive_lock()
+inline void test_all_recursive_lock()
 {
    //Now generic interprocess_mutex tests
    std::cout << "test_recursive_lock<" << typeid(M).name() << ">" << std::endl;

Modified: branches/release/libs/interprocess/test/named_creation_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/named_creation_template.hpp (original)
+++ branches/release/libs/interprocess/test/named_creation_template.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -15,12 +15,13 @@
 #include <boost/interprocess/exceptions.hpp>
 #include "boost_interprocess_check.hpp"
 #include <iostream>
+#include <typeinfo>
 #include <boost/interprocess/creation_tags.hpp>
 
 namespace boost { namespace interprocess { namespace test {
 
 template <class NamedResource>
-static inline void create_then_open_then_open_or_create()
+inline void create_then_open_then_open_or_create()
 {
    try{
       //Create it and open it twice
@@ -35,7 +36,7 @@
 }
 
 template <class NamedResource>
-static inline void open_or_create_then_create()
+inline void open_or_create_then_create()
 {
    //Create it with open_or_create and try to create it twice
    NamedResource nresource1(open_or_create);
@@ -48,7 +49,7 @@
 }
 
 template <class NamedResource>
-static inline void dont_create_and_open()
+inline void dont_create_and_open()
 {
    //Try to open it without creating
    try{
@@ -63,7 +64,7 @@
 }
 
 template <class NamedResource>
-static inline void test_named_creation()
+inline void test_named_creation()
 {
    std::cout << "create_then_open_then_open_or_create<"
                << typeid(NamedResource).name() << ">" << std::endl;

Modified: branches/release/libs/interprocess/test/node_allocator_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/node_allocator_test.cpp (original)
+++ branches/release/libs/interprocess/test/node_allocator_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -16,6 +16,7 @@
 #include "dummy_test_allocator.hpp"
 #include "movable_int.hpp"
 #include "list_test.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
@@ -23,15 +24,31 @@
 //Alias a integer node allocator type
 typedef node_allocator
    <int, managed_shared_memory::segment_manager> shmem_node_allocator_t;
+typedef detail::node_allocator_v1
+ <int, managed_shared_memory::segment_manager> shmem_node_allocator_v1_t;
+
+//Explicit instantiations to catch compilation errors
+template class node_allocator<int, managed_shared_memory::segment_manager>;
+template class detail::node_allocator_v1<int, managed_shared_memory::segment_manager>;
 
 //Alias list types
 typedef list<int, shmem_node_allocator_t> MyShmList;
+typedef list<int, shmem_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, shmem_node_allocator_t> MyShmVector;
+typedef vector<int, shmem_node_allocator_v1_t> MyShmVectorV1;
 
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>())
       return 1;
-
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
    return 0;
 }
 

Modified: branches/release/libs/interprocess/test/node_pool_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/node_pool_test.hpp (original)
+++ branches/release/libs/interprocess/test/node_pool_test.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -42,7 +42,7 @@
 
    //First allocate nodes
    for(std::size_t i = 0; i < num_alloc; ++i){
- nodes.push_back(pool.allocate(1));
+ nodes.push_back(pool.allocate_node());
    }
 
    //Check that the free count is correct
@@ -52,7 +52,7 @@
    
    //Now deallocate all and check again
    for(std::size_t i = 0; i < num_alloc; ++i){
- pool.deallocate(nodes[i], 1);
+ pool.deallocate_node(nodes[i]);
    }
 
    //Check that the free count is correct
@@ -85,7 +85,7 @@
 
    //First allocate nodes
    for(std::size_t i = 0; i < max_nodes; ++i){
- nodes.push_back(pool.allocate(1));
+ nodes.push_back(pool.allocate_node());
    }
 
    //Check that the free count is correct
@@ -97,7 +97,7 @@
    for(std::size_t node_i = 0; node_i < nodes_per_chunk; ++node_i){
       //Deallocate a node per chunk
       for(std::size_t i = 0; i < max_chunks; ++i){
- pool.deallocate(nodes[i*nodes_per_chunk + node_i], 1);
+ pool.deallocate_node(nodes[i*nodes_per_chunk + node_i]);
       }
 
       //Check that the free count is correct

Modified: branches/release/libs/interprocess/test/private_adaptive_pool_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/private_adaptive_pool_test.cpp (original)
+++ branches/release/libs/interprocess/test/private_adaptive_pool_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -16,6 +16,7 @@
 #include "dummy_test_allocator.hpp"
 #include "movable_int.hpp"
 #include "list_test.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
@@ -23,15 +24,31 @@
 //Alias a private adaptive pool that allocates ints
 typedef private_adaptive_pool
    <int, managed_shared_memory::segment_manager> priv_node_allocator_t;
+typedef detail::private_adaptive_pool_v1
+ <int, managed_shared_memory::segment_manager> priv_node_allocator_v1_t;
+
+//Explicit instantiations to catch compilation errors
+template class private_adaptive_pool<int, managed_shared_memory::segment_manager>;
+template class detail::private_adaptive_pool_v1<int, managed_shared_memory::segment_manager>;
 
 //Alias list types
 typedef list<int, priv_node_allocator_t> MyShmList;
+typedef list<int, priv_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, priv_node_allocator_t> MyShmVector;
+typedef vector<int, priv_node_allocator_v1_t> MyShmVectorV1;
 
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>(false))
       return 1;
-
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>(false))
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
    return 0;
 }
 

Modified: branches/release/libs/interprocess/test/private_node_allocator_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/private_node_allocator_test.cpp (original)
+++ branches/release/libs/interprocess/test/private_node_allocator_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -16,6 +16,7 @@
 #include "dummy_test_allocator.hpp"
 #include "movable_int.hpp"
 #include "list_test.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
@@ -23,15 +24,31 @@
 //Alias a integer node allocator type
 typedef private_node_allocator
    <int, managed_shared_memory::segment_manager> priv_node_allocator_t;
+typedef detail::private_node_allocator_v1
+ <int, managed_shared_memory::segment_manager> priv_node_allocator_v1_t;
+
+//Explicit instantiations to catch compilation errors
+template class private_node_allocator<int, managed_shared_memory::segment_manager>;
+template class detail::private_node_allocator_v1<int, managed_shared_memory::segment_manager>;
 
 //Alias list types
-typedef list<int, priv_node_allocator_t> MyShmList;
+typedef list<int, priv_node_allocator_t> MyShmList;
+typedef list<int, priv_node_allocator_v1_t> MyShmListV1;
+
+//Alias vector types
+typedef vector<int, priv_node_allocator_t> MyShmVector;
+typedef vector<int, priv_node_allocator_v1_t> MyShmVectorV1;
 
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>(false))
       return 1;
-
+ if(test::list_test<managed_shared_memory, MyShmListV1, true>(false))
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVector>())
+ return 1;
+ if(test::vector_test<managed_shared_memory, MyShmVectorV1>())
+ return 1;
    return 0;
 }
 

Modified: branches/release/libs/interprocess/test/semaphore_test_template.hpp
==============================================================================
--- branches/release/libs/interprocess/test/semaphore_test_template.hpp (original)
+++ branches/release/libs/interprocess/test/semaphore_test_template.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -282,7 +282,7 @@
 }
 
 template <typename P>
-static inline void test_all_lock()
+inline void test_all_lock()
 {
    //Now generic interprocess_mutex tests
    std::cout << "test_wait<" << typeid(P).name() << ">" << std::endl;
@@ -294,7 +294,7 @@
 }
 
 template <typename P>
-static inline void test_all_recursive_lock()
+inline void test_all_recursive_lock()
 {
    //Now generic interprocess_mutex tests
    std::cout << "test_recursive_lock<" << typeid(P).name() << ">" << std::endl;

Modified: branches/release/libs/interprocess/test/set_test.hpp
==============================================================================
--- branches/release/libs/interprocess/test/set_test.hpp (original)
+++ branches/release/libs/interprocess/test/set_test.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -384,6 +384,8 @@
       }
 
       //Now do count exercise
+ shmset->erase(shmset->begin(), shmset->end());
+ shmmultiset->erase(shmmultiset->begin(), shmmultiset->end());
       shmset->clear();
       shmmultiset->clear();
 

Modified: branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp (original)
+++ branches/release/libs/interprocess/test/shared_memory_mapping_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -69,7 +69,7 @@
          //Create a file mapping
          shared_memory_object mapping(open_only, test::get_process_id_name(), read_write);
          mapped_region region(mapping, read_write, 0, FileSize/2, 0);
- mapped_region region2(mapping, read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0);
+ mapped_region region2(mapping, read_write, FileSize/2, FileSize - FileSize/2, 0);
 
          unsigned char *checker = (unsigned char*)region.get_address();
          //Check pattern

Modified: branches/release/libs/interprocess/test/vector_test.cpp
==============================================================================
--- branches/release/libs/interprocess/test/vector_test.cpp (original)
+++ branches/release/libs/interprocess/test/vector_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -17,227 +17,22 @@
 
 #include <boost/interprocess/managed_shared_memory.hpp>
 #include <boost/interprocess/containers/vector.hpp>
-#include <boost/interprocess/indexes/flat_map_index.hpp>
 #include <boost/interprocess/allocators/allocator.hpp>
 #include "allocator_v1.hpp"
-#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/move_iterator.hpp>
-#include <boost/interprocess/detail/move.hpp>
-#include "print_container.hpp"
 #include "check_equal_containers.hpp"
 #include "movable_int.hpp"
 #include "expand_bwd_test_allocator.hpp"
 #include "expand_bwd_test_template.hpp"
 #include "dummy_test_allocator.hpp"
-#include <string>
-#include "get_process_id_name.hpp"
+#include "vector_test.hpp"
 
 using namespace boost::interprocess;
 
-typedef basic_managed_shared_memory
- <char,
- simple_seq_fit<mutex_family>,
- flat_map_index
- > managed_shared_memory_t;
-
 //Explicit instantiation to detect compilation errors
 template class boost::interprocess::vector<test::movable_and_copyable_int,
    test::dummy_test_allocator<test::movable_and_copyable_int> >;
 
-template<class V1, class V2>
-bool copyable_only(V1 *, V2 *, detail::false_type)
-{
- return true;
-}
-
-//Function to check if both sets are equal
-template<class V1, class V2>
-bool copyable_only(V1 *shmvector, V2 *stdvector, detail::true_type)
-{
- typedef typename V1::value_type IntType;
- std::size_t size = shmvector->size();
- stdvector->insert(stdvector->end(), 50, 1);
- shmvector->insert(shmvector->end(), 50, 1);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- {
- IntType move_me(1);
- stdvector->insert(stdvector->begin()+size/2, 50, 1);
- shmvector->insert(shmvector->begin()+size/2, 50, move(move_me));
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
- }
- {
- IntType move_me(2);
- shmvector->assign(shmvector->size()/2, move(move_me));
- stdvector->assign(stdvector->size()/2, 2);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
- }
- {
- IntType move_me(3);
- shmvector->assign(shmvector->size()*3-1, move(move_me));
- stdvector->assign(stdvector->size()*3-1, 3);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
- }
- return true;
-}
-
-template<class IntType, template<class T, class SegmentManager> class AllocatorType >
-bool do_test()
-{
- //Customize managed_shared_memory class
- typedef basic_managed_shared_memory
- <char,
- //simple_seq_fit<mutex_family>,
- rbtree_best_fit<mutex_family>,
- flat_map_index
- > my_managed_shared_memory;
-
- //Alias AllocatorType type
- typedef AllocatorType<IntType, my_managed_shared_memory::segment_manager>
- shmem_allocator_t;
-
- //Alias vector types
- typedef vector<IntType, shmem_allocator_t> MyShmVector;
- typedef std::vector<int> MyStdVector;
-
- std::string process_name;
- test::get_process_id_name(process_name);
-
- const int Memsize = 65536;
- const char *const shMemName = process_name.c_str();
- const int max = 100;
-
- {
- //Compare several shared memory vector operations with std::vector
- //Create shared memory
- shared_memory_object::remove(shMemName);
- try{
- my_managed_shared_memory segment(create_only, shMemName, Memsize);
-
- segment.reserve_named_objects(100);
-
- //Shared memory allocator must be always be initialized
- //since it has no default constructor
- MyShmVector *shmvector = segment.template construct<MyShmVector>("MyShmVector")
- (segment.get_segment_manager());
- MyStdVector *stdvector = new MyStdVector;
-
- shmvector->resize(100);
- stdvector->resize(100);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- shmvector->resize(200);
- stdvector->resize(200);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- shmvector->resize(0);
- stdvector->resize(0);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- for(int i = 0; i < max; ++i){
- IntType new_int(i);
- shmvector->insert(shmvector->end(), move(new_int));
- stdvector->insert(stdvector->end(), i);
- }
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- typename MyShmVector::iterator shmit(shmvector->begin());
- typename MyStdVector::iterator stdit(stdvector->begin());
- typename MyShmVector::const_iterator cshmit = shmit;
- ++shmit; ++stdit;
- shmvector->erase(shmit);
- stdvector->erase(stdit);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- shmvector->erase(shmvector->begin());
- stdvector->erase(stdvector->begin());
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- {
- //Initialize values
- IntType aux_vect[50];
- for(int i = 0; i < 50; ++i){
- IntType new_int(-1);
- aux_vect[i] = move(new_int);
- }
- int aux_vect2[50];
- for(int i = 0; i < 50; ++i){
- aux_vect2[i] = -1;
- }
-
- shmvector->insert(shmvector->end()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(aux_vect + 50));
- stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- for(int i = 0, j = static_cast<int>(shmvector->size()); i < j; ++i){
- shmvector->erase(shmvector->begin());
- stdvector->erase(stdvector->begin());
- }
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
- }
- {
- IntType aux_vect[50];
- for(int i = 0; i < 50; ++i){
- IntType new_int(-1);
- aux_vect[i] = move(new_int);
- }
- int aux_vect2[50];
- for(int i = 0; i < 50; ++i){
- aux_vect2[i] = -1;
- }
- shmvector->insert(shmvector->begin()
- ,detail::make_move_iterator(&aux_vect[0])
- ,detail::make_move_iterator(aux_vect + 50));
- stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
- }
-
- shmvector->reserve(shmvector->size()*2);
- stdvector->reserve(stdvector->size()*2);
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- IntType push_back_this(1);
- shmvector->push_back(move(push_back_this));
- stdvector->push_back(int(1));
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- if(!copyable_only(shmvector, stdvector
- ,detail::bool_<!is_movable<IntType>::value>())){
- return false;
- }
-
- shmvector->erase(shmvector->begin());
- stdvector->erase(stdvector->begin());
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- for(int i = 0; i < max; ++i){
- IntType insert_this(i);
- shmvector->insert(shmvector->begin(), move(insert_this));
- stdvector->insert(stdvector->begin(), i);
- }
- if(!test::CheckEqualContainers(shmvector, stdvector)) return false;
-
- delete stdvector;
- segment.template destroy<MyShmVector>("MyShmVector");
- segment.shrink_to_fit_indexes();
-
- if(!segment.all_memory_deallocated())
- return false;
- }
- catch(std::exception &ex){
- shared_memory_object::remove(shMemName);
- std::cout << ex.what() << std::endl;
- return false;
- }
- }
- shared_memory_object::remove(shMemName);
- std::cout << std::endl << "Test OK!" << std::endl;
- return true;
-}
-
-bool test_expand_bwd()
+int test_expand_bwd()
 {
    //Now test all back insertion possibilities
 
@@ -248,7 +43,7 @@
       int_vector;
 
    if(!test::test_all_expand_bwd<int_vector>())
- return false;
+ return 1;
 
    //Now user defined wrapped int
    typedef test::expand_bwd_test_allocator<test::int_holder>
@@ -257,7 +52,7 @@
       int_holder_vector;
 
    if(!test::test_all_expand_bwd<int_holder_vector>())
- return false;
+ return 1;
 
    //Now user defined bigger wrapped int
    typedef test::expand_bwd_test_allocator<test::triple_int_holder>
@@ -267,26 +62,32 @@
       triple_int_holder_vector;
 
    if(!test::test_all_expand_bwd<triple_int_holder_vector>())
- return false;
+ return 1;
 
- return true;
+ return 0;
 }
 
 int main()
 {
- if(!do_test<int, allocator>())
- return 1;
+ typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
+ typedef vector<int, ShmemAllocator> MyVector;
+
+ typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
+ typedef vector<test::movable_int, ShmemMoveAllocator> MyMoveVector;
+
+ typedef allocator<test::movable_and_copyable_int, managed_shared_memory::segment_manager> ShmemCopyMoveAllocator;
+ typedef vector<test::movable_and_copyable_int, ShmemCopyMoveAllocator> MyCopyMoveVector;
 
- if(!do_test<test::movable_int, allocator>())
+ if(test::vector_test<managed_shared_memory, MyVector>())
       return 1;
 
- if(!do_test<test::movable_and_copyable_int, allocator>())
+ if(test::vector_test<managed_shared_memory, MyMoveVector>())
       return 1;
 
- if(!do_test<int, test::allocator_v1>())
+ if(test::vector_test<managed_shared_memory, MyCopyMoveVector>())
       return 1;
 
- if(!test_expand_bwd())
+ if(test_expand_bwd())
       return 1;
 
    return 0;

Modified: branches/release/libs/intrusive/doc/html/reference.css
==============================================================================
--- branches/release/libs/intrusive/doc/html/reference.css (original)
+++ branches/release/libs/intrusive/doc/html/reference.css 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,3 +1,11 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
 PRE.synopsis {
   background-color: #e0ffff;
   border: thin solid blue;

Modified: branches/release/libs/intrusive/example/doc_list_algorithms.cpp
==============================================================================
--- branches/release/libs/intrusive/example/doc_list_algorithms.cpp (original)
+++ branches/release/libs/intrusive/example/doc_list_algorithms.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -38,7 +38,7 @@
 
    //Create an empty doubly linked list container:
    //"one" will be the first node of the container
- algo::init(&one);
+ algo::init_header(&one);
    assert(algo::count(&one) == 1);
 
    //Now add a new node before "one"

Modified: branches/release/libs/intrusive/example/doc_slist_algorithms.cpp
==============================================================================
--- branches/release/libs/intrusive/example/doc_slist_algorithms.cpp (original)
+++ branches/release/libs/intrusive/example/doc_slist_algorithms.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -36,7 +36,7 @@
 
    //Create an empty singly linked list container:
    //"one" will be the first node of the container
- algo::init(&one);
+ algo::init_header(&one);
    assert(algo::count(&one) == 1);
 
    //Now add a new node

Modified: branches/release/libs/intrusive/example/doc_splay_algorithms.cpp
==============================================================================
--- branches/release/libs/intrusive/example/doc_splay_algorithms.cpp (original)
+++ branches/release/libs/intrusive/example/doc_splay_algorithms.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -75,5 +75,4 @@
    algo::erase(&header, &three);
    return 0;
 }
-
-//]
\ No newline at end of file
+//]

Modified: branches/release/libs/intrusive/proj/vc7ide/Intrusive.sln
==============================================================================
--- branches/release/libs/intrusive/proj/vc7ide/Intrusive.sln (original)
+++ branches/release/libs/intrusive/proj/vc7ide/Intrusive.sln 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -1,175 +1,175 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list", "list\list.vcproj", "{977B61B4-9968-497C-9F0B-24A8145473B8}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist", "slist\slist.vcproj", "{5A02061D-3728-4C49-AFC8-0130C1F161C0}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiset", "multiset\multiset.vcproj", "{961F0E06-C092-4AF7-ABC5-2A49999F3B79}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_intrusivelib", "_intrusivelib\_intrusivelib.vcproj", "{90F3C5BD-8E6C-4629-BC71-A1009EC88059}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "set", "set\set.vcproj", "{960E01F6-92C1-F74A-BCA5-2A9F3B994979}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_set", "unordered_set\unordered_set.vcproj", "{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_multiset", "unordered_multiset\unordered_multiset.vcproj", "{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perf_test", "perf_test\perf_test.vcproj", "{910E70E6-2C91-AA67-BF4C-A9C74A309927}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "default_hook", "default_hook\default_hook.vcproj", "{761A79B4-9968-CB81-F02B-2A4497345475}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stateful_value_traits", "stateful_value_traits\stateful_value_traits.vcproj", "{9571A7B4-9968-B9C1-17FB-134547B46975}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "virtual_base", "virtual_base\virtual_base.vcproj", "{3579B1A4-9894-02AB-CB81-297B46154345}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_functions", "make_functions\make_functions.vcproj", "{7679B41B-F2B4-9176-CB81-35449467B435}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "custom_bucket_traits", "custom_bucket_traits\custom_bucket_traits.vcproj", "{31C77B84-0B2C-9481-CB81-27A149F33825}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "external_value_traits", "external_value_traits\external_value_traits.vcproj", "{97B69A72-B9D3-7389-17FB-74612F4A9543}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_multiset", "splay_multiset\splay_multiset.vcproj", "{01E70176-B6C5-BF47-2C91-A949077BA323}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_set", "splay_set\splay_set.vcproj", "{1E6909E7-C971-F24A-6C7B-A92094B71B59}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avl_multiset", "avl_multiset\avl_multiset.vcproj", "{0AE70176-5B8C-4BC7-392C-A4A312B07893}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avl_set", "avl_set\avl_set.vcproj", "{16909EE7-24AF-97C1-C76B-204B971BA959}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_multiset", "sg_multiset\sg_multiset.vcproj", "{07022E76-6CB5-92C1-B47F-A10772A79B43}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_set", "sg_set\sg_set.vcproj", "{1690A9E7-DB57-971C-F24A-09B752A942F7}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.ActiveCfg = Debug|Win32
- {977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.Build.0 = Debug|Win32
- {977B61B4-9968-497C-9F0B-24A8145473B8}.Release.ActiveCfg = Release|Win32
- {977B61B4-9968-497C-9F0B-24A8145473B8}.Release.Build.0 = Release|Win32
- {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Debug.ActiveCfg = Debug|Win32
- {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Debug.Build.0 = Debug|Win32
- {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Release.ActiveCfg = Release|Win32
- {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Release.Build.0 = Release|Win32
- {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Debug.ActiveCfg = Debug|Win32
- {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Debug.Build.0 = Debug|Win32
- {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Release.ActiveCfg = Release|Win32
- {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Release.Build.0 = Release|Win32
- {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Debug.ActiveCfg = Debug|Win32
- {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Debug.Build.0 = Debug|Win32
- {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Release.ActiveCfg = Release|Win32
- {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Release.Build.0 = Release|Win32
- {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Debug.ActiveCfg = Debug|Win32
- {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Debug.Build.0 = Debug|Win32
- {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Release.ActiveCfg = Release|Win32
- {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Release.Build.0 = Release|Win32
- {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.ActiveCfg = Debug|Win32
- {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.Build.0 = Debug|Win32
- {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Release.ActiveCfg = Release|Win32
- {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Release.Build.0 = Release|Win32
- {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Debug.ActiveCfg = Debug|Win32
- {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Debug.Build.0 = Debug|Win32
- {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Release.ActiveCfg = Release|Win32
- {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Release.Build.0 = Release|Win32
- {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Debug.ActiveCfg = Debug|Win32
- {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Debug.Build.0 = Debug|Win32
- {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Release.ActiveCfg = Release|Win32
- {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Release.Build.0 = Release|Win32
- {761A79B4-9968-CB81-F02B-2A4497345475}.Debug.ActiveCfg = Debug|Win32
- {761A79B4-9968-CB81-F02B-2A4497345475}.Debug.Build.0 = Debug|Win32
- {761A79B4-9968-CB81-F02B-2A4497345475}.Release.ActiveCfg = Release|Win32
- {761A79B4-9968-CB81-F02B-2A4497345475}.Release.Build.0 = Release|Win32
- {9571A7B4-9968-B9C1-17FB-134547B46975}.Debug.ActiveCfg = Debug|Win32
- {9571A7B4-9968-B9C1-17FB-134547B46975}.Debug.Build.0 = Debug|Win32
- {9571A7B4-9968-B9C1-17FB-134547B46975}.Release.ActiveCfg = Release|Win32
- {9571A7B4-9968-B9C1-17FB-134547B46975}.Release.Build.0 = Release|Win32
- {3579B1A4-9894-02AB-CB81-297B46154345}.Debug.ActiveCfg = Debug|Win32
- {3579B1A4-9894-02AB-CB81-297B46154345}.Debug.Build.0 = Debug|Win32
- {3579B1A4-9894-02AB-CB81-297B46154345}.Release.ActiveCfg = Release|Win32
- {3579B1A4-9894-02AB-CB81-297B46154345}.Release.Build.0 = Release|Win32
- {7679B41B-F2B4-9176-CB81-35449467B435}.Debug.ActiveCfg = Debug|Win32
- {7679B41B-F2B4-9176-CB81-35449467B435}.Debug.Build.0 = Debug|Win32
- {7679B41B-F2B4-9176-CB81-35449467B435}.Release.ActiveCfg = Release|Win32
- {7679B41B-F2B4-9176-CB81-35449467B435}.Release.Build.0 = Release|Win32
- {31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.ActiveCfg = Debug|Win32
- {31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.Build.0 = Debug|Win32
- {31C77B84-0B2C-9481-CB81-27A149F33825}.Release.ActiveCfg = Release|Win32
- {31C77B84-0B2C-9481-CB81-27A149F33825}.Release.Build.0 = Release|Win32
- {97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.ActiveCfg = Debug|Win32
- {97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.Build.0 = Debug|Win32
- {97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.ActiveCfg = Release|Win32
- {97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.Build.0 = Release|Win32
- {01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.ActiveCfg = Debug|Win32
- {01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.Build.0 = Debug|Win32
- {01E70176-B6C5-BF47-2C91-A949077BA323}.Release.ActiveCfg = Release|Win32
- {01E70176-B6C5-BF47-2C91-A949077BA323}.Release.Build.0 = Release|Win32
- {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Debug.ActiveCfg = Debug|Win32
- {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Debug.Build.0 = Debug|Win32
- {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Release.ActiveCfg = Release|Win32
- {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Release.Build.0 = Release|Win32
- {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Debug.ActiveCfg = Debug|Win32
- {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Debug.Build.0 = Debug|Win32
- {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Release.ActiveCfg = Release|Win32
- {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Release.Build.0 = Release|Win32
- {16909EE7-24AF-97C1-C76B-204B971BA959}.Debug.ActiveCfg = Debug|Win32
- {16909EE7-24AF-97C1-C76B-204B971BA959}.Debug.Build.0 = Debug|Win32
- {16909EE7-24AF-97C1-C76B-204B971BA959}.Release.ActiveCfg = Release|Win32
- {16909EE7-24AF-97C1-C76B-204B971BA959}.Release.Build.0 = Release|Win32
- {07022E76-6CB5-92C1-B47F-A10772A79B43}.Debug.ActiveCfg = Debug|Win32
- {07022E76-6CB5-92C1-B47F-A10772A79B43}.Debug.Build.0 = Debug|Win32
- {07022E76-6CB5-92C1-B47F-A10772A79B43}.Release.ActiveCfg = Release|Win32
- {07022E76-6CB5-92C1-B47F-A10772A79B43}.Release.Build.0 = Release|Win32
- {1690A9E7-DB57-971C-F24A-09B752A942F7}.Debug.ActiveCfg = Debug|Win32
- {1690A9E7-DB57-971C-F24A-09B752A942F7}.Debug.Build.0 = Debug|Win32
- {1690A9E7-DB57-971C-F24A-09B752A942F7}.Release.ActiveCfg = Release|Win32
- {1690A9E7-DB57-971C-F24A-09B752A942F7}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list", "list\list.vcproj", "{977B61B4-9968-497C-9F0B-24A8145473B8}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist", "slist\slist.vcproj", "{5A02061D-3728-4C49-AFC8-0130C1F161C0}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiset", "multiset\multiset.vcproj", "{961F0E06-C092-4AF7-ABC5-2A49999F3B79}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_intrusivelib", "_intrusivelib\_intrusivelib.vcproj", "{90F3C5BD-8E6C-4629-BC71-A1009EC88059}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "set", "set\set.vcproj", "{960E01F6-92C1-F74A-BCA5-2A9F3B994979}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_set", "unordered_set\unordered_set.vcproj", "{90E701E6-2C91-F4A7-BA6C-A9F3B0949279}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_multiset", "unordered_multiset\unordered_multiset.vcproj", "{9101EE76-BB6C-2C91-F4B7-A9F3B9490279}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perf_test", "perf_test\perf_test.vcproj", "{910E70E6-2C91-AA67-BF4C-A9C74A309927}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "default_hook", "default_hook\default_hook.vcproj", "{761A79B4-9968-CB81-F02B-2A4497345475}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stateful_value_traits", "stateful_value_traits\stateful_value_traits.vcproj", "{9571A7B4-9968-B9C1-17FB-134547B46975}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "virtual_base", "virtual_base\virtual_base.vcproj", "{3579B1A4-9894-02AB-CB81-297B46154345}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_functions", "make_functions\make_functions.vcproj", "{7679B41B-F2B4-9176-CB81-35449467B435}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "custom_bucket_traits", "custom_bucket_traits\custom_bucket_traits.vcproj", "{31C77B84-0B2C-9481-CB81-27A149F33825}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "external_value_traits", "external_value_traits\external_value_traits.vcproj", "{97B69A72-B9D3-7389-17FB-74612F4A9543}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_multiset", "splay_multiset\splay_multiset.vcproj", "{01E70176-B6C5-BF47-2C91-A949077BA323}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_set", "splay_set\splay_set.vcproj", "{1E6909E7-C971-F24A-6C7B-A92094B71B59}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avl_multiset", "avl_multiset\avl_multiset.vcproj", "{0AE70176-5B8C-4BC7-392C-A4A312B07893}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avl_set", "avl_set\avl_set.vcproj", "{16909EE7-24AF-97C1-C76B-204B971BA959}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_multiset", "sg_multiset\sg_multiset.vcproj", "{07022E76-6CB5-92C1-B47F-A10772A79B43}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sg_set", "sg_set\sg_set.vcproj", "{1690A9E7-DB57-971C-F24A-09B752A942F7}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.ActiveCfg = Debug|Win32
+ {977B61B4-9968-497C-9F0B-24A8145473B8}.Debug.Build.0 = Debug|Win32
+ {977B61B4-9968-497C-9F0B-24A8145473B8}.Release.ActiveCfg = Release|Win32
+ {977B61B4-9968-497C-9F0B-24A8145473B8}.Release.Build.0 = Release|Win32
+ {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Debug.ActiveCfg = Debug|Win32
+ {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Debug.Build.0 = Debug|Win32
+ {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Release.ActiveCfg = Release|Win32
+ {5A02061D-3728-4C49-AFC8-0130C1F161C0}.Release.Build.0 = Release|Win32
+ {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Debug.ActiveCfg = Debug|Win32
+ {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Debug.Build.0 = Debug|Win32
+ {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Release.ActiveCfg = Release|Win32
+ {961F0E06-C092-4AF7-ABC5-2A49999F3B79}.Release.Build.0 = Release|Win32
+ {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Debug.ActiveCfg = Debug|Win32
+ {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Debug.Build.0 = Debug|Win32
+ {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Release.ActiveCfg = Release|Win32
+ {90F3C5BD-8E6C-4629-BC71-A1009EC88059}.Release.Build.0 = Release|Win32
+ {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Debug.ActiveCfg = Debug|Win32
+ {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Debug.Build.0 = Debug|Win32
+ {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Release.ActiveCfg = Release|Win32
+ {960E01F6-92C1-F74A-BCA5-2A9F3B994979}.Release.Build.0 = Release|Win32
+ {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.ActiveCfg = Debug|Win32
+ {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Debug.Build.0 = Debug|Win32
+ {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Release.ActiveCfg = Release|Win32
+ {90E701E6-2C91-F4A7-BA6C-A9F3B0949279}.Release.Build.0 = Release|Win32
+ {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Debug.ActiveCfg = Debug|Win32
+ {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Debug.Build.0 = Debug|Win32
+ {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Release.ActiveCfg = Release|Win32
+ {9101EE76-BB6C-2C91-F4B7-A9F3B9490279}.Release.Build.0 = Release|Win32
+ {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Debug.ActiveCfg = Debug|Win32
+ {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Debug.Build.0 = Debug|Win32
+ {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Release.ActiveCfg = Release|Win32
+ {910E70E6-2C91-AA67-BF4C-A9C74A309927}.Release.Build.0 = Release|Win32
+ {761A79B4-9968-CB81-F02B-2A4497345475}.Debug.ActiveCfg = Debug|Win32
+ {761A79B4-9968-CB81-F02B-2A4497345475}.Debug.Build.0 = Debug|Win32
+ {761A79B4-9968-CB81-F02B-2A4497345475}.Release.ActiveCfg = Release|Win32
+ {761A79B4-9968-CB81-F02B-2A4497345475}.Release.Build.0 = Release|Win32
+ {9571A7B4-9968-B9C1-17FB-134547B46975}.Debug.ActiveCfg = Debug|Win32
+ {9571A7B4-9968-B9C1-17FB-134547B46975}.Debug.Build.0 = Debug|Win32
+ {9571A7B4-9968-B9C1-17FB-134547B46975}.Release.ActiveCfg = Release|Win32
+ {9571A7B4-9968-B9C1-17FB-134547B46975}.Release.Build.0 = Release|Win32
+ {3579B1A4-9894-02AB-CB81-297B46154345}.Debug.ActiveCfg = Debug|Win32
+ {3579B1A4-9894-02AB-CB81-297B46154345}.Debug.Build.0 = Debug|Win32
+ {3579B1A4-9894-02AB-CB81-297B46154345}.Release.ActiveCfg = Release|Win32
+ {3579B1A4-9894-02AB-CB81-297B46154345}.Release.Build.0 = Release|Win32
+ {7679B41B-F2B4-9176-CB81-35449467B435}.Debug.ActiveCfg = Debug|Win32
+ {7679B41B-F2B4-9176-CB81-35449467B435}.Debug.Build.0 = Debug|Win32
+ {7679B41B-F2B4-9176-CB81-35449467B435}.Release.ActiveCfg = Release|Win32
+ {7679B41B-F2B4-9176-CB81-35449467B435}.Release.Build.0 = Release|Win32
+ {31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.ActiveCfg = Debug|Win32
+ {31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.Build.0 = Debug|Win32
+ {31C77B84-0B2C-9481-CB81-27A149F33825}.Release.ActiveCfg = Release|Win32
+ {31C77B84-0B2C-9481-CB81-27A149F33825}.Release.Build.0 = Release|Win32
+ {97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.ActiveCfg = Debug|Win32
+ {97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.Build.0 = Debug|Win32
+ {97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.ActiveCfg = Release|Win32
+ {97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.Build.0 = Release|Win32
+ {01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.ActiveCfg = Debug|Win32
+ {01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.Build.0 = Debug|Win32
+ {01E70176-B6C5-BF47-2C91-A949077BA323}.Release.ActiveCfg = Release|Win32
+ {01E70176-B6C5-BF47-2C91-A949077BA323}.Release.Build.0 = Release|Win32
+ {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Debug.ActiveCfg = Debug|Win32
+ {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Debug.Build.0 = Debug|Win32
+ {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Release.ActiveCfg = Release|Win32
+ {1E6909E7-C971-F24A-6C7B-A92094B71B59}.Release.Build.0 = Release|Win32
+ {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Debug.ActiveCfg = Debug|Win32
+ {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Debug.Build.0 = Debug|Win32
+ {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Release.ActiveCfg = Release|Win32
+ {0AE70176-5B8C-4BC7-392C-A4A312B07893}.Release.Build.0 = Release|Win32
+ {16909EE7-24AF-97C1-C76B-204B971BA959}.Debug.ActiveCfg = Debug|Win32
+ {16909EE7-24AF-97C1-C76B-204B971BA959}.Debug.Build.0 = Debug|Win32
+ {16909EE7-24AF-97C1-C76B-204B971BA959}.Release.ActiveCfg = Release|Win32
+ {16909EE7-24AF-97C1-C76B-204B971BA959}.Release.Build.0 = Release|Win32
+ {07022E76-6CB5-92C1-B47F-A10772A79B43}.Debug.ActiveCfg = Debug|Win32
+ {07022E76-6CB5-92C1-B47F-A10772A79B43}.Debug.Build.0 = Debug|Win32
+ {07022E76-6CB5-92C1-B47F-A10772A79B43}.Release.ActiveCfg = Release|Win32
+ {07022E76-6CB5-92C1-B47F-A10772A79B43}.Release.Build.0 = Release|Win32
+ {1690A9E7-DB57-971C-F24A-09B752A942F7}.Debug.ActiveCfg = Debug|Win32
+ {1690A9E7-DB57-971C-F24A-09B752A942F7}.Debug.Build.0 = Debug|Win32
+ {1690A9E7-DB57-971C-F24A-09B752A942F7}.Release.ActiveCfg = Release|Win32
+ {1690A9E7-DB57-971C-F24A-09B752A942F7}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal

Modified: branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj
==============================================================================
--- branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj (original)
+++ branches/release/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -136,6 +136,9 @@
                                 RelativePath="..\..\..\..\..\boost\intrusive\intrusive_fwd.hpp">
                         </File>
                         <File
+ RelativePath="..\..\..\..\..\boost\intrusive\linear_slist_algorithms.hpp">
+ </File>
+ <File
                                 RelativePath="..\..\..\..\..\boost\intrusive\link_mode.hpp">
                         </File>
                         <File
@@ -214,6 +217,9 @@
                                         RelativePath="..\..\..\..\..\boost\intrusive\detail\avltree_node.hpp">
                                 </File>
                                 <File
+ RelativePath="..\..\..\..\..\boost\intrusive\detail\common_slist_algorithms.hpp">
+ </File>
+ <File
                                         RelativePath="..\..\..\..\..\boost\intrusive\detail\config_begin.hpp">
                                 </File>
                                 <File

Deleted: branches/release/libs/intrusive/proj/vc7ide/to-do.txt
==============================================================================
--- branches/release/libs/intrusive/proj/vc7ide/to-do.txt 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
+++ (empty file)
@@ -1,7 +0,0 @@
-add includes needed for the snippets
-add section explaining splice(...,n)
-Faltaría, en mi opinión, una guía de qué headers incluyen a cuáles. P.ej.,
-los *_hook.hpp típicamente están incluidos por el header del contenedor asociado, etc.
-Add resize() to list
-Optimize rehash for when shrinking: there is no need to hash the values.
-Optimize store_hash<true> to work with the same node and type traits as store_hash<false>

Modified: branches/release/libs/intrusive/test/itestvalue.hpp
==============================================================================
--- branches/release/libs/intrusive/test/itestvalue.hpp (original)
+++ branches/release/libs/intrusive/test/itestvalue.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -237,7 +237,7 @@
    // have to be handled appropriately when copied:
 
    testvalue & operator= (const testvalue& src)
- {
+ {/*
       set_base_hook_t::operator=(src);
       set_auto_base_hook_t::operator=(src);
       this->set_node_ = src.set_node_;
@@ -270,7 +270,7 @@
       slist_auto_base_hook_t::operator=(src);
       this->slist_node_ = src.slist_node_;
       this->slist_auto_node_ = src.slist_auto_node_;
-
+*/
       value_ = src.value_;
       return *this;
    }
@@ -366,6 +366,14 @@
    }
 };
 
+struct is_even
+{
+ template<class VoidPointer, bool constant_time_size>
+ bool operator()
+ (const testvalue<VoidPointer, constant_time_size>& v1) const
+ { return (v1.value_ & 1) == 0; }
+};
+
 } //namespace boost{
 } //namespace intrusive{
 

Modified: branches/release/libs/intrusive/test/list_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/list_test.cpp (original)
+++ branches/release/libs/intrusive/test/list_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -31,6 +31,8 @@
    static void test_all(std::vector<value_type>& values);
    static void test_front_back(std::vector<value_type>& values);
    static void test_sort(std::vector<value_type>& values);
+ static void test_merge(std::vector<value_type>& values);
+ static void test_remove_unique(std::vector<value_type>& values);
    static void test_insert(std::vector<value_type>& values);
    static void test_shift(std::vector<value_type>& values);
    static void test_swap(std::vector<value_type>& values);
@@ -58,19 +60,13 @@
 
    test_front_back(values);
    test_sort(values);
+ test_merge(values);
+ test_remove_unique(values);
    test_insert(values);
    test_shift(values);
    test_swap(values);
    test_clone(values);
    test_container_from_end(values);
-/*
- const char *list_name = typeid(list_type).name();
- std::cout << list_name << std::endl << strlen(list_name) << std::endl;
- const char *value_t = typeid(typename list_type::value_traits).name();
- std::cout << value_t << std::endl << strlen(value_t) << std::endl;
- const char *list_it_name = typeid(typename list_type::iterator).name();
- std::cout << list_it_name << std::endl << strlen(list_it_name ) << std::endl;
-*/
 }
 
 //test: push_front, pop_front, push_back, pop_back, front, back, size, empty:
@@ -134,6 +130,60 @@
    { int init_values [] = { 5, 3, 1, 4, 2 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
 }
+
+//test: merge due to error in merge implementation:
+template<class ValueTraits>
+void test_list<ValueTraits>
+ ::test_remove_unique (std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ > list_type;
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_if(is_even());
+ int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ std::vector<typename ValueTraits::value_type> values2(values);
+ list_type list(values.begin(), values.end());
+ list.insert(list.end(), values2.begin(), values2.end());
+ list.sort();
+ int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ list.unique();
+ int init_values2 [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
+ }
+}
+
+//test: merge due to error in merge implementation:
+template<class ValueTraits>
+void test_list<ValueTraits>
+ ::test_merge (std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef list
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ > list_type;
+ list_type testlist1, testlist2;
+ testlist1.push_front (values[0]);
+ testlist2.push_front (values[4]);
+ testlist2.push_front (values[3]);
+ testlist2.push_front (values[2]);
+ testlist1.merge (testlist2);
+
+ int init_values [] = { 1, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
+}
   
 //test: assign, insert, const_iterator, const_reverse_iterator, erase, s_iterator_to:
 template<class ValueTraits>
@@ -194,26 +244,29 @@
    const int num_values = (int)values.size();
    std::vector<int> expected_values(num_values);
 
- //Shift forward all possible positions 3 times
- for(int i = 0; i < num_values*3; ++i){
- testlist.assign(values.begin(), values.end());
- testlist.shift_forward(i);
- for(int j = 0; j < num_values; ++j){
- expected_values[(j + num_values - i%num_values) % num_values] = (j + 1);
+ for(int s = 1; s <= num_values; ++s){
+ expected_values.resize(s);
+ //Shift forward all possible positions 3 times
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert(testlist.begin(), &values[0], &values[0] + s);
+ testlist.shift_forward(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + s - i%s) % s] = (j + 1);
+ }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
+ testlist.clear();
       }
- TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
- testlist.clear();
- }
 
- //Shift backwards all possible positions
- for(int i = 0; i < num_values*3; ++i){
- testlist.assign(values.begin(), values.end());
- testlist.shift_backwards(i);
- for(int j = 0; j < num_values; ++j){
- expected_values[(j + i) % num_values] = (j + 1);
+ //Shift backwards all possible positions
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert(testlist.begin(), &values[0], &values[0] + s);
+ testlist.shift_backwards(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + i) % s] = (j + 1);
+ }
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
+ testlist.clear();
       }
- TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin());
- testlist.clear();
    }
 }
 
@@ -278,6 +331,28 @@
       { int init_values [] = { 4, 3 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
    }
+ {
+ list_type testlist1 (&values[0], &values[1]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ values[1].swap_nodes(values[2]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ values[0].swap_nodes(values[2]);
+
+ { int init_values [] = { 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ values[0].swap_nodes(values[2]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ }
+
 }
 
 template<class ValueTraits>

Modified: branches/release/libs/intrusive/test/slist_test.cpp
==============================================================================
--- branches/release/libs/intrusive/test/slist_test.cpp (original)
+++ branches/release/libs/intrusive/test/slist_test.cpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
@@ -24,24 +24,28 @@
 
 using namespace boost::intrusive;
 
-template<class ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
 struct test_slist
 {
    typedef typename ValueTraits::value_type value_type;
- static void test_all (std::vector<value_type>& values);
- static void test_front_back (std::vector<value_type>& values);
+ static void test_all(std::vector<value_type>& values);
+ static void test_front(std::vector<value_type>& values);
+ static void test_back(std::vector<value_type>& values, detail::bool_<true>);
+ static void test_back(std::vector<value_type>& values, detail::bool_<false>);
    static void test_sort(std::vector<value_type>& values);
- static void test_merge (std::vector<value_type>& values);
+ static void test_merge(std::vector<value_type>& values);
+ static void test_remove_unique(std::vector<value_type>& values);
    static void test_insert(std::vector<value_type>& values);
    static void test_shift(std::vector<value_type>& values);
    static void test_swap(std::vector<value_type>& values);
- static void test_slow_insert (std::vector<value_type>& values);
- static void test_clone (std::vector<value_type>& values);
- static void test_container_from_end(std::vector<value_type> &values);
+ static void test_slow_insert(std::vector<value_type>& values);
+ static void test_clone(std::vector<value_type>& values);
+ static void test_container_from_end(std::vector<value_type> &, detail::bool_<true>){}
+ static void test_container_from_end(std::vector<value_type> &values, detail::bool_<false>);
 };
 
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_all (std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -50,6 +54,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    {
       list_type list(values.begin(), values.end());
@@ -58,21 +64,23 @@
       list.insert(list.end(), values.begin(), values.end());
       test::test_sequence_container(list, values);
    }
- test_front_back (values);
+ test_front(values);
+ test_back(values, detail::bool_<CacheLast>());
    test_sort(values);
    test_merge (values);
+ test_remove_unique(values);
    test_insert(values);
    test_shift(values);
    test_slow_insert (values);
    test_swap(values);
    test_clone(values);
- test_container_from_end(values);
+ test_container_from_end(values, detail::bool_<Linear>());
 }
 
 //test: push_front, pop_front, front, size, empty:
-template<class ValueTraits>
-void test_slist<ValueTraits>
- ::test_front_back (std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_front(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef slist
@@ -80,6 +88,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist;
    BOOST_TEST (testlist.empty());
@@ -98,11 +108,45 @@
      
    testlist.pop_front();
    BOOST_TEST (testlist.empty());
-}
+}
+
+//test: push_front, pop_front, front, size, empty:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_back(std::vector<typename ValueTraits::value_type>& values, detail::bool_<true>)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
+ > list_type;
+ list_type testlist;
+ BOOST_TEST (testlist.empty());
+
+ testlist.push_back (values[0]);
+ BOOST_TEST (testlist.size() == 1);
+ BOOST_TEST (&testlist.front() == &values[0]);
+ BOOST_TEST (&testlist.back() == &values[0]);
+ testlist.push_back(values[1]);
+ BOOST_TEST(*testlist.previous(testlist.end()) == values[1]);
+ BOOST_TEST (&testlist.front() == &values[0]);
+ BOOST_TEST (&testlist.back() == &values[1]);
+}
+
+//test: push_front, pop_front, front, size, empty:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_back(std::vector<typename ValueTraits::value_type>&, detail::bool_<false>)
+{}
+
 
 //test: merge due to error in merge implementation:
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_merge (std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -111,6 +155,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist1, testlist2;
    testlist1.push_front (values[0]);
@@ -123,9 +169,42 @@
    TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
 }
 
+//test: merge due to error in merge implementation:
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_remove_unique (std::vector<typename ValueTraits::value_type>& values)
+{
+ typedef typename ValueTraits::value_type value_type;
+ typedef slist
+ < value_type
+ , value_traits<ValueTraits>
+ , size_type<std::size_t>
+ , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
+ > list_type;
+ {
+ list_type list(values.begin(), values.end());
+ list.remove_if(is_even());
+ int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ }
+ {
+ std::vector<typename ValueTraits::value_type> values2(values);
+ list_type list(values.begin(), values.end());
+ list.insert_after(list.before_begin(), values2.begin(), values2.end());
+ list.sort();
+ int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
+ list.unique();
+ int init_values2 [] = { 1, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
+ }
+}
+
 //test: constructor, iterator, sort, reverse:
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -134,6 +213,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist (values.begin(), values.end());
 
@@ -145,13 +226,13 @@
       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
 
    testlist.reverse();
- { int init_values [] = { 5, 3, 1, 4, 2, };
+ { int init_values [] = { 5, 3, 1, 4, 2 };
       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() ); }
 }
   
 //test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous:
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -160,6 +241,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist;
    testlist.assign (&values[0] + 2, &values[0] + 5);
@@ -189,8 +272,8 @@
 }
 
 //test: insert, const_iterator, erase, siterator_to:
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_slow_insert (std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -199,6 +282,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist;
    testlist.push_front (values[4]);
@@ -232,8 +317,8 @@
    BOOST_TEST (testlist.front().value_ == 3);
 }
 
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_shift(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -242,6 +327,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist;
 
@@ -249,33 +336,36 @@
    std::vector<int> expected_values(num_values);
 
    //Shift forward all possible positions 3 times
- for(int i = 0; i < num_values*3; ++i){
- testlist.assign(values.begin(), values.end());
- testlist.shift_forward(i);
- for(int j = 0; j < num_values; ++j){
- expected_values[(j + num_values - i%num_values) % num_values] = (j + 1);
+ for(int s = 1; s <= num_values; ++s){
+ expected_values.resize(s);
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert_after(testlist.before_begin(), &values[0], &values[0] + s);
+ testlist.shift_forward(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + s - i%s) % s] = (j + 1);
+ }
+
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
+ testlist.clear();
       }
 
- TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
- testlist.clear();
- }
+ //Shift backwards all possible positions
+ for(int i = 0; i < s*3; ++i){
+ testlist.insert_after(testlist.before_begin(), &values[0], &values[0] + s);
+ testlist.shift_backwards(i);
+ for(int j = 0; j < s; ++j){
+ expected_values[(j + i) % s] = (j + 1);
+ }
 
- //Shift backwards all possible positions
- for(int i = 0; i < num_values*3; ++i){
- testlist.assign(values.begin(), values.end());
- testlist.shift_backwards(i);
- for(int j = 0; j < num_values; ++j){
- expected_values[(j + i) % num_values] = (j + 1);
+ TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
+ testlist.clear();
       }
-
- TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
- testlist.clear();
    }
 }
 
 //test: insert_after (seq-version), swap, splice_after:
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -284,11 +374,13 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    {
       list_type testlist1 (&values[0], &values[0] + 2);
       list_type testlist2;
- testlist2.insert_after (testlist2.end(), &values[0] + 2, &values[0] + 5);
+ testlist2.insert_after (testlist2.before_begin(), &values[0] + 2, &values[0] + 5);
       testlist1.swap(testlist2);
       { int init_values [] = { 3, 4, 5 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
@@ -299,19 +391,20 @@
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
       BOOST_TEST (testlist1.empty());
 
- testlist1.splice_after (testlist1.end(), testlist2, ++testlist2.begin());
+ testlist1.splice_after (testlist1.before_begin(), testlist2, ++testlist2.begin());
       { int init_values [] = { 4 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
       { int init_values [] = { 1, 3, 5, 2 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
 
       testlist1.splice_after (testlist1.begin(), testlist2,
- testlist2.end(), ++++testlist2.begin());
+ testlist2.before_begin(), ++++testlist2.begin());
       { int init_values [] = { 4, 1, 3, 5 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
       { int init_values [] = { 2 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
    }
+ if(!list_type::linear)
    {
       list_type testlist1 (&values[0], &values[0] + 2);
       list_type testlist2 (&values[0] + 3, &values[0] + 5);
@@ -326,10 +419,32 @@
       { int init_values [] = { 4, 3 };
          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() ); }
    }
+ if(!list_type::linear)
+ {
+ list_type testlist1 (&values[0], &values[1]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ values[1].swap_nodes(values[2]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ values[0].swap_nodes(values[2]);
+
+ { int init_values [] = { 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+
+ values[0].swap_nodes(values[2]);
+
+ { int init_values [] = { 1 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() ); }
+ }
 }
 
-template<class ValueTraits>
-void test_slist<ValueTraits>
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -338,6 +453,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
 
       list_type testlist1 (&values[0], &values[0] + values.size());
@@ -349,9 +466,10 @@
       BOOST_TEST (testlist2.empty());
 }
 
-template<class ValueTraits>
-void test_slist<ValueTraits>
- ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool Linear, bool CacheLast>
+void test_slist<ValueTraits, Linear, CacheLast>
+ ::test_container_from_end(std::vector<typename ValueTraits::value_type>& values
+ ,detail::bool_<false>)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef slist
@@ -359,6 +477,8 @@
       , value_traits<ValueTraits>
       , size_type<std::size_t>
       , constant_time_size<value_type::constant_time_size>
+ , linear<Linear>
+ , cache_last<CacheLast>
> list_type;
    list_type testlist1 (&values[0], &values[0] + values.size());
    BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end()));
@@ -380,7 +500,29 @@
                   < value_type
                   , typename value_type::slist_base_hook_t
>::type
+ , false
+ , false
+ >::test_all(data);
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ , false
+ , false
+ >::test_all(data);
+
+ //Now linear slists
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ , true
+ , false
>::test_all(data);
+
       test_slist < typename detail::get_member_value_traits
                   < value_type
                   , member_hook< value_type
@@ -388,8 +530,48 @@
                                , &value_type::slist_node_
>
>::type
+ , true
+ , false
>::test_all(data);
 
+ //Now the same but caching the last node
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ , false
+ , true
+ >::test_all(data);
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ , false
+ , true
+ >::test_all(data);
+
+ //Now linear slists
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ , true
+ , true
+ >::test_all(data);
+
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ , true
+ , true
+ >::test_all(data);
       return 0;
    }
 };
@@ -409,6 +591,8 @@
                   < value_type
                   , typename value_type::slist_base_hook_t
>::type
+ , false
+ , false
>::test_all(data);
 
       test_slist < typename detail::get_member_value_traits
@@ -418,12 +602,16 @@
                                , &value_type::slist_node_
>
>::type
+ , false
+ , false
>::test_all(data);
 
       test_slist < typename detail::get_base_value_traits
                   < value_type
                   , typename value_type::slist_auto_base_hook_t
>::type
+ , false
+ , false
>::test_all(data);
 
       test_slist < typename detail::get_member_value_traits
@@ -433,6 +621,66 @@
                                , &value_type::slist_auto_node_
>
>::type
+ , false
+ , false
+ >::test_all(data);
+
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ , true
+ , false
+ >::test_all(data);
+
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ , true
+ , false
+ >::test_all(data);
+
+ //Now cache last
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ , false
+ , true
+ >::test_all(data);
+
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ , false
+ , true
+ >::test_all(data);
+
+ test_slist < typename detail::get_base_value_traits
+ < value_type
+ , typename value_type::slist_base_hook_t
+ >::type
+ , true
+ , true
+ >::test_all(data);
+
+ test_slist < typename detail::get_member_value_traits
+ < value_type
+ , member_hook< value_type
+ , typename value_type::slist_member_hook_t
+ , &value_type::slist_node_
+ >
+ >::type
+ , true
+ , true
>::test_all(data);
       return 0;
    }

Deleted: branches/release/libs/intrusive/test/test_templates.hpp
==============================================================================
--- branches/release/libs/intrusive/test/test_templates.hpp 2008-01-27 17:22:22 EST (Sun, 27 Jan 2008)
+++ (empty file)
@@ -1,65 +0,0 @@
-#ifndef BOOST_INTRUSIVE_TEST_TEST_TEMPLATES_HPP
-#define BOOST_INTRUSIVE_TEST_TEST_TEMPLATES_HPP
-
-#include <vector>
-
-namespace boost {
-namespace intrusive {
-namespace test {
-
-template<class Container>
-void test_shift()
-{
- typedef typename ValueTraits::value_type testvalue_t;
- boost::test_tools::output_test_stream test_seq;
- Container test_cont;
- const int NumElem = 6;
-
- std::vector<typename Container::value_type> values(NumElem);
- for(int i = 0; i < NumElem; ++i){
- values[i] = i+1;
- }
-
- const int num_values = (int)values.size();
- std::vector<int> expected_values(num_values);
-
- //Shift forward all possible positions 3 times
- for(int i = 0; i < num_values*3; ++i){
- test_cont.assign(values.begin(), values.end());
- test_cont.shift_forward(i);
- for(int j = 0; j < num_values; ++j){
- expected_values[(j + num_values - i%num_values) % num_values] = (j + 1);
- }
- std::copy (test_cont.begin(), test_cont.end(),
- std::ostream_iterator<testvalue_t> (test_seq));
- std::stringstream stream;
- std::copy (expected_values.begin(), expected_values.end(),
- std::ostream_iterator<testvalue_t> (stream));
- stream << std::ends;
- BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
- test_cont.clear();
- }
-
- //Shift backwards all possible positions
- for(int i = 0; i < num_values*2; ++i){
- test_cont.assign(values.begin(), values.end());
- test_cont.shift_backwards(i);
- for(int j = 0; j < num_values; ++j){
- expected_values[(j + i) % num_values] = (j + 1);
- }
- std::copy (test_cont.begin(), test_cont.end(),
- std::ostream_iterator<testvalue_t> (test_seq));
- std::stringstream stream;
- std::copy (expected_values.begin(), expected_values.end(),
- std::ostream_iterator<testvalue_t> (stream));
- stream << std::ends;
- BOOST_CHECK (test_seq.is_equal (stream.str().c_str()));
- test_cont.clear();
- }
-}
-
-} //namespace test {
-} //namespace intrusive {
-} //namespace boost {
-
-#endif //#ifndef BOOST_INTRUSIVE_TEST_TEST_TEMPLATES_HPP


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