Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49322 - in branches/release/boost: interprocess interprocess/allocators interprocess/allocators/detail interprocess/containers interprocess/containers/detail interprocess/detail interprocess/ipc interprocess/mem_algo interprocess/mem_algo/detail interprocess/smart_ptr interprocess/sync interprocess/sync/emulation interprocess/sync/posix intrusive intrusive/detail
From: igaztanaga_at_[hidden]
Date: 2008-10-13 15:37:00


Author: igaztanaga
Date: 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
New Revision: 49322
URL: http://svn.boost.org/trac/boost/changeset/49322

Log:
Changes and fixes for Boost 1.37

Added:
   branches/release/boost/interprocess/detail/advanced_insert_int.hpp
      - copied unchanged from r49318, /trunk/boost/interprocess/detail/advanced_insert_int.hpp
   branches/release/boost/interprocess/detail/preprocessor.hpp
      - copied unchanged from r49318, /trunk/boost/interprocess/detail/preprocessor.hpp
   branches/release/boost/interprocess/detail/variadic_templates_tools.hpp
      - copied unchanged from r49318, /trunk/boost/interprocess/detail/variadic_templates_tools.hpp
   branches/release/boost/intrusive/detail/workaround.hpp
      - copied unchanged from r49317, /trunk/boost/intrusive/detail/workaround.hpp
Properties modified:
   branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp (contents, props changed)
   branches/release/boost/interprocess/detail/math_functions.hpp (contents, props changed)
   branches/release/boost/interprocess/detail/segment_manager_helper.hpp (contents, props changed)
   branches/release/boost/interprocess/detail/utilities.hpp (contents, props changed)
Text files modified:
   branches/release/boost/interprocess/allocators/allocator.hpp | 2
   branches/release/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 21
   branches/release/boost/interprocess/allocators/detail/node_pool.hpp | 15
   branches/release/boost/interprocess/anonymous_shared_memory.hpp | 12
   branches/release/boost/interprocess/containers/deque.hpp | 958 ++++++++++++++++++---------------------
   branches/release/boost/interprocess/containers/detail/flat_tree.hpp | 204 +++++++-
   branches/release/boost/interprocess/containers/detail/node_alloc_holder.hpp | 98 ++-
   branches/release/boost/interprocess/containers/detail/tree.hpp | 300 +++++++++--
   branches/release/boost/interprocess/containers/flat_map.hpp | 281 +++++++++--
   branches/release/boost/interprocess/containers/flat_set.hpp | 187 +++++++
   branches/release/boost/interprocess/containers/list.hpp | 252 ++++++++--
   branches/release/boost/interprocess/containers/map.hpp | 102 ++++
   branches/release/boost/interprocess/containers/set.hpp | 167 ++++++
   branches/release/boost/interprocess/containers/slist.hpp | 263 ++++++++--
   branches/release/boost/interprocess/containers/string.hpp | 2
   branches/release/boost/interprocess/containers/vector.hpp | 782 +++++++++++++++++++-------------
   branches/release/boost/interprocess/detail/algorithms.hpp | 11
   branches/release/boost/interprocess/detail/atomic.hpp | 8
   branches/release/boost/interprocess/detail/config_begin.hpp | 4
   branches/release/boost/interprocess/detail/intersegment_ptr.hpp | 69 +-
   branches/release/boost/interprocess/detail/managed_memory_impl.hpp | 10
   branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp | 4
   branches/release/boost/interprocess/detail/managed_open_or_create_impl.hpp | 8
   branches/release/boost/interprocess/detail/math_functions.hpp | 220 ++++----
   branches/release/boost/interprocess/detail/move.hpp | 12
   branches/release/boost/interprocess/detail/named_proxy.hpp | 193 +++++--
   branches/release/boost/interprocess/detail/os_file_functions.hpp | 13
   branches/release/boost/interprocess/detail/segment_manager_helper.hpp | 30
   branches/release/boost/interprocess/detail/type_traits.hpp | 41 -
   branches/release/boost/interprocess/detail/utilities.hpp | 151 ++++-
   branches/release/boost/interprocess/detail/win32_api.hpp | 20
   branches/release/boost/interprocess/errors.hpp | 2
   branches/release/boost/interprocess/file_mapping.hpp | 2
   branches/release/boost/interprocess/interprocess_fwd.hpp | 5
   branches/release/boost/interprocess/ipc/message_queue.hpp | 36 +
   branches/release/boost/interprocess/mapped_region.hpp | 11
   branches/release/boost/interprocess/mem_algo/detail/mem_algo_common.hpp | 37
   branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp | 72 +-
   branches/release/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 75 +-
   branches/release/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 85 +-
   branches/release/boost/interprocess/offset_ptr.hpp | 16
   branches/release/boost/interprocess/segment_manager.hpp | 88 +-
   branches/release/boost/interprocess/shared_memory_object.hpp | 1
   branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp | 2
   branches/release/boost/interprocess/smart_ptr/weak_ptr.hpp | 2
   branches/release/boost/interprocess/sync/emulation/interprocess_condition.hpp | 16
   branches/release/boost/interprocess/sync/emulation/interprocess_mutex.hpp | 10
   branches/release/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp | 4
   branches/release/boost/interprocess/sync/emulation/interprocess_semaphore.hpp | 4
   branches/release/boost/interprocess/sync/file_lock.hpp | 8
   branches/release/boost/interprocess/sync/interprocess_condition.hpp | 12
   branches/release/boost/interprocess/sync/interprocess_mutex.hpp | 2
   branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 3
   branches/release/boost/interprocess/sync/interprocess_semaphore.hpp | 4
   branches/release/boost/interprocess/sync/interprocess_upgradable_mutex.hpp | 12
   branches/release/boost/interprocess/sync/lock_options.hpp | 2
   branches/release/boost/interprocess/sync/named_condition.hpp | 16
   branches/release/boost/interprocess/sync/named_mutex.hpp | 16
   branches/release/boost/interprocess/sync/named_recursive_mutex.hpp | 8
   branches/release/boost/interprocess/sync/named_semaphore.hpp | 16
   branches/release/boost/interprocess/sync/named_upgradable_mutex.hpp | 26
   branches/release/boost/interprocess/sync/posix/interprocess_mutex.hpp | 4
   branches/release/boost/interprocess/sync/posix/interprocess_recursive_mutex.hpp | 4
   branches/release/boost/interprocess/sync/posix/interprocess_semaphore.hpp | 8
   branches/release/boost/interprocess/sync/posix/semaphore_wrapper.hpp | 2
   branches/release/boost/interprocess/sync/sharable_lock.hpp | 2
   branches/release/boost/interprocess/sync/upgradable_lock.hpp | 4
   branches/release/boost/intrusive/any_hook.hpp | 46 +
   branches/release/boost/intrusive/avl_set.hpp | 114 +++-
   branches/release/boost/intrusive/avl_set_hook.hpp | 42 +
   branches/release/boost/intrusive/avltree.hpp | 98 ++-
   branches/release/boost/intrusive/avltree_algorithms.hpp | 16
   branches/release/boost/intrusive/bs_set_hook.hpp | 62 +-
   branches/release/boost/intrusive/circular_slist_algorithms.hpp | 4
   branches/release/boost/intrusive/detail/any_node_and_algorithms.hpp | 23
   branches/release/boost/intrusive/detail/assert.hpp | 18
   branches/release/boost/intrusive/detail/list_node.hpp | 3
   branches/release/boost/intrusive/detail/mpl.hpp | 172 ++++--
   branches/release/boost/intrusive/detail/slist_node.hpp | 3
   branches/release/boost/intrusive/detail/tree_algorithms.hpp | 4
   branches/release/boost/intrusive/hashtable.hpp | 892 +++++++++++++++++++++++++------------
   branches/release/boost/intrusive/intrusive_fwd.hpp | 152 +++++
   branches/release/boost/intrusive/linear_slist_algorithms.hpp | 4
   branches/release/boost/intrusive/list.hpp | 146 +++--
   branches/release/boost/intrusive/list_hook.hpp | 44 +
   branches/release/boost/intrusive/options.hpp | 214 ++++++++
   branches/release/boost/intrusive/pointer_plus_bits.hpp | 7
   branches/release/boost/intrusive/rbtree.hpp | 106 ++-
   branches/release/boost/intrusive/set.hpp | 116 +++-
   branches/release/boost/intrusive/set_hook.hpp | 44 +
   branches/release/boost/intrusive/sg_set.hpp | 116 +++-
   branches/release/boost/intrusive/sgtree.hpp | 96 ++-
   branches/release/boost/intrusive/sgtree_algorithms.hpp | 2
   branches/release/boost/intrusive/slist.hpp | 212 ++++----
   branches/release/boost/intrusive/slist_hook.hpp | 44 +
   branches/release/boost/intrusive/splay_set.hpp | 115 +++-
   branches/release/boost/intrusive/splay_set_hook.hpp | 44 +
   branches/release/boost/intrusive/splaytree.hpp | 109 ++-
   branches/release/boost/intrusive/splaytree_algorithms.hpp | 2
   branches/release/boost/intrusive/unordered_set.hpp | 154 +++++
   branches/release/boost/intrusive/unordered_set_hook.hpp | 44 +
   101 files changed, 5563 insertions(+), 2762 deletions(-)

Modified: branches/release/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- branches/release/boost/interprocess/allocators/allocator.hpp (original)
+++ branches/release/boost/interprocess/allocators/allocator.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -147,7 +147,7 @@
       (void)hint;
       if(count > this->max_size())
          throw bad_alloc();
- return pointer((value_type*)mp_mngr->allocate(count*sizeof(T)));
+ return pointer(static_cast<value_type*>(mp_mngr->allocate(count*sizeof(T))));
    }
 
    //!Deallocates memory previously allocated.

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -410,14 +410,14 @@
          (void)free_nodes;
          assert(free_nodes == mp_impl->m_real_num_node);
          assert(0 == to_deallocate->hdr_offset);
- hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block((block_info_t*)detail::get_pointer(to_deallocate));
+ hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(detail::get_pointer(to_deallocate));
          mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
       }
       const private_adaptive_node_pool_impl *mp_impl;
    };
 
    //This macro will activate invariant checking. Slow, but helpful for debugging the code.
- #define BOOST_INTERPROCESS_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+ //#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
@@ -463,10 +463,10 @@
       for(; it != itend; ++it){
          hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
          for(std::size_t i = 0, max = m_num_subblocks; i < max; ++i){
- assert(hdr_off_holder->hdr_offset == std::size_t((char*)&*it- (char*)hdr_off_holder));
+ assert(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
             assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
             assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
- hdr_off_holder = (hdr_offset_holder *)((char*)hdr_off_holder + m_real_block_alignment);
+ hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
          }
       }
       }
@@ -498,19 +498,20 @@
    block_info_t *priv_block_from_node(void *node) const
    {
       hdr_offset_holder *hdr_off_holder =
- (hdr_offset_holder*)((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
+ reinterpret_cast<hdr_offset_holder*>((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
       assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
       assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
- block_info_t *block = (block_info_t *)(((char*)hdr_off_holder) + hdr_off_holder->hdr_offset);
+ block_info_t *block = reinterpret_cast<block_info_t *>
+ (reinterpret_cast<char*>(hdr_off_holder) + hdr_off_holder->hdr_offset);
       assert(block->hdr_offset == 0);
       return block;
    }
 
    hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
    {
- hdr_offset_holder *hdr_off_holder = (hdr_offset_holder*)
- (((char*)block) - (m_num_subblocks-1)*m_real_block_alignment);
- assert(hdr_off_holder->hdr_offset == std::size_t((char*)block - (char*)hdr_off_holder));
+ hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
+ (reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
+ assert(hdr_off_holder->hdr_offset == std::size_t(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
       assert(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
       assert(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
       return hdr_off_holder;
@@ -526,7 +527,7 @@
       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
+ char *mem_address = static_cast<char*>
             (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
          if(!mem_address) throw std::bad_alloc();
          ++m_totally_free_blocks;

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -96,7 +96,7 @@
       if (m_freelist.empty())
          priv_alloc_block();
       //We take the first free node
- node_t *n = (node_t*)&m_freelist.front();
+ node_t *n = &m_freelist.front();
       m_freelist.pop_front();
       ++m_allocated;
       return n;
@@ -292,13 +292,13 @@
       : 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)
+ : beg_(static_cast<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);
+ return (beg_ <= reinterpret_cast<const char *>(&v) &&
+ end_ > reinterpret_cast<const char *>(&v));
       }
       private:
       const char * beg_;
@@ -312,7 +312,7 @@
       //element in the free Node list
       std::size_t blocksize =
          detail::get_rounded_size(m_real_node_size*m_nodes_per_block, alignment_of<node_t>::value);
- char *pNode = detail::char_ptr_cast
+ char *pNode = reinterpret_cast<char*>
          (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
       if(!pNode) throw bad_alloc();
       char *pBlock = pNode;
@@ -337,14 +337,13 @@
    //!Returns a reference to the block hook placed in the end of the block
    static inline node_t & get_block_hook (void *block, std::size_t blocksize)
    {
- return *static_cast<node_t*>(
- static_cast<void*>((detail::char_ptr_cast(block) + blocksize)));
+ return *reinterpret_cast<node_t*>(reinterpret_cast<char*>(block) + blocksize);
    }
 
    //!Returns the starting address of the block reference to the block hook placed in the end of the block
    inline void *get_block_from_hook (node_t *hook, std::size_t blocksize)
    {
- return static_cast<void*>((detail::char_ptr_cast(hook) - blocksize));
+ return (reinterpret_cast<char*>(hook) - blocksize);
    }
 
    private:

Modified: branches/release/boost/interprocess/anonymous_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/anonymous_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/anonymous_shared_memory.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -93,12 +93,12 @@
    #endif
 
 
- address = mmap( (void*)address
- , size
- , PROT_READ|PROT_WRITE
- , flags
- , fd
- , 0);
+ address = mmap( address
+ , size
+ , PROT_READ|PROT_WRITE
+ , flags
+ , fd
+ , 0);
 
    if(address == MAP_FAILED){
       if(fd != -1)

Modified: branches/release/boost/interprocess/containers/deque.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/deque.hpp (original)
+++ branches/release/boost/interprocess/containers/deque.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -57,16 +57,21 @@
 #include <boost/interprocess/detail/min_max.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
 #include <boost/interprocess/interprocess_fwd.hpp>
-#include <iterator>
 #include <cstddef>
 #include <iterator>
+#include <cassert>
 #include <memory>
 #include <algorithm>
 #include <stdexcept>
 #include <boost/detail/no_exceptions_support.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
 #include <boost/interprocess/detail/move_iterator.hpp>
 #include <boost/interprocess/detail/move.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/interprocess/detail/advanced_insert_int.hpp>
 
 namespace boost {
 namespace interprocess {
@@ -75,6 +80,21 @@
 template <class T, class Alloc>
 class deque;
 
+template <class T, class A>
+struct deque_value_traits
+{
+ typedef T value_type;
+ typedef A allocator_type;
+ static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr_after_move =
+ has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_copy = has_trivial_copy<value_type>::value;
+ static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
+ static const bool trivial_assign = has_trivial_assign<value_type>::value;
+ static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
+
+};
+
 // Note: this function is simply a kludge to work around several compilers'
 // bugs in handling constant expressions.
 inline std::size_t deque_buf_size(std::size_t size)
@@ -105,16 +125,18 @@
    typedef allocator_type stored_allocator_type;
 
    protected:
- enum { trivial_dctr_after_move = boost::has_trivial_destructor<val_alloc_val>::value };
 
+ typedef deque_value_traits<T, Alloc> traits_t;
    typedef typename Alloc::template
       rebind<typename Alloc::pointer>::other map_allocator_type;
 
+ static std::size_t s_buffer_size() { return deque_buf_size(sizeof(T)); }
+
    val_alloc_ptr priv_allocate_node()
- { return this->alloc().allocate(deque_buf_size(sizeof(T))); }
+ { return this->alloc().allocate(s_buffer_size()); }
 
    void priv_deallocate_node(val_alloc_ptr p)
- { this->alloc().deallocate(p, deque_buf_size(sizeof(T))); }
+ { this->alloc().deallocate(p, s_buffer_size()); }
 
    ptr_alloc_ptr priv_allocate_map(std::size_t n)
       { return this->ptr_alloc().allocate(n); }
@@ -153,7 +175,7 @@
                               val_alloc_cptr, val_alloc_cref>
    {
       public:
- static std::size_t s_buffer_size() { return deque_buf_size(sizeof(T)); }
+ static std::size_t s_buffer_size() { return deque_base<T, Alloc>::s_buffer_size(); }
 
       typedef std::random_access_iterator_tag iterator_category;
       typedef val_alloc_val value_type;
@@ -297,7 +319,7 @@
       public:
       typedef std::random_access_iterator_tag iterator_category;
       typedef val_alloc_val value_type;
- typedef ptr_alloc_ptr pointer;
+ typedef val_alloc_ptr pointer;
       typedef val_alloc_ref reference;
       typedef std::size_t size_type;
       typedef std::ptrdiff_t difference_type;
@@ -371,34 +393,40 @@
          this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
       }
    }
+
+ private:
+ deque_base(const deque_base&);
   
    protected:
+
    void priv_initialize_map(std::size_t num_elements)
    {
- std::size_t num_nodes = num_elements / deque_buf_size(sizeof(T)) + 1;
+// if(num_elements){
+ std::size_t num_nodes = num_elements / s_buffer_size() + 1;
 
- this->members_.m_map_size = max_value((std::size_t) InitialMapSize, num_nodes + 2);
- this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
+ this->members_.m_map_size = max_value((std::size_t) InitialMapSize, num_nodes + 2);
+ this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
 
- ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
- ptr_alloc_ptr nfinish = nstart + num_nodes;
-
- BOOST_TRY {
- this->priv_create_nodes(nstart, nfinish);
- }
- BOOST_CATCH(...){
- this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
- this->members_.m_map = 0;
- this->members_.m_map_size = 0;
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
+ ptr_alloc_ptr nfinish = nstart + num_nodes;
+
+ BOOST_TRY {
+ this->priv_create_nodes(nstart, nfinish);
+ }
+ BOOST_CATCH(...){
+ this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+ this->members_.m_map = 0;
+ this->members_.m_map_size = 0;
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
 
- this->members_.m_start.priv_set_node(nstart);
- this->members_.m_finish.priv_set_node(nfinish - 1);
- this->members_.m_start.m_cur = this->members_.m_start.m_first;
- this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
- num_elements % deque_buf_size(sizeof(T));
+ this->members_.m_start.priv_set_node(nstart);
+ this->members_.m_finish.priv_set_node(nfinish - 1);
+ this->members_.m_start.m_cur = this->members_.m_start.m_first;
+ this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
+ num_elements % s_buffer_size();
+// }
    }
 
    void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
@@ -495,10 +523,14 @@
    typedef std::reverse_iterator<iterator> reverse_iterator;
 
    /// @cond
- protected: // Internal typedefs
+ private: // Internal typedefs
    typedef ptr_alloc_ptr index_pointer;
    static std::size_t s_buffer_size()
- { return deque_buf_size(sizeof(T)); }
+ { return Base::s_buffer_size(); }
+ typedef detail::advanced_insert_aux_int<value_type, iterator> advanced_insert_aux_int_t;
+ typedef repeat_iterator<T, difference_type> r_iterator;
+ typedef detail::move_iterator<r_iterator> move_it;
+
    /// @endcond
 
    allocator_type get_allocator() const { return Base::alloc(); }
@@ -528,6 +560,18 @@
    const_reverse_iterator rend() const
       { return const_reverse_iterator(this->members_.m_start); }
 
+ const_iterator cbegin() const
+ { return this->members_.m_start; }
+
+ const_iterator cend() const
+ { return this->members_.m_finish; }
+
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->members_.m_finish); }
+
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->members_.m_start); }
+
    reference operator[](size_type n)
       { return this->members_.m_start[difference_type(n)]; }
 
@@ -545,18 +589,12 @@
 
    reference front() { return *this->members_.m_start; }
 
- reference back()
- {
- iterator tmp = this->members_.m_finish;
- --tmp;
- return *tmp;
- }
+ reference back() { return *(end()-1); }
 
    const_reference front() const
       { return *this->members_.m_start; }
 
- const_reference back() const
- { const_iterator tmp = this->members_.m_finish; --tmp; return *tmp; }
+ const_reference back() const { return *(cend()-1); }
 
    size_type size() const
       { return this->members_.m_finish - this->members_.m_start; }
@@ -565,10 +603,11 @@
       { return this->alloc().max_size(); }
 
    bool empty() const
- { return this->members_.m_finish == this->members_.m_start; }
+ { return this->members_.m_finish == this->members_.m_start; }
 
    explicit deque(const allocator_type& a = allocator_type())
- : Base(a, 0) {}
+ : Base(a)
+ {}
 
    deque(const deque& x)
       : Base(x.alloc(), x.size())
@@ -576,11 +615,11 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    deque(const detail::moved_object<deque> &mx)
- : Base(mx.get())
+ : Base(mx.get().alloc())
    { this->swap(mx.get()); }
    #else
    deque(deque &&x)
- : Base(detail::move_impl(x))
+ : Base(x.alloc())
    { this->swap(x); }
    #endif
 
@@ -593,8 +632,8 @@
 
    // Check whether it's an integral type. If so, it's not an iterator.
    template <class InpIt>
- deque(InpIt first, InpIt last,
- const allocator_type& a = allocator_type()) : Base(a)
+ deque(InpIt first, InpIt last, const allocator_type& a = allocator_type())
+ : Base(a)
    {
       //Dispatch depending on integer/iterator
       const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
@@ -603,7 +642,9 @@
    }
 
    ~deque()
- { priv_destroy_range(this->members_.m_start, this->members_.m_finish); }
+ {
+ priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+ }
 
    deque& operator= (const deque& x)
    {
@@ -622,13 +663,22 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    deque& operator= (const detail::moved_object<deque> &mx)
- { this->clear(); this->swap(mx.get()); return *this; }
+ {
+ deque &x = mx.get();
    #else
- deque& operator= (deque &&mx)
- { this->clear(); this->swap(mx); return *this; }
+ deque& operator= (deque &&x)
+ {
    #endif
+ this->clear();
+ this->swap(x);
+ return *this;
+ }
 
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void swap(deque& x)
+ #else
+ void swap(deque &&x)
+ #endif
    {
       std::swap(this->members_.m_start, x.members_.m_start);
       std::swap(this->members_.m_finish, x.members_.m_finish);
@@ -639,16 +689,14 @@
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void swap(const detail::moved_object<deque> &mx)
    { this->swap(mx.get()); }
- #else
- void swap(deque &&mx)
- { this->swap(mx); }
    #endif
 
    void assign(size_type n, const T& val)
    { this->priv_fill_assign(n, val); }
 
    template <class InpIt>
- void assign(InpIt first, InpIt last) {
+ void assign(InpIt first, InpIt last)
+ {
       //Dispatch depending on integer/iterator
       const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
       typedef detail::bool_<aux_boolean> Result;
@@ -657,67 +705,59 @@
 
    void push_back(const value_type& t)
    {
- if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
- new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
- ++this->members_.m_finish.m_cur;
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(t);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), size_type(1), t);
       }
- else
- this->priv_push_back_aux(t);
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void push_back(const detail::moved_object<value_type> &mt)
    {
- if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
- new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
- ++this->members_.m_finish.m_cur;
- }
- else
- this->priv_push_back_aux(mt);
- }
+ value_type &t = mt.get();
    #else
- void push_back(value_type &&mt)
+ void push_back(value_type &&t)
    {
- if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
- new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(detail::move_impl(mt));
- ++this->members_.m_finish.m_cur;
+ #endif
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(detail::move_impl(t));
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
       }
- else
- this->priv_push_back_aux(detail::move_impl(mt));
    }
- #endif
 
    void push_front(const value_type& t)
    {
- if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
- new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(t);
- --this->members_.m_start.m_cur;
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(t);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), size_type(1), t);
       }
- else
- this->priv_push_front_aux(t);
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void push_front(const detail::moved_object<value_type> &mt)
    {
- if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
- new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(mt);
- --this->members_.m_start.m_cur;
- }
- else
- this->priv_push_front_aux(mt);
- }
+ value_type &t = mt.get();
    #else
- void push_front(value_type &&mt)
+ void push_front(value_type &&t)
    {
- if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
- new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(detail::move_impl(mt));
- --this->members_.m_start.m_cur;
+ #endif
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(detail::move_impl(t));
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ this->priv_insert_aux(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
       }
- else
- this->priv_push_front_aux(detail::move_impl(mt));
    }
- #endif
 
    void pop_back()
    {
@@ -739,65 +779,53 @@
          this->priv_pop_front_aux();
    }
 
- iterator insert(iterator position, const value_type& x)
+ iterator insert(const_iterator position, const value_type& x)
    {
- if (position.m_cur == this->members_.m_start.m_cur) {
+ if (position == cbegin()){
          this->push_front(x);
- return this->members_.m_start;
+ return begin();
       }
- else if (position.m_cur == this->members_.m_finish.m_cur) {
+ else if (position == cend()){
          this->push_back(x);
- iterator tmp = this->members_.m_finish;
- --tmp;
- return tmp;
+ return (end()-1);
       }
       else {
- return this->priv_insert_aux(position, x);
+ size_type n = position - cbegin();
+ this->priv_insert_aux(position, size_type(1), x);
+ return iterator(this->begin() + n);
       }
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<value_type> &mx)
+ iterator insert(const_iterator position, const detail::moved_object<value_type> &m)
    {
- if (position.m_cur == this->members_.m_start.m_cur) {
- this->push_front(mx);
- return this->members_.m_start;
- }
- else if (position.m_cur == this->members_.m_finish.m_cur) {
- this->push_back(mx);
- iterator tmp = this->members_.m_finish;
- --tmp;
- return tmp;
- }
- else {
- return this->priv_insert_aux(position, mx);
- }
- }
+ value_type &mx = m.get();
    #else
- iterator insert(iterator position, value_type &&mx)
+ iterator insert(const_iterator position, value_type &&mx)
    {
- if (position.m_cur == this->members_.m_start.m_cur) {
+ #endif
+ if (position == cbegin()) {
          this->push_front(detail::move_impl(mx));
- return this->members_.m_start;
+ return begin();
       }
- else if (position.m_cur == this->members_.m_finish.m_cur) {
+ else if (position == cend()) {
          this->push_back(detail::move_impl(mx));
- iterator tmp = this->members_.m_finish;
- --tmp;
- return tmp;
+ return(end()-1);
       }
       else {
- return this->priv_insert_aux(position, detail::move_impl(mx));
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type n = position - begin();
+ this->priv_insert_aux(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
+ return iterator(this->begin() + n);
       }
    }
- #endif
 
- void insert(iterator pos, size_type n, const value_type& x)
- { this->priv_fill_insert(pos, n, x); }
+ void insert(const_iterator pos, size_type n, const value_type& x)
+ { this->priv_fill_insert(pos, n, x); }
 
    // Check whether it's an integral type. If so, it's not an iterator.
    template <class InpIt>
- void insert(iterator pos, InpIt first, InpIt last)
+ void insert(const_iterator pos, InpIt first, InpIt last)
    {
       //Dispatch depending on integer/iterator
       const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
@@ -805,6 +833,158 @@
       this->priv_insert_dispatch(pos, first, last, Result());
    }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ {
+ if(this->priv_push_back_simple_available()){
+ new(this->priv_push_back_simple_pos())value_type(detail::forward_impl<Args>(args)...);
+ this->priv_push_back_simple_commit();
+ }
+ else{
+ detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(detail::forward_impl<Args>(args)...);
+ this->priv_insert_aux_impl(this->cend(), 1, proxy);
+ }
+ }
+
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ {
+ if(this->priv_push_front_simple_available()){
+ new(this->priv_push_front_simple_pos())value_type(detail::forward_impl<Args>(args)...);
+ this->priv_push_front_simple_commit();
+ }
+ else{
+ detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(detail::forward_impl<Args>(args)...);
+ this->priv_insert_aux_impl(this->cbegin(), 1, proxy);
+ }
+ }
+
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ {
+ if(p == this->cbegin()){
+ this->emplace_front(detail::forward_impl<Args>(args)...);
+ return this->begin();
+ }
+ else if(p == this->cend()){
+ this->emplace_back(detail::forward_impl<Args>(args)...);
+ return (this->end()-1);
+ }
+ else{
+ size_type n = p - this->cbegin();
+ detail::advanced_insert_aux_emplace<T, iterator, Args...> proxy(detail::forward_impl<Args>(args)...);
+ this->priv_insert_aux_impl(p, 1, proxy);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_back()
+ {
+ if(priv_push_front_simple_available()){
+ new(priv_push_front_simple_pos())value_type();
+ priv_push_front_simple_commit();
+ }
+ else{
+ detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(cend(), 1, proxy);
+ }
+ }
+
+ void emplace_front()
+ {
+ if(priv_push_front_simple_available()){
+ new(priv_push_front_simple_pos())value_type();
+ priv_push_front_simple_commit();
+ }
+ else{
+ detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(cbegin(), 1, proxy);
+ }
+ }
+
+ iterator emplace(const_iterator p)
+ {
+ if(p == cbegin()){
+ emplace_front();
+ return begin();
+ }
+ else if(p == cend()){
+ emplace_back();
+ return (end()-1);
+ }
+ else{
+ size_type n = p - cbegin();
+ detail::advanced_insert_aux_emplace<T, iterator> proxy;
+ priv_insert_aux_impl(p, 1, proxy);
+ return iterator(this->begin() + n);
+ }
+ }
+
+ //advanced_insert_int.hpp includes all necessary preprocessor machinery...
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ if(priv_push_back_simple_available()){ \
+ new(priv_push_back_simple_pos())value_type \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ priv_push_back_simple_commit(); \
+ } \
+ else{ \
+ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ priv_insert_aux_impl(cend(), 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ if(priv_push_front_simple_available()){ \
+ new(priv_push_front_simple_pos())value_type \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ priv_push_front_simple_commit(); \
+ } \
+ else{ \
+ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ priv_insert_aux_impl(cbegin(), 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ if(p == this->cbegin()){ \
+ this->emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ return this->begin(); \
+ } \
+ else if(p == cend()){ \
+ this->emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ return (this->end()-1); \
+ } \
+ else{ \
+ size_type pos_num = p - this->cbegin(); \
+ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ this->priv_insert_aux_impl(p, 1, proxy); \
+ return iterator(this->begin() + pos_num); \
+ } \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    void resize(size_type new_size, const value_type& x)
    {
       const size_type len = size();
@@ -821,41 +1001,32 @@
          this->erase(this->members_.m_start + new_size, this->members_.m_finish);
       else{
          size_type n = new_size - this->size();
- this->priv_reserve_elements_at_back(new_size);
-
- while(n--){
- //T default_constructed = detail::move_impl(T());
- T default_constructed;
-/* if(boost::is_scalar<T>::value){
- //Value initialization
- new(&default_constructed)T();
- }*/
- this->push_back(detail::move_impl(default_constructed));
- }
+ detail::default_construct_aux_proxy<T, iterator, size_type> proxy(n);
+ priv_insert_aux_impl(this->cend(), n, proxy);
       }
    }
 
- iterator erase(iterator pos)
+ iterator erase(const_iterator pos)
    {
- iterator next = pos;
+ const_iterator next = pos;
       ++next;
       difference_type index = pos - this->members_.m_start;
       if (size_type(index) < (this->size() >> 1)) {
- std::copy_backward( detail::make_move_iterator(this->members_.m_start)
- , detail::make_move_iterator(pos)
- , next);
+ std::copy_backward( detail::make_move_iterator(begin())
+ , detail::make_move_iterator(iterator(pos))
+ , iterator(next));
          pop_front();
       }
       else {
- std::copy( detail::make_move_iterator(next)
- , detail::make_move_iterator(this->members_.m_finish)
- , pos);
+ std::copy( detail::make_move_iterator(iterator(next))
+ , detail::make_move_iterator(end())
+ , iterator(pos));
          pop_back();
       }
       return this->members_.m_start + index;
    }
 
- iterator erase(iterator first, iterator last)
+ iterator erase(const_iterator first, const_iterator last)
    {
       if (first == this->members_.m_start && last == this->members_.m_finish) {
          this->clear();
@@ -865,21 +1036,21 @@
          difference_type n = last - first;
          difference_type elems_before = first - this->members_.m_start;
          if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
- std::copy_backward( detail::make_move_iterator(this->members_.m_start)
- , detail::make_move_iterator(first)
- , last);
+ std::copy_backward( detail::make_move_iterator(begin())
+ , detail::make_move_iterator(iterator(first))
+ , iterator(last));
             iterator new_start = this->members_.m_start + n;
- if(!Base::trivial_dctr_after_move)
+ if(!Base::traits_t::trivial_dctr_after_move)
                this->priv_destroy_range(this->members_.m_start, new_start);
             this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
             this->members_.m_start = new_start;
          }
          else {
- std::copy( detail::make_move_iterator(last)
- , detail::make_move_iterator(this->members_.m_finish)
- , first);
+ std::copy( detail::make_move_iterator(iterator(last))
+ , detail::make_move_iterator(end())
+ , iterator(first));
             iterator new_finish = this->members_.m_finish - n;
- if(!Base::trivial_dctr_after_move)
+ if(!Base::traits_t::trivial_dctr_after_move)
                this->priv_destroy_range(new_finish, this->members_.m_finish);
             this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
             this->members_.m_finish = new_finish;
@@ -911,56 +1082,58 @@
    /// @cond
    private:
 
- template <class InpIt>
- void insert(iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
- { std::copy(first, last, std::inserter(*this, pos)); }
+ bool priv_push_back_simple_available() const
+ {
+ return this->members_.m_map &&
+ (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
+ }
 
- template <class FwdIt>
- void insert(iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ void *priv_push_back_simple_pos() const
    {
-
- size_type n = 0;
- n = std::distance(first, last);
+ return static_cast<void*>(detail::get_pointer(this->members_.m_finish.m_cur));
+ }
 
- if (pos.m_cur == this->members_.m_start.m_cur) {
- iterator new_start = this->priv_reserve_elements_at_front(n);
- BOOST_TRY{
- std::uninitialized_copy(first, last, new_start);
- this->members_.m_start = new_start;
- }
- BOOST_CATCH(...){
- this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- else if (pos.m_cur == this->members_.m_finish.m_cur) {
- iterator new_finish = this->priv_reserve_elements_at_back(n);
- BOOST_TRY{
- std::uninitialized_copy(first, last, this->members_.m_finish);
- this->members_.m_finish = new_finish;
- }
- BOOST_CATCH(...){
- this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ void priv_push_back_simple_commit()
+ {
+ ++this->members_.m_finish.m_cur;
+ }
+
+ bool priv_push_front_simple_available() const
+ {
+ return this->members_.m_map &&
+ (this->members_.m_start.m_cur != this->members_.m_start.m_first);
+ }
+
+ void *priv_push_front_simple_pos() const
+ { return static_cast<void*>(detail::get_pointer(this->members_.m_start.m_cur) - 1); }
+
+ void priv_push_front_simple_commit()
+ { --this->members_.m_start.m_cur; }
+
+ template <class InpIt>
+ void priv_insert_aux(const_iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
+ {
+ for(;first != last; ++first){
+ this->insert(pos, move_impl(value_type(*first)));
       }
- else
- this->priv_insert_aux(pos, first, last, n);
    }
 
+ template <class FwdIt>
+ void priv_insert_aux(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+ { this->priv_insert_aux(pos, first, last); }
+
   // assign(), a generalized assignment member function. Two
   // versions: one that takes a count, and one that takes a range.
   // The range version is a member template, so we dispatch on whether
   // or not the type is an integer.
- void priv_fill_assign(size_type n, const T& val) {
+ void priv_fill_assign(size_type n, const T& val)
+ {
       if (n > size()) {
          std::fill(begin(), end(), val);
- this->insert(end(), n - size(), val);
+ this->insert(cend(), n - size(), val);
       }
       else {
- this->erase(begin() + n, end());
+ this->erase(cbegin() + n, cend());
          std::fill(begin(), end(), val);
       }
    }
@@ -1009,112 +1182,80 @@
       for ( ; first != last && cur != end(); ++cur, ++first)
          *cur = *first;
       if (first == last)
- this->erase(cur, end());
+ this->erase(cur, cend());
       else
- this->insert(end(), first, last);
+ this->insert(cend(), first, last);
    }
 
    template <class FwdIt>
- void priv_assign_aux(FwdIt first, FwdIt last,
- std::forward_iterator_tag) {
- size_type len = 0;
- std::distance(first, last, len);
+ void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ {
+ size_type len = std::distance(first, last);
       if (len > size()) {
          FwdIt mid = first;
          std::advance(mid, size());
          std::copy(first, mid, begin());
- this->insert(end(), mid, last);
+ this->insert(cend(), mid, last);
       }
       else
- this->erase(std::copy(first, last, begin()), end());
+ this->erase(std::copy(first, last, begin()), cend());
    }
 
    template <class Integer>
- void priv_insert_dispatch(iterator pos, Integer n, Integer x,
- detail::true_)
- {
- this->priv_fill_insert(pos, (size_type) n, (value_type) x);
- }
+ void priv_insert_dispatch(const_iterator pos, Integer n, Integer x, detail::true_)
+ { this->priv_fill_insert(pos, (size_type) n, (value_type) x); }
 
    template <class InpIt>
- void priv_insert_dispatch(iterator pos,
- InpIt first, InpIt last,
- detail::false_)
+ void priv_insert_dispatch(const_iterator pos,InpIt first, InpIt last, detail::false_)
    {
       typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->insert(pos, first, last, ItCat());
+ this->priv_insert_aux(pos, first, last, ItCat());
    }
 
- iterator priv_insert_aux(iterator pos, const value_type& x)
+ void priv_insert_aux(const_iterator pos, size_type n, const value_type& x)
    {
- size_type n = pos - begin();
- this->priv_insert_aux(pos, size_type(1), x);
- return iterator(this->begin() + n);
+ typedef constant_iterator<value_type, difference_type> c_it;
+ this->priv_insert_aux(pos, c_it(x, n), c_it());
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator priv_insert_aux(iterator pos, const detail::moved_object<value_type> &mx)
- {
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef detail::move_iterator<r_iterator> move_it;
- //Just call more general insert(pos, size, value) and return iterator
- size_type n = pos - begin();
- this->insert(pos
- ,move_it(r_iterator(mx.get(), 1))
- ,move_it(r_iterator()));
- return iterator(this->begin() + n);
- }
- #else
- iterator priv_insert_aux(iterator pos, value_type &&mx)
+ //Just forward all operations to priv_insert_aux_impl
+ template <class FwdIt>
+ void priv_insert_aux(const_iterator p, FwdIt first, FwdIt last)
    {
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef detail::move_iterator<r_iterator> move_it;
- //Just call more general insert(pos, size, value) and return iterator
- size_type n = pos - begin();
- this->insert(pos
- ,move_it(r_iterator(mx, 1))
- ,move_it(r_iterator()));
- return iterator(this->begin() + n);
+ detail::advanced_insert_aux_proxy<T, FwdIt, iterator> proxy(first, last);
+ priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
    }
- #endif
 
- void priv_insert_aux(iterator pos, size_type n, const value_type& x)
+ void priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
    {
- typedef constant_iterator<value_type, difference_type> c_it;
- this->insert(pos, c_it(x, n), c_it());
- }
+ iterator pos(p);
+ if(!this->members_.m_map){
+ this->priv_initialize_map(0);
+ pos = this->begin();
+ }
 
- template <class FwdIt>
- void priv_insert_aux(iterator pos, FwdIt first, FwdIt last, size_type n)
- {
       const difference_type elemsbefore = pos - this->members_.m_start;
- size_type length = size();
+ size_type length = this->size();
       if (elemsbefore < static_cast<difference_type>(length / 2)) {
          iterator new_start = this->priv_reserve_elements_at_front(n);
          iterator old_start = this->members_.m_start;
          pos = this->members_.m_start + elemsbefore;
- BOOST_TRY {
- if (elemsbefore >= difference_type(n)) {
- iterator start_n = this->members_.m_start + difference_type(n);
- std::uninitialized_copy(detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(start_n), new_start);
- this->members_.m_start = new_start;
- std::copy(detail::make_move_iterator(start_n), detail::make_move_iterator(pos), old_start);
- std::copy(first, last, pos - difference_type(n));
- }
- else {
- FwdIt mid = first;
- std::advance(mid, difference_type(n) - elemsbefore);
- this->priv_uninitialized_copy_copy
- (detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(pos), first, mid, new_start);
- this->members_.m_start = new_start;
- std::copy(mid, last, old_start);
- }
+ if (elemsbefore >= difference_type(n)) {
+ iterator start_n = this->members_.m_start + difference_type(n);
+ std::uninitialized_copy(detail::make_move_iterator(this->members_.m_start), detail::make_move_iterator(start_n), new_start);
+ this->members_.m_start = new_start;
+ std::copy(detail::make_move_iterator(start_n), detail::make_move_iterator(pos), old_start);
+ interf.copy_all_to(pos - difference_type(n));
          }
- BOOST_CATCH(...){
- this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
- BOOST_RETHROW
+ else {
+ difference_type mid_count = (difference_type(n) - elemsbefore);
+ iterator mid_start = old_start - mid_count;
+ interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
+ this->members_.m_start = mid_start;
+ std::uninitialized_copy(detail::make_move_iterator(old_start), detail::make_move_iterator(pos), new_start);
+ this->members_.m_start = new_start;
+ interf.copy_all_to(old_start);
          }
- BOOST_CATCH_END
       }
       else {
          iterator new_finish = this->priv_reserve_elements_at_back(n);
@@ -1122,31 +1263,24 @@
          const difference_type elemsafter =
             difference_type(length) - elemsbefore;
          pos = this->members_.m_finish - elemsafter;
- BOOST_TRY {
- if (elemsafter > difference_type(n)) {
- iterator finish_n = this->members_.m_finish - difference_type(n);
- std::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish);
- this->members_.m_finish = new_finish;
- std::copy_backward(detail::make_move_iterator(pos), detail::make_move_iterator(finish_n), old_finish);
- std::copy(first, last, pos);
- }
- else {
- FwdIt mid = first;
- std::advance(mid, elemsafter);
- this->priv_uninitialized_copy_copy(mid, last, detail::make_move_iterator(pos), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish);
- this->members_.m_finish = new_finish;
- std::copy(first, mid, pos);
- }
+ if (elemsafter >= difference_type(n)) {
+ iterator finish_n = this->members_.m_finish - difference_type(n);
+ std::uninitialized_copy(detail::make_move_iterator(finish_n), detail::make_move_iterator(this->members_.m_finish), this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ std::copy_backward(detail::make_move_iterator(pos), detail::make_move_iterator(finish_n), old_finish);
+ interf.copy_all_to(pos);
          }
- BOOST_CATCH(...){
- this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
- BOOST_RETHROW
+ else {
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_finish += n-elemsafter;
+ std::uninitialized_copy(detail::make_move_iterator(pos), detail::make_move_iterator(old_finish), this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ interf.copy_all_to(pos);
          }
- BOOST_CATCH_END
       }
    }
 
- void priv_fill_insert(iterator pos, size_type n, const value_type& x)
+ void priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
    {
       typedef constant_iterator<value_type, difference_type> c_it;
       this->insert(pos, c_it(x, n), c_it());
@@ -1211,112 +1345,6 @@
       BOOST_CATCH_END
    }
 
- // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_last - 1.
- void priv_push_back_aux(const value_type& t = value_type())
- {
- this->priv_reserve_map_at_back();
- *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
- BOOST_TRY {
- new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
- this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
- this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
- }
- BOOST_CATCH(...){
- this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_last - 1.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void priv_push_back_aux(const detail::moved_object<value_type> &mt)
- {
- this->priv_reserve_map_at_back();
- *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
- BOOST_TRY {
- new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
- this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
- this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
- }
- BOOST_CATCH(...){
- this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- #else
- void priv_push_back_aux(value_type &&mt)
- {
- this->priv_reserve_map_at_back();
- *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
- BOOST_TRY {
- new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(detail::move_impl(mt));
- this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
- this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
- }
- BOOST_CATCH(...){
- this->priv_deallocate_node(*(this->members_.m_finish.m_node + 1));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- #endif
-
- // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_first.
- void priv_push_front_aux(const value_type& t)
- {
- this->priv_reserve_map_at_front();
- *(this->members_.m_start.m_node - 1) = this->priv_allocate_node();
- BOOST_TRY {
- this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
- this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
- new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(t);
- }
- BOOST_CATCH(...){
- ++this->members_.m_start;
- this->priv_deallocate_node(*(this->members_.m_start.m_node - 1));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void priv_push_front_aux(const detail::moved_object<value_type> &mt)
- {
- this->priv_reserve_map_at_front();
- *(this->members_.m_start.m_node - 1) = this->priv_allocate_node();
- BOOST_TRY {
- this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
- this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
- new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(mt);
- }
- BOOST_CATCH(...){
- ++this->members_.m_start;
- this->priv_deallocate_node(*(this->members_.m_start.m_node - 1));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- #else
- void priv_push_front_aux(value_type &&mt)
- {
- this->priv_reserve_map_at_front();
- *(this->members_.m_start.m_node - 1) = this->priv_allocate_node();
- BOOST_TRY {
- this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
- this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
- new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(detail::move_impl(mt));
- }
- BOOST_CATCH(...){
- ++this->members_.m_start;
- this->priv_deallocate_node(*(this->members_.m_start.m_node - 1));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
- #endif
-
    // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
    void priv_pop_back_aux()
    {
@@ -1341,68 +1369,52 @@
    iterator priv_reserve_elements_at_front(size_type n)
    {
       size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
- if (n > vacancies)
- this->priv_new_elements_at_front(n - vacancies);
+ if (n > vacancies){
+ size_type new_elems = n-vacancies;
+ size_type new_nodes = (new_elems + this->s_buffer_size() - 1) /
+ this->s_buffer_size();
+ size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
+ if (new_nodes > s){
+ this->priv_reallocate_map(new_nodes, true);
+ }
+ size_type i = 1;
+ BOOST_TRY {
+ for (; i <= new_nodes; ++i)
+ *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...) {
+ for (size_type j = 1; j < i; ++j)
+ this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ }
       return this->members_.m_start - difference_type(n);
    }
 
    iterator priv_reserve_elements_at_back(size_type n)
    {
       size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
- if (n > vacancies)
- this->priv_new_elements_at_back(n - vacancies);
- return this->members_.m_finish + difference_type(n);
- }
-
- void priv_new_elements_at_front(size_type new_elems)
- {
- 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 = 1;
- BOOST_TRY {
- for (; i <= new_nodes; ++i)
- *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
- }
- BOOST_CATCH(...) {
- for (size_type j = 1; j < i; ++j)
- this->priv_deallocate_node(*(this->members_.m_start.m_node - j));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- void priv_new_elements_at_back(size_type new_elems)
- {
- size_type new_nodes = (new_elems + this->s_buffer_size() - 1)
- / this->s_buffer_size();
- this->priv_reserve_map_at_back(new_nodes);
- size_type i;
- BOOST_TRY {
- for (i = 1; i <= new_nodes; ++i)
- *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
- }
- BOOST_CATCH(...) {
- for (size_type j = 1; j < i; ++j)
- this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
- BOOST_RETHROW
+ if (n > vacancies){
+ size_type new_elems = n - vacancies;
+ size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
+ size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
+ if (new_nodes + 1 > s){
+ this->priv_reallocate_map(new_nodes, false);
+ }
+ size_type i;
+ BOOST_TRY {
+ for (i = 1; i <= new_nodes; ++i)
+ *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
+ }
+ BOOST_CATCH(...) {
+ for (size_type j = 1; j < i; ++j)
+ this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
       }
- BOOST_CATCH_END
- }
-
- // Makes sure the this->members_.m_map has space for new nodes. Does not actually
- // add the nodes. Can invalidate this->members_.m_map pointers. (And consequently,
- // deque iterators.)
- void priv_reserve_map_at_back (size_type nodes_to_add = 1)
- {
- if (nodes_to_add + 1 > this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map))
- this->priv_reallocate_map(nodes_to_add, false);
- }
-
- void priv_reserve_map_at_front (size_type nodes_to_add = 1)
- {
- if (nodes_to_add > size_type(this->members_.m_start.m_node - this->members_.m_map))
- this->priv_reallocate_map(nodes_to_add, true);
+ return this->members_.m_finish + difference_type(n);
    }
 
    void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
@@ -1437,68 +1449,6 @@
       this->members_.m_start.priv_set_node(new_nstart);
       this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
    }
-
- // this->priv_uninitialized_copy_fill
- // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
- // fills [first2 + (last1 - first1), last2) with x.
- void priv_uninitialized_copy_fill(iterator first1, iterator last1,
- iterator first2, iterator last2,
- const T& x)
- {
- iterator mid2 = std::uninitialized_copy(first1, last1, first2);
- BOOST_TRY {
- std::uninitialized_fill(mid2, last2, x);
- }
- BOOST_CATCH(...){
- for(;first2 != mid2; ++first2){
- detail::get_pointer(&*first2)->~value_type();
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- // this->priv_uninitialized_fill_copy
- // Fills [result, mid) with x, and copies [first, last) into
- // [mid, mid + (last - first)).
- iterator priv_uninitialized_fill_copy(iterator result, iterator mid,
- const T& x,
- iterator first, iterator last)
- {
- std::uninitialized_fill(result, mid, x);
- BOOST_TRY {
- return std::uninitialized_copy(first, last, mid);
- }
- BOOST_CATCH(...){
- for(;result != mid; ++result){
- detail::get_pointer(&*result)->~value_type();
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
-
- // this->priv_uninitialized_copy_copy
- // Copies [first1, last1) into [result, result + (last1 - first1)), and
- // copies [first2, last2) into
- // [result, result + (last1 - first1) + (last2 - first2)).
- template <class InpIt1, class InpIt2, class FwdIt>
- FwdIt priv_uninitialized_copy_copy(InpIt1 first1, InpIt1 last1,
- InpIt2 first2, InpIt2 last2,
- FwdIt result)
- {
- FwdIt mid = std::uninitialized_copy(first1, last1, result);
- BOOST_TRY {
- return std::uninitialized_copy(first2, last2, mid);
- }
- BOOST_CATCH(...){
- for(;result != mid; ++result){
- detail::get_pointer(&*result)->~value_type();
- }
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
    /// @endcond
 };
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -175,25 +175,37 @@
    { return this->m_data.m_vect.begin(); }
 
    const_iterator begin() const
+ { return this->cbegin(); }
+
+ const_iterator cbegin() const
    { return this->m_data.m_vect.begin(); }
 
    iterator end()
    { return this->m_data.m_vect.end(); }
 
    const_iterator end() const
+ { return this->cend(); }
+
+ const_iterator cend() const
    { return this->m_data.m_vect.end(); }
 
    reverse_iterator rbegin()
    { return reverse_iterator(this->end()); }
 
    const_reverse_iterator rbegin() const
- { return const_reverse_iterator(this->end()); }
+ { return this->crbegin(); }
+
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->cend()); }
 
    reverse_iterator rend()
    { return reverse_iterator(this->begin()); }
 
    const_reverse_iterator rend() const
- { return const_reverse_iterator(this->begin()); }
+ { return this->crend(); }
+
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->cbegin()); }
 
    bool empty() const
    { return this->m_data.m_vect.empty(); }
@@ -237,24 +249,18 @@
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    std::pair<iterator,bool> insert_unique(const detail::moved_object<value_type>& mval)
    {
- insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(mval.get(), data);
- if(ret.second){
- ret.first = priv_insert_commit(data, mval);
- }
- return ret;
- }
+ value_type &val = mval.get();
    #else
- std::pair<iterator,bool> insert_unique(value_type && mval)
+ std::pair<iterator,bool> insert_unique(value_type && val)
    {
+ #endif
       insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(mval, data);
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
       if(ret.second){
- ret.first = priv_insert_commit(data, detail::move_impl(mval));
+ ret.first = priv_insert_commit(data, detail::move_impl(val));
       }
       return ret;
    }
- #endif
 
 
    iterator insert_equal(const value_type& val)
@@ -350,6 +356,146 @@
       priv_insert_equal(first, last, ItCat());
    }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template <class... Args>
+ iterator emplace_unique(Args&&... args)
+ {
+ value_type val(detail::forward_impl<Args>(args)...);
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ template <class... Args>
+ iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ {
+ value_type val(detail::forward_impl<Args>(args)...);
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ template <class... Args>
+ iterator emplace_equal(Args&&... args)
+ {
+ value_type val(detail::forward_impl<Args>(args)...);
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, detail::move_impl<value_type>(val));
+ return i;
+ }
+
+ template <class... Args>
+ iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ {
+ value_type val(detail::forward_impl<Args>(args)...);
+ insert_commit_data data;
+ priv_insert_equal_prepare(hint, val, data);
+ return priv_insert_commit(data, detail::move_impl<value_type>(val));
+ }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace_unique()
+ {
+ detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ priv_insert_unique_prepare(val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ iterator emplace_hint_unique(const_iterator hint)
+ {
+ detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ if(ret.second){
+ ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val));
+ }
+ return ret.first;
+ }
+
+ iterator emplace_equal()
+ {
+ detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ iterator i = this->upper_bound(KeyOfValue()(val));
+ i = this->m_data.m_vect.insert(i, detail::move_impl<value_type>(val));
+ return i;
+ }
+
+ iterator emplace_hint_equal(const_iterator hint)
+ {
+ detail::value_init<value_type> vval;
+ value_type &val = vval.m_t;
+ insert_commit_data data;
+ priv_insert_equal_prepare(hint, val, data);
+ return priv_insert_commit(data, detail::move_impl<value_type>(val));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
+ if(ret.second){ \
+ ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val)); \
+ } \
+ return ret.first; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_unique(const_iterator hint, \
+ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
+ if(ret.second){ \
+ ret.first = priv_insert_commit(data, detail::move_impl<value_type>(val)); \
+ } \
+ return ret.first; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ iterator i = this->upper_bound(KeyOfValue()(val)); \
+ i = this->m_data.m_vect.insert(i, detail::move_impl<value_type>(val)); \
+ return i; \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_equal(const_iterator hint, \
+ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ value_type val(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ insert_commit_data data; \
+ priv_insert_equal_prepare(hint, val, data); \
+ return priv_insert_commit(data, detail::move_impl<value_type>(val)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    iterator erase(const_iterator position)
    { return this->m_data.m_vect.erase(position); }
 
@@ -435,14 +581,13 @@
    private:
    struct insert_commit_data
    {
- iterator position;
+ const_iterator position;
    };
 
    // insert/erase
    void priv_insert_equal_prepare
- (const_iterator p, const value_type& val, insert_commit_data &data)
+ (const_iterator pos, const value_type& val, insert_commit_data &data)
    {
- iterator &pos = (iterator &)(const_iterator &)p;
       // N1780
       // To insert val at pos:
       // if pos == end || val <= *pos
@@ -456,13 +601,13 @@
       // insert val before lower_bound(val)
       const value_compare &value_comp = this->m_data;
 
- if(pos == this->end() || !value_comp(*pos, val)){
- if (pos == this->begin() || !value_comp(val, pos[-1])){
+ if(pos == this->cend() || !value_comp(*pos, val)){
+ if (pos == this->cbegin() || !value_comp(val, pos[-1])){
             data.position = pos;
          }
          else{
             data.position =
- this->priv_upper_bound(this->begin(), pos, KeyOfValue()(val));
+ this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
          }
       }
       //Works, but increases code complexity
@@ -471,17 +616,17 @@
       //}
       else{
          data.position =
- this->priv_lower_bound(pos, this->end(), KeyOfValue()(val));
+ this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
       }
    }
 
    std::pair<iterator,bool> priv_insert_unique_prepare
- (iterator beg, iterator end, const value_type& val, insert_commit_data &commit_data)
+ (const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
    {
       const value_compare &value_comp = this->m_data;
       commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
       return std::pair<iterator,bool>
- ( commit_data.position
+ ( *reinterpret_cast<iterator*>(&commit_data.position)
          , commit_data.position == end || value_comp(val, *commit_data.position));
    }
 
@@ -490,9 +635,8 @@
    { return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
 
    std::pair<iterator,bool> priv_insert_unique_prepare
- (const_iterator p, const value_type& val, insert_commit_data &commit_data)
+ (const_iterator pos, const value_type& val, insert_commit_data &commit_data)
    {
- iterator &pos = (iterator &)(const_iterator &)p;
       //N1780. Props to Howard Hinnant!
       //To insert val at pos:
       //if pos == end || val <= *pos
@@ -506,17 +650,17 @@
       // insert val before lower_bound(val)
       const value_compare &value_comp = this->m_data;
 
- if(pos == this->end() || value_comp(val, *pos)){
- if(pos != this->begin() && !value_comp(val, pos[-1])){
+ if(pos == this->cend() || value_comp(val, *pos)){
+ if(pos != this->cbegin() && !value_comp(val, pos[-1])){
             if(value_comp(pos[-1], val)){
- commit_data.position = iterator(pos);
- return std::pair<iterator,bool>(pos, true);
+ commit_data.position = pos;
+ return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
             }
             else{
- return std::pair<iterator,bool>(pos, false);
+ return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
             }
          }
- return this->priv_insert_unique_prepare(this->begin(), pos, val, commit_data);
+ return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
       }
 
       // Works, but increases code complexity

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -54,7 +54,7 @@
    { return static_cast<const ValueCompare &>(*this); }
 
    bool operator()(const Node &a, const Node &b) const
- { return ValueCompare::operator()(a.m_data, b.m_data); }
+ { return ValueCompare::operator()(a.get_data(), b.get_data()); }
 };
 
 template<class A, class ICont>
@@ -143,22 +143,8 @@
    { this->node_alloc().deallocate_one(p); }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible>
- static void construct(const NodePtr &ptr, const Convertible &value)
- { new((void*)detail::get_pointer(ptr)) Node(value); }
- #else
- template<class Convertible>
- static void construct(const NodePtr &ptr, Convertible &&value)
- { new((void*)detail::get_pointer(ptr)) Node(detail::forward_impl<Convertible>(value)); }
- #endif
-
- static void construct(const NodePtr &ptr)
- { new((void*)detail::get_pointer(ptr)) Node(); }
-
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Convertible1, class Convertible2>
- static void construct(const NodePtr &ptr,
- const detail::moved_object<std::pair<Convertible1, Convertible2> > &value)
+ static void construct(const NodePtr &ptr, const detail::moved_object<std::pair<Convertible1, Convertible2> > &value)
    {
       typedef typename Node::hook_type hook_type;
       typedef typename Node::value_type::first_type first_type;
@@ -168,7 +154,7 @@
       //Hook constructor does not throw
       new(static_cast<hook_type*>(nodeptr))hook_type();
       //Now construct pair members_holder
- value_type *valueptr = &nodeptr->m_data;
+ value_type *valueptr = &nodeptr->get_data();
       new((void*)&valueptr->first) first_type(detail::move_impl(value.get().first));
       BOOST_TRY{
          new((void*)&valueptr->second) second_type(detail::move_impl(value.get().second));
@@ -182,8 +168,7 @@
    }
    #else
    template<class Convertible1, class Convertible2>
- static void construct(const NodePtr &ptr,
- std::pair<Convertible1, Convertible2> &&value)
+ static void construct(const NodePtr &ptr, std::pair<Convertible1, Convertible2> &&value)
    {
       typedef typename Node::hook_type hook_type;
       typedef typename Node::value_type::first_type first_type;
@@ -193,7 +178,7 @@
       //Hook constructor does not throw
       new(static_cast<hook_type*>(nodeptr))hook_type();
       //Now construct pair members_holder
- value_type *valueptr = &nodeptr->m_data;
+ value_type *valueptr = &nodeptr->get_data();
       new((void*)&valueptr->first) first_type(detail::move_impl(value.first));
       BOOST_TRY{
          new((void*)&valueptr->second) second_type(detail::move_impl(value.second));
@@ -210,43 +195,82 @@
    static void destroy(const NodePtr &ptr)
    { detail::get_pointer(ptr)->~Node(); }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible>
- NodePtr create_node(const Convertible& x)
+
+ #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ Deallocator
+ #else
+ move_return<Deallocator>
+ #endif
+ create_node_and_deallocator()
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
- self_t::construct(p, x);
- node_deallocator.release();
- return (p);
+ return node_deallocator;
    }
- #else
- template<class Convertible>
- NodePtr create_node(Convertible &&x)
+
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ static void construct(const NodePtr &ptr, Args &&...args)
+ { new((void*)detail::get_pointer(ptr)) Node(detail::forward_impl<Args>(args)...); }
+
+ template<class ...Args>
+ NodePtr create_node(Args &&...args)
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
- self_t::construct(p, detail::forward_impl<Convertible>(x));
+ self_t::construct(p, detail::forward_impl<Args>(args)...);
       node_deallocator.release();
       return (p);
    }
- #endif
 
- template<class It>
- NodePtr create_node_from_it(It it)
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ static void construct(const NodePtr &ptr)
+ { new((void*)detail::get_pointer(ptr)) Node(); }
+
+ NodePtr create_node()
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
- ::boost::interprocess::construct_in_place(detail::get_pointer(p), it);
+ self_t::construct(p);
       node_deallocator.release();
       return (p);
    }
 
- NodePtr create_node()
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void construct(const NodePtr &ptr, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ new((void*)detail::get_pointer(ptr)) \
+ Node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ NodePtr create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p = this->allocate_one(); \
+ Deallocator node_deallocator(p, this->node_alloc()); \
+ self_t::construct(p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ node_deallocator.release(); \
+ return (p); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template<class It>
+ NodePtr create_node_from_it(It it)
    {
       NodePtr p = this->allocate_one();
       Deallocator node_deallocator(p, this->node_alloc());
- self_t::construct(p);
+ ::boost::interprocess::construct_in_place(detail::get_pointer(p), it);
       node_deallocator.release();
       return (p);
    }
@@ -339,7 +363,7 @@
       {}
 
       NodePtr operator()(const Node &other) const
- { return m_holder.create_node(other.m_data); }
+ { return m_holder.create_node(other.get_data()); }
 
       node_alloc_holder &m_holder;
    };

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -52,7 +52,11 @@
 #include <boost/detail/no_exceptions_support.hpp>
 #include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
 #include <boost/intrusive/rbtree.hpp>
+#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+#include <boost/interprocess/detail/preprocessor.hpp>
+#endif
 
+#include <utility> //std::pair
 #include <iterator>
 #include <algorithm>
 
@@ -84,39 +88,79 @@
    { return key_compare::operator()(KeyOfValue()(a), KeyOfValue()(b)); }
 };
 
-template <class T, class VoidPointer>
-struct rbtree_node
- : public bi::make_set_base_hook
- < bi::void_pointer<VoidPointer>
- , bi::link_mode<bi::normal_link>
- , bi::optimize_size<true>
- >::type
+template<class VoidPointer>
+struct rbtree_hook
 {
    typedef typename bi::make_set_base_hook
       < bi::void_pointer<VoidPointer>
       , bi::link_mode<bi::normal_link>
       , bi::optimize_size<true>
- >::type hook_type;
+ >::type type;
+};
+
+template<class T>
+struct rbtree_type
+{
+ typedef T type;
+};
+
+template<class T1, class T2>
+struct rbtree_type< std::pair<T1, T2> >
+{
+ typedef detail::pair<T1, T2> type;
+};
+
+template <class T, class VoidPointer>
+struct rbtree_node
+ : public rbtree_hook<VoidPointer>::type
+{
+ typedef typename rbtree_hook<VoidPointer>::type hook_type;
 
    typedef T value_type;
+ typedef typename rbtree_type<T>::type internal_type;
 
    typedef rbtree_node<T, VoidPointer> node_type;
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible>
- rbtree_node(const Convertible &conv)
- : m_data(conv){}
- #else
- template<class Convertible>
- rbtree_node(Convertible &&conv)
- : m_data(detail::forward_impl<Convertible>(conv)){}
- #endif
+ #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ rbtree_node()
+ : m_data()
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ rbtree_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ rbtree_node(Args &&...args)
+ : m_data(detail::forward_impl<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
    rbtree_node &operator=(const rbtree_node &other)
    { do_assign(other.m_data); return *this; }
 
- T m_data;
- private:
+ T &get_data()
+ {
+ T* ptr = reinterpret_cast<T*>(&this->m_data);
+ return *ptr;
+ }
+
+ const T &get_data() const
+ {
+ const T* ptr = reinterpret_cast<const T*>(&this->m_data);
+ return *ptr;
+ }
+
+ private:
+ internal_type m_data;
 
    template<class A, class B>
    void do_assign(const std::pair<const A, B> &p)
@@ -125,49 +169,27 @@
       m_data.second = p.second;
    }
 
+ template<class A, class B>
+ void do_assign(const detail::pair<const A, B> &p)
+ {
+ const_cast<A&>(m_data.first) = p.first;
+ m_data.second = p.second;
+ }
+
    template<class V>
    void do_assign(const V &v)
    { m_data = v; }
 
    public:
- #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE)
-
- template<class Convertible>
- static void construct(node_type *ptr, const Convertible &value)
- { new(ptr) node_type(value); }
-
- template<class Convertible1, class Convertible2>
- static void construct(node_type *ptr,
- const detail::moved_object<std::pair<Convertible1, Convertible2> > &value)
- {
- //std::pair is not movable so we define our own type and overwrite it
- typedef detail::pair<typename node_type::value_type::first_type
- ,typename node_type::value_type::second_type> hack_pair_t;
-
- typedef rbtree_node<hack_pair_t, VoidPointer> hack_node_t;
-
- new((void*)ptr) hack_node_t(value);
- }
-
- #elif !defined(BOOST_INTERPROCESS_RVALUE_PAIR)
-
    template<class Convertible>
- static void construct(node_type *ptr, Convertible &&value)
- { new(ptr) node_type(detail::forward_impl<Convertible>(value)); }
-
- template<class Convertible1, class Convertible2>
- static void construct(node_type *ptr,
- std::pair<Convertible1, Convertible2> &&value)
- {
- //std::pair is not movable so we define our own type and overwrite it
- typedef detail::pair<typename node_type::value_type::first_type
- ,typename node_type::value_type::second_type> hack_pair_t;
 
- typedef rbtree_node<hack_pair_t, VoidPointer> hack_node_t;
-
- new((void*)ptr) hack_node_t(value);
- }
+ static void construct(node_type *ptr
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE)
+ , const Convertible &value)
+ #else
+ , Convertible &&value)
    #endif
+ { new(ptr) node_type(detail::forward_impl<Convertible>(value)); }
 };
 
 }//namespace detail {
@@ -193,7 +215,7 @@
    typedef typename bi::make_rbtree
       <node_type
       ,bi::compare<node_compare_type>
- ,bi::base_hook<typename node_type::hook_type>
+ ,bi::base_hook<typename rbtree_hook<void_pointer>::type>
       ,bi::constant_time_size<true>
       ,bi::size_type<typename A::size_type>
>::type container_type;
@@ -302,11 +324,11 @@
       
       template<class KeyType>
       bool operator()(const Node &n, const KeyType &k) const
- { return KeyValueCompare::operator()(n.m_data, k); }
+ { return KeyValueCompare::operator()(n.get_data(), k); }
 
       template<class KeyType>
       bool operator()(const KeyType &k, const Node &n) const
- { return KeyValueCompare::operator()(k, n.m_data); }
+ { return KeyValueCompare::operator()(k, n.get_data()); }
    };
 
    typedef key_node_compare<value_compare> KeyNodeCompare;
@@ -341,10 +363,10 @@
 
       //Pointer like operators
       const_reference operator*() const
- { return m_it->m_data; }
+ { return m_it->get_data(); }
 
       const_pointer operator->() const
- { return const_pointer(&m_it->m_data); }
+ { return const_pointer(&m_it->get_data()); }
 
       //Increment / Decrement
       const_iterator& operator++()
@@ -387,8 +409,8 @@
       iterator(){}
 
       //Pointer like operators
- reference operator*() const { return this->m_it->m_data; }
- pointer operator->() const { return pointer(&this->m_it->m_data); }
+ reference operator*() const { return this->m_it->get_data(); }
+ pointer operator->() const { return pointer(&this->m_it->get_data()); }
 
       //Increment / Decrement
       iterator& operator++()
@@ -495,25 +517,59 @@
    { return iterator(this->icont().begin()); }
 
    const_iterator begin() const
- { return const_iterator(this->non_const_icont().begin()); }
+ { return this->cbegin(); }
 
    iterator end()
    { return iterator(this->icont().end()); }
 
    const_iterator end() const
- { return const_iterator(this->non_const_icont().end()); }
+ { return this->cend(); }
 
    reverse_iterator rbegin()
    { return reverse_iterator(end()); }
 
    const_reverse_iterator rbegin() const
- { return const_reverse_iterator(end()); }
+ { return this->crbegin(); }
 
    reverse_iterator rend()
    { return reverse_iterator(begin()); }
 
    const_reverse_iterator rend() const
- { return const_reverse_iterator(begin()); }
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(cend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(cbegin()); }
 
    bool empty() const
    { return !this->size(); }
@@ -621,6 +677,113 @@
    }
    #endif
 
+ private:
+ iterator emplace_unique_impl(NodePtr p)
+ {
+ value_type &v = p->get_data();
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(KeyOfValue()(v), data);
+ if(!ret.second){
+ Destroyer(this->node_alloc())(p);
+ return ret.first;
+ }
+ return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+ }
+
+ iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
+ {
+ value_type &v = p->get_data();
+ insert_commit_data data;
+ std::pair<iterator,bool> ret =
+ this->insert_unique_check(hint, KeyOfValue()(v), data);
+ if(!ret.second){
+ Destroyer(this->node_alloc())(p);
+ return ret.first;
+ }
+ return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+ }
+
+ public:
+
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template <class... Args>
+ iterator emplace_unique(Args&&... args)
+ { return this->emplace_unique_impl(AllocHolder::create_node(detail::forward_impl<Args>(args)...)); }
+
+ template <class... Args>
+ iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(detail::forward_impl<Args>(args)...)); }
+
+ template <class... Args>
+ iterator emplace_equal(Args&&... args)
+ {
+ NodePtr p(AllocHolder::create_node(detail::forward_impl<Args>(args)...));
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ template <class... Args>
+ iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ {
+ NodePtr p(AllocHolder::create_node(detail::forward_impl<Args>(args)...));
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace_unique()
+ { return this->emplace_unique_impl(AllocHolder::create_node()); }
+
+ iterator emplace_hint_unique(const_iterator hint)
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node()); }
+
+ iterator emplace_equal()
+ {
+ NodePtr p(AllocHolder::create_node());
+ return iterator(this->icont().insert_equal(this->icont().end(), *p));
+ }
+
+ iterator emplace_hint_equal(const_iterator hint)
+ {
+ NodePtr p(AllocHolder::create_node());
+ return iterator(this->icont().insert_equal(hint.get(), *p));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_unique_impl \
+ (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_unique(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_unique_hint_impl \
+ (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint_equal(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_equal(hint.get(), *p)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    iterator insert_unique(const_iterator hint, const value_type& v)
    {
       insert_commit_data data;
@@ -663,7 +826,7 @@
       if(this->empty()){
          //Insert with end hint, to achieve linear
          //complexity if [first, last) is ordered
- iterator end(this->end());
+ const_iterator end(this->end());
          for( ; first != last; ++first)
             this->insert_unique(end, *first);
       }
@@ -722,7 +885,7 @@
    {
       //Insert with end hint, to achieve linear
       //complexity if [first, last) is ordered
- iterator end(this->end());
+ const_iterator end(this->cend());
       for( ; first != last; ++first)
          this->insert_equal(end, *first);
    }
@@ -815,7 +978,6 @@
    class insertion_functor
    {
       Icont &icont_;
- typename Icont::iterator pos_;
 
       public:
       insertion_functor(Icont &icont)
@@ -823,7 +985,7 @@
       {}
 
       void operator()(Node &n)
- { this->icont_.insert_equal(this->icont_.end(), n); }
+ { this->icont_.insert_equal(this->icont_.cend(), n); }
    };
 
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -77,7 +77,7 @@
                            Pred,
                            Alloc> tree_t;
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    //This is the real tree stored here. It's based on a movable pair
    typedef detail::flat_tree<Key,
                            detail::pair<Key, T>,
@@ -85,10 +85,11 @@
                            Pred,
                            typename Alloc::template
                               rebind<detail::pair<Key, T> >::other> impl_tree_t;
+/*
    #else
    typedef tree_t impl_tree_t;
    #endif
-
+*/
    impl_tree_t m_flat_tree; // flat tree representing flat_map
 
    typedef typename impl_tree_t::value_type impl_value_type;
@@ -106,20 +107,17 @@
    typedef detail::moved_object<impl_value_type> impl_moved_value_type;
    #endif
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class D, class S>
    static D &force(const S &s)
- { return *((D*)(void*)(const void*)(&s)); }
- #else
- //For rvalue-aware compilers, just forward
- template<class Type>
- static const Type &force(const Type &t)
- { return t; }
-
- template<class Type>
- static Type &force(Type &t)
- { return t; }
- #endif
+ { return *const_cast<D*>(reinterpret_cast<const D*>(&s)); }
+
+ template<class D, class S>
+ static D force_copy(S s)
+ {
+ value_type *vp = reinterpret_cast<value_type *>(&*s);
+ return D(vp);
+ }
 
    /// @endcond
 
@@ -235,7 +233,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator begin()
- { return force<iterator>(m_flat_tree.begin()); }
+ { return force_copy<iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
    //!
@@ -245,13 +243,21 @@
    const_iterator begin() const
       { return force<const_iterator>(m_flat_tree.begin()); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return force<const_iterator>(m_flat_tree.cbegin()); }
+
    //! <b>Effects</b>: Returns an iterator to the end of the container.
    //!
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
    iterator end()
- { return force<iterator>(m_flat_tree.end()); }
+ { return force_copy<iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
    //!
@@ -261,6 +267,14 @@
    const_iterator end() const
       { return force<const_iterator>(m_flat_tree.end()); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return force<const_iterator>(m_flat_tree.cend()); }
+
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed container.
    //!
@@ -279,6 +293,15 @@
    const_reverse_iterator rbegin() const
       { return force<const_reverse_iterator>(m_flat_tree.rbegin()); }
 
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return force<const_reverse_iterator>(m_flat_tree.crbegin()); }
+
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed container.
    //!
@@ -297,6 +320,15 @@
    const_reverse_iterator rend() const
       { return force<const_reverse_iterator>(m_flat_tree.rend()); }
 
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return force<const_reverse_iterator>(m_flat_tree.crend()); }
+
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
    //! <b>Throws</b>: Nothing.
@@ -425,7 +457,8 @@
          m_flat_tree.insert_unique(force<impl_moved_value_type>(x))); }
    #else
    std::pair<iterator,bool> insert(value_type &&x)
- { return m_flat_tree.insert_unique(detail::move_impl(x)); }
+ { return force<std::pair<iterator,bool> >(
+ m_flat_tree.insert_unique(detail::move_impl(force<impl_value_type>(x)))); }
    #endif
 
    //! <b>Effects</b>: Inserts a copy of x in the container if and only if there is
@@ -439,9 +472,9 @@
    //! right before p) plus insertion linear to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(iterator position, const value_type& x)
- { return force<iterator>(
- m_flat_tree.insert_unique(force<impl_iterator>(position), force<impl_value_type>(x))); }
+ iterator insert(const_iterator position, const value_type& x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
 
    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -453,12 +486,13 @@
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<value_type>& x)
- { return force<iterator>(
- m_flat_tree.insert_unique(force<impl_iterator>(position), force<impl_moved_value_type>(x))); }
+ iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), force<impl_moved_value_type>(x))); }
    #else
- iterator insert(iterator position, value_type &&x)
- { return m_flat_tree.insert_unique(position, detail::move_impl(x)); }
+ iterator insert(const_iterator position, value_type &&x)
+ { return force_copy<iterator>(
+ m_flat_tree.insert_unique(force<impl_const_iterator>(position), detail::move_impl(force<impl_value_type>(x)))); }
    #endif
 
    //! <b>Requires</b>: i, j are not iterators into *this.
@@ -472,7 +506,70 @@
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    template <class InputIterator>
    void insert(InputIterator first, InputIterator last)
- { m_flat_tree.insert_unique(first, last); }
+ { m_flat_tree.insert_unique(first, last); }
+
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_unique(detail::forward_impl<Args>(args)...)); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint), detail::forward_impl<Args>(args)...)); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return force_copy<iterator>(m_flat_tree.emplace_unique()); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_unique(force<impl_const_iterator>(hint))); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_unique \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_hint_unique \
+ (force<impl_const_iterator>(hint), \
+ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
    //! <b>Effects</b>: Erases the element pointed to by position.
    //!
@@ -485,7 +582,7 @@
    //! <b>Note</b>: Invalidates elements with keys
    //! not less than the erased element.
    iterator erase(const_iterator position)
- { return force<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
 
    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
    //!
@@ -505,7 +602,7 @@
    //! <b>Complexity</b>: Logarithmic search time plus erasure time
    //! linear to the elements with bigger keys.
    iterator erase(const_iterator first, const_iterator last)
- { return force<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
 
    //! <b>Effects</b>: erase(a.begin(),a.end()).
    //!
@@ -529,7 +626,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic.
    iterator find(const key_type& x)
- { return force<iterator>(m_flat_tree.find(x)); }
+ { return force_copy<iterator>(m_flat_tree.find(x)); }
 
    //! <b>Returns</b>: A const_iterator pointing to an element with the key
    //! equivalent to x, or end() if such an element is not found.
@@ -549,7 +646,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    iterator lower_bound(const key_type& x)
- { return force<iterator>(m_flat_tree.lower_bound(x)); }
+ { return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
 
    //! <b>Returns</b>: A const iterator pointing to the first element with key not
    //! less than k, or a.end() if such an element is not found.
@@ -563,7 +660,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    iterator upper_bound(const key_type& x)
- { return force<iterator>(m_flat_tree.upper_bound(x)); }
+ { return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
 
    //! <b>Returns</b>: A const iterator pointing to the first element with key not
    //! less than x, or end() if such an element is not found.
@@ -725,7 +822,7 @@
                            detail::select1st< std::pair<Key, T> >,
                            Pred,
                            Alloc> tree_t;
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    //This is the real tree stored here. It's based on a movable pair
    typedef detail::flat_tree<Key,
                            detail::pair<Key, T>,
@@ -733,10 +830,11 @@
                            Pred,
                            typename Alloc::template
                               rebind<detail::pair<Key, T> >::other> impl_tree_t;
+/*
    #else
    typedef tree_t impl_tree_t;
    #endif
-
+*/
    impl_tree_t m_flat_tree; // flat tree representing flat_map
 
    typedef typename impl_tree_t::value_type impl_value_type;
@@ -754,20 +852,17 @@
    typedef detail::moved_object<impl_value_type> impl_moved_value_type;
    #endif
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ //#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class D, class S>
    static D &force(const S &s)
    { return *const_cast<D*>((reinterpret_cast<const D*>(&s))); }
- #else
- //For rvalue-aware compilers, just forward
- template<class Type>
- static const Type &force(const Type &t)
- { return t; }
-
- template<class Type>
- static Type &force(Type &t)
- { return t; }
- #endif
+
+ template<class D, class S>
+ static D force_copy(S s)
+ {
+ value_type *vp = reinterpret_cast<value_type *>(&*s);
+ return D(vp);
+ }
    /// @endcond
 
    public:
@@ -882,7 +977,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator begin()
- { return force<iterator>(m_flat_tree.begin()); }
+ { return force_copy<iterator>(m_flat_tree.begin()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
    //!
@@ -898,7 +993,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    iterator end()
- { return force<iterator>(m_flat_tree.end()); }
+ { return force_copy<iterator>(m_flat_tree.end()); }
 
    //! <b>Effects</b>: Returns a const_iterator to the end of the container.
    //!
@@ -999,7 +1094,7 @@
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    iterator insert(const value_type& x)
- { return force<iterator>(m_flat_tree.insert_equal(force<impl_value_type>(x))); }
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_value_type>(x))); }
 
    //! <b>Effects</b>: Inserts a new value move-constructed from x and returns
    //! the iterator pointing to the newly inserted element.
@@ -1010,10 +1105,10 @@
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    iterator insert(const detail::moved_object<value_type>& x)
- { return force<iterator>(m_flat_tree.insert_equal(force<impl_moved_value_type>(x))); }
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_moved_value_type>(x))); }
    #else
    iterator insert(value_type &&x)
- { return m_flat_tree.insert_equal(detail::move_impl(x)); }
+ { return force_copy<iterator>(m_flat_tree.insert_equal(detail::move_impl(x))); }
    #endif
 
    //! <b>Effects</b>: Inserts a copy of x in the container.
@@ -1027,8 +1122,8 @@
    //! to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(iterator position, const value_type& x)
- { return force<iterator>(m_flat_tree.insert_equal(force<impl_iterator>(position), force<impl_value_type>(x))); }
+ iterator insert(const_iterator position, const value_type& x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_value_type>(x))); }
 
    //! <b>Effects</b>: Inserts a value move constructed from x in the container.
    //! p is a hint pointing to where the insert should start to search.
@@ -1042,11 +1137,11 @@
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<value_type>& x)
- { return force<iterator>(m_flat_tree.insert_equal(force<impl_iterator>(position), force<impl_moved_value_type>(x))); }
+ iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), force<impl_moved_value_type>(x))); }
    #else
- iterator insert(iterator position, value_type &&x)
- { return m_flat_tree.insert_equal(force<impl_iterator>(position), detail::move_impl(x)); }
+ iterator insert(const_iterator position, value_type &&x)
+ { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_const_iterator>(position), detail::move_impl(x))); }
    #endif
 
    //! <b>Requires</b>: i, j are not iterators into *this.
@@ -1061,6 +1156,68 @@
    void insert(InputIterator first, InputIterator last)
       { m_flat_tree.insert_equal(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return force_copy<iterator>(m_flat_tree.emplace_equal(detail::forward_impl<Args>(args)...)); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant time if the value
+ //! is to be inserted before p) plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ {
+ return force_copy<iterator>(m_flat_tree.emplace_hint_equal
+ (force<impl_const_iterator>(hint), detail::forward_impl<Args>(args)...));
+ }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return force_copy<iterator>(m_flat_tree.emplace_equal()); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return force_copy<iterator>(m_flat_tree.emplace_hint_equal(force<impl_const_iterator>(hint))); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_equal \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return force_copy<iterator>(m_flat_tree.emplace_hint_equal \
+ (force<impl_const_iterator>(hint), \
+ BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _))); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by position.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
@@ -1072,7 +1229,7 @@
    //! <b>Note</b>: Invalidates elements with keys
    //! not less than the erased element.
    iterator erase(const_iterator position)
- { return force<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(position))); }
 
    //! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
    //!
@@ -1092,7 +1249,7 @@
    //! <b>Complexity</b>: Logarithmic search time plus erasure time
    //! linear to the elements with bigger keys.
    iterator erase(const_iterator first, const_iterator last)
- { return force<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
+ { return force_copy<iterator>(m_flat_tree.erase(force<impl_const_iterator>(first), force<impl_const_iterator>(last))); }
 
    //! <b>Effects</b>: erase(a.begin(),a.end()).
    //!
@@ -1116,7 +1273,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic.
    iterator find(const key_type& x)
- { return force<iterator>(m_flat_tree.find(x)); }
+ { return force_copy<iterator>(m_flat_tree.find(x)); }
 
    //! <b>Returns</b>: An const_iterator pointing to an element with the key
    //! equivalent to x, or end() if such an element is not found.
@@ -1136,7 +1293,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    iterator lower_bound(const key_type& x)
- {return force<iterator>(m_flat_tree.lower_bound(x)); }
+ {return force_copy<iterator>(m_flat_tree.lower_bound(x)); }
 
    //! <b>Returns</b>: A const iterator pointing to the first element with key
    //! not less than k, or a.end() if such an element is not found.
@@ -1150,7 +1307,7 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    iterator upper_bound(const key_type& x)
- {return force<iterator>(m_flat_tree.upper_bound(x)); }
+ {return force_copy<iterator>(m_flat_tree.upper_bound(x)); }
 
    //! <b>Returns</b>: A const iterator pointing to the first element with key
    //! not less than x, or end() if such an element is not found.
@@ -1163,14 +1320,14 @@
    //!
    //! <b>Complexity</b>: Logarithmic
    std::pair<iterator,iterator> equal_range(const key_type& x)
- { return force<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
+ { return force_copy<std::pair<iterator,iterator> >(m_flat_tree.equal_range(x)); }
 
    //! <b>Effects</b>: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
    //!
    //! <b>Complexity</b>: Logarithmic
    std::pair<const_iterator,const_iterator>
       equal_range(const key_type& x) const
- { return force<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
+ { return force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
 
    //! <b>Effects</b>: Number of elements for which memory has been allocated.
    //! capacity() is always greater than or equal to size().

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -185,6 +185,14 @@
    const_iterator begin() const
       { return m_flat_tree.begin(); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_flat_tree.cbegin(); }
+
    //! <b>Effects</b>: Returns an iterator to the end of the container.
    //!
    //! <b>Throws</b>: Nothing.
@@ -201,6 +209,14 @@
    const_iterator end() const
       { return m_flat_tree.end(); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_flat_tree.cend(); }
+
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed container.
    //!
@@ -219,6 +235,15 @@
    const_reverse_iterator rbegin() const
       { return m_flat_tree.rbegin(); }
 
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_flat_tree.crbegin(); }
+
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed container.
    //!
@@ -237,6 +262,15 @@
    const_reverse_iterator rend() const
       { return m_flat_tree.rend(); }
 
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_flat_tree.crend(); }
+
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
    //! <b>Throws</b>: Nothing.
@@ -328,7 +362,7 @@
    //! right before p) plus insertion linear to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(iterator position, const value_type& x)
+ iterator insert(const_iterator position, const value_type& x)
       { return m_flat_tree.insert_unique(position, x); }
 
    //! <b>Effects</b>: Inserts an element move constructed from x in the container.
@@ -341,10 +375,10 @@
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<value_type>& x)
+ iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
       { return m_flat_tree.insert_unique(position, x); }
    #else
- iterator insert(iterator position, value_type && x)
+ iterator insert(const_iterator position, value_type && x)
       { return m_flat_tree.insert_unique(position, detail::move_impl(x)); }
    #endif
 
@@ -361,6 +395,62 @@
    void insert(InputIterator first, InputIterator last)
       { m_flat_tree.insert_unique(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is no element in the container
+ //! with key equivalent to the key of x.
+ //!
+ //! <b>Returns</b>: The bool component of the returned pair is true if and only
+ //! if the insertion takes place, and the iterator component of the pair
+ //! points to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_flat_tree.emplace_unique(detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with key equivalent to the key of x.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_flat_tree.emplace_hint_unique(hint, detail::forward_impl<Args>(args)...); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_flat_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_flat_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by position.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
@@ -704,6 +794,14 @@
    const_iterator begin() const
       { return m_flat_tree.begin(); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_flat_tree.cbegin(); }
+
    //! <b>Effects</b>: Returns an iterator to the end of the container.
    //!
    //! <b>Throws</b>: Nothing.
@@ -720,6 +818,14 @@
    const_iterator end() const
       { return m_flat_tree.end(); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_flat_tree.cend(); }
+
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed container.
    //!
@@ -738,6 +844,15 @@
    const_reverse_iterator rbegin() const
       { return m_flat_tree.rbegin(); }
 
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_flat_tree.crbegin(); }
+
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed container.
    //!
@@ -756,6 +871,15 @@
    const_reverse_iterator rend() const
       { return m_flat_tree.rend(); }
 
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_flat_tree.crend(); }
+
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
    //! <b>Throws</b>: Nothing.
@@ -838,7 +962,7 @@
    //! right before p) plus insertion linear to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- iterator insert(iterator position, const value_type& x)
+ iterator insert(const_iterator position, const value_type& x)
       { return m_flat_tree.insert_equal(position, x); }
 
    //! <b>Effects</b>: Inserts a new value move constructed from x in the container.
@@ -852,10 +976,10 @@
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<value_type>& x)
+ iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
       { return m_flat_tree.insert_equal(position, x); }
    #else
- iterator insert(iterator position, value_type && x)
+ iterator insert(const_iterator position, value_type && x)
       { return m_flat_tree.insert_equal(position, detail::move_impl(x)); }
    #endif
 
@@ -871,6 +995,57 @@
    void insert(InputIterator first, InputIterator last)
       { m_flat_tree.insert_equal(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time plus linear insertion
+ //! to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_flat_tree.emplace_equal(detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic search time (constant if x is inserted
+ //! right before p) plus insertion linear to the elements with bigger keys than x.
+ //!
+ //! <b>Note</b>: If an element it's inserted it might invalidate elements.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_flat_tree.emplace_hint_equal(hint, detail::forward_impl<Args>(args)...); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_flat_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_flat_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_flat_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by position.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately

Modified: branches/release/boost/interprocess/containers/list.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/list.hpp (original)
+++ branches/release/boost/interprocess/containers/list.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -49,7 +49,6 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
-
 #include <boost/interprocess/interprocess_fwd.hpp>
 #include <boost/interprocess/detail/version_type.hpp>
 #include <boost/interprocess/detail/move.hpp>
@@ -60,6 +59,11 @@
 #include <boost/intrusive/list.hpp>
 #include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
 
+#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+//Preprocessor library to emulate perfect forwarding
+#include <boost/interprocess/detail/preprocessor.hpp>
+#endif
+
 #include <iterator>
 #include <utility>
 #include <memory>
@@ -73,29 +77,40 @@
 /// @cond
 namespace detail {
 
+template<class VoidPointer>
+struct list_hook
+{
+ typedef typename bi::make_list_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type type;
+};
+
 template <class T, class VoidPointer>
 struct list_node
- : public bi::make_list_base_hook
- <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type
+ : public list_hook<VoidPointer>::type
 {
- typedef typename bi::make_list_base_hook
- <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type hook_type;
+
+ #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
    list_node()
       : m_data()
    {}
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible>
- list_node(const Convertible &conv)
- : m_data(conv)
- {}
- #else
- template<class Convertible>
- list_node(Convertible &&conv)
- : m_data(detail::forward_impl<Convertible>(conv))
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ list_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ list_node(Args &&...args)
+ : m_data(detail::forward_impl<Args>(args)...)
    {}
- #endif
+ #endif//#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
    T m_data;
 };
@@ -110,7 +125,7 @@
          <value_type, void_pointer> node_type;
    typedef typename bi::make_list
       < node_type
- , bi::base_hook<typename node_type::hook_type>
+ , bi::base_hook<typename list_hook<void_pointer>::type>
       , bi::constant_time_size<true>
       , bi::size_type<typename A::size_type>
>::type container_type;
@@ -335,7 +350,7 @@
    //! <b>Complexity</b>: Linear to n.
    list(size_type n, const T& value = T(), const A& a = A())
       : AllocHolder(a)
- { this->insert(begin(), n, value); }
+ { this->insert(this->cbegin(), n, value); }
 
    //! <b>Effects</b>: Copy constructs a list.
    //!
@@ -346,7 +361,7 @@
    //! <b>Complexity</b>: Linear to the elements x contains.
    list(const list& x)
       : AllocHolder(x)
- { this->insert(begin(), x.begin(), x.end()); }
+ { this->insert(this->cbegin(), x.begin(), x.end()); }
 
    //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
    //!
@@ -373,7 +388,7 @@
    template <class InpIt>
    list(InpIt first, InpIt last, const A &a = A())
       : AllocHolder(a)
- { insert(begin(), first, last); }
+ { this->insert(this->cbegin(), first, last); }
 
    //! <b>Effects</b>: Destroys the list. All stored values are destroyed
    //! and used memory is deallocated.
@@ -420,7 +435,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const
- { return const_iterator(this->non_const_icont().begin()); }
+ { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
    //!
@@ -436,7 +451,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return const_iterator(this->non_const_icont().end()); }
+ { return this->cend(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed list.
@@ -454,7 +469,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin() const
- { return const_reverse_iterator(end()); }
+ { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed list.
@@ -472,7 +487,41 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const
- { return const_reverse_iterator(begin()); }
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return const_reverse_iterator(this->cend()); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return const_reverse_iterator(this->cbegin()); }
 
    //! <b>Effects</b>: Returns true if the list contains no elements.
    //!
@@ -505,7 +554,7 @@
    //!
    //! <b>Complexity</b>: Amortized constant time.
    void push_front(const T& x)
- { this->insert(this->begin(), x); }
+ { this->insert(this->cbegin(), x); }
 
    //! <b>Effects</b>: Constructs a new element in the beginning of the list
    //! and moves the resources of t to this new element.
@@ -515,10 +564,10 @@
    //! <b>Complexity</b>: Amortized constant time.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void push_front(const detail::moved_object<T>& x)
- { this->insert(this->begin(), x); }
+ { this->insert(this->cbegin(), x); }
    #else
    void push_front(T &&x)
- { this->insert(this->begin(), detail::move_impl(x)); }
+ { this->insert(this->cbegin(), detail::move_impl(x)); }
    #endif
 
    //! <b>Effects</b>: Removes the last element from the list.
@@ -527,7 +576,7 @@
    //!
    //! <b>Complexity</b>: Amortized constant time.
    void push_back (const T& x)
- { this->insert(this->end(), x); }
+ { this->insert(this->cend(), x); }
 
    //! <b>Effects</b>: Removes the first element from the list.
    //!
@@ -536,10 +585,10 @@
    //! <b>Complexity</b>: Amortized constant time.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void push_back (const detail::moved_object<T>& x)
- { this->insert(this->end(), x); }
+ { this->insert(this->cend(), x); }
    #else
    void push_back (T &&x)
- { this->insert(this->end(), detail::move_impl(x)); }
+ { this->insert(this->cend(), detail::move_impl(x)); }
    #endif
 
    //! <b>Effects</b>: Removes the first element from the list.
@@ -548,7 +597,7 @@
    //!
    //! <b>Complexity</b>: Amortized constant time.
    void pop_front()
- { this->erase(this->begin()); }
+ { this->erase(this->cbegin()); }
 
    //! <b>Effects</b>: Removes the last element from the list.
    //!
@@ -556,7 +605,7 @@
    //!
    //! <b>Complexity</b>: Amortized constant time.
    void pop_back()
- { iterator tmp = this->end(); this->erase(--tmp); }
+ { const_iterator tmp = this->cend(); this->erase(--tmp); }
 
    //! <b>Requires</b>: !empty()
    //!
@@ -610,7 +659,7 @@
    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
    void resize(size_type new_size, const T& x)
    {
- iterator iend = this->end();
+ const_iterator iend = this->cend();
       size_type len = this->size();
       
       if(len > new_size){
@@ -618,7 +667,7 @@
          while(to_erase--){
             --iend;
          }
- this->erase(iend, this->end());
+ this->erase(iend, this->cend());
       }
       else{
          this->priv_create_and_insert_nodes(iend, new_size - len, x);
@@ -633,12 +682,12 @@
    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
    void resize(size_type new_size)
    {
- iterator iend = this->end();
+ const_iterator iend = this->end();
       size_type len = this->size();
       
       if(len > new_size){
          size_type to_erase = len - new_size;
- iterator ifirst;
+ const_iterator ifirst;
          if(to_erase < len/2u){
             ifirst = iend;
             while(to_erase--){
@@ -655,7 +704,7 @@
          this->erase(ifirst, iend);
       }
       else{
- this->priv_create_and_insert_nodes(this->end(), new_size - len);
+ this->priv_create_and_insert_nodes(this->cend(), new_size - len);
       }
    }
 
@@ -726,7 +775,7 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to n.
- void insert(iterator p, size_type n, const T& x)
+ void insert(const_iterator p, size_type n, const T& x)
    { this->priv_create_and_insert_nodes(p, n, x); }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -738,7 +787,7 @@
    //!
    //! <b>Complexity</b>: Linear to std::distance [first, last).
    template <class InpIt>
- void insert(iterator p, InpIt first, InpIt last)
+ void insert(const_iterator p, InpIt first, InpIt last)
    {
       const bool aux_boolean = detail::is_convertible<InpIt, std::size_t>::value;
       typedef detail::bool_<aux_boolean> Result;
@@ -752,7 +801,7 @@
    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- iterator insert(iterator p, const T& x)
+ iterator insert(const_iterator p, const T& x)
    {
       NodePtr tmp = AllocHolder::create_node(x);
       return iterator(this->icont().insert(p.get(), *tmp));
@@ -766,19 +815,109 @@
    //!
    //! <b>Complexity</b>: Amortized constant time.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator p, const detail::moved_object<T>& x)
+ iterator insert(const_iterator p, const detail::moved_object<T>& x)
    {
       NodePtr tmp = AllocHolder::create_node(x);
       return iterator(this->icont().insert(p.get(), *tmp));
    }
    #else
- iterator insert(iterator p, T &&x)
+ iterator insert(const_iterator p, T &&x)
    {
       NodePtr tmp = AllocHolder::create_node(detail::move_impl(x));
       return iterator(this->icont().insert(p.get(), *tmp));
    }
    #endif
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ {
+ this->emplace(this->cend(), detail::forward_impl<Args>(args)...);
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the beginning of the list.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ {
+ this->emplace(this->cbegin(), detail::forward_impl<Args>(args)...);
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)detail::get_pointer(d.get())) Node(detail::forward_impl<Args>(args)...);
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert(p.get(), *node));
+ }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_back()
+ { this->emplace(this->cend()); }
+
+ void emplace_front()
+ { this->emplace(this->cbegin()); }
+
+ iterator emplace(const_iterator p)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)detail::get_pointer(d.get())) Node();
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert(p.get(), *node));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace(this->cend(), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { this->emplace(this->cbegin(), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));} \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
+ new ((void*)detail::get_pointer(d.get())) \
+ Node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ NodePtr node = d.get(); \
+ d.release(); \
+ return iterator(this->icont().insert(p.get(), *node)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Requires</b>: p must be a valid iterator of *this.
    //!
    //! <b>Effects</b>: Erases the element at p p.
@@ -786,7 +925,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- iterator erase(iterator p)
+ iterator erase(const_iterator p)
    { return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -796,7 +935,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the distance between first and last.
- iterator erase(iterator first, iterator last)
+ iterator erase(const_iterator first, const_iterator last)
    { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
 
    //! <b>Effects</b>: Assigns the n copies of val to *this.
@@ -861,7 +1000,7 @@
    //!
    //! <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 p, ThisType &x, iterator i)
+ void splice(const_iterator p, ThisType &x, const_iterator i)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont(), i.get());
@@ -871,7 +1010,7 @@
       }
    }
 
-// void splice(iterator p, const detail::moved_object<ThisType> &x, iterator i)
+// void splice(const_iterator p, const detail::moved_object<ThisType> &x, const_iterator i)
 // { this->splice(p, x.get(), i); }
 
    //! <b>Requires</b>: p must point to an element contained
@@ -887,7 +1026,7 @@
    //!
    //! <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 p, ThisType &x, iterator first, iterator last)
+ void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont(), first.get(), last.get());
@@ -897,7 +1036,7 @@
       }
    }
 
-// void splice(iterator p, detail::moved_object<ThisType> &x, iterator first, iterator last)
+// void splice(const_iterator p, detail::moved_object<ThisType> &x, const_iterator first, const_iterator last)
 // { return this->splice(p, x.get(), first, last); }
 
    //! <b>Requires</b>: p must point to an element contained
@@ -914,7 +1053,7 @@
    //!
    //! <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 p, ThisType &x, iterator first, iterator last, size_type n)
+ void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
@@ -924,7 +1063,7 @@
       }
    }
 
-// void splice(iterator p, detail::moved_object<ThisType> &x, iterator first, iterator last, size_type n)
+// void splice(const_iterator p, detail::moved_object<ThisType> &x, const_iterator first, const_iterator last, size_type n)
 // { return this->splice(p, x.get(), first, last, n); }
 
    //! <b>Effects</b>: Reverses the order of elements in the list.
@@ -1128,10 +1267,10 @@
    class insertion_functor
    {
       Icont &icont_;
- typename Icont::iterator pos_;
+ typename Icont::const_iterator pos_;
 
       public:
- insertion_functor(Icont &icont, typename Icont::iterator pos)
+ insertion_functor(Icont &icont, typename Icont::const_iterator pos)
          : icont_(icont), pos_(pos)
       {}
 
@@ -1165,13 +1304,13 @@
 
    //Dispatch to detect iterator range or integer overloads
    template <class InputIter>
- void priv_insert_dispatch(iterator p,
+ void priv_insert_dispatch(const_iterator p,
                              InputIter first, InputIter last,
                              detail::false_)
    { this->priv_create_and_insert_nodes(p, first, last); }
 
    template<class Integer>
- void priv_insert_dispatch(iterator p, Integer n, Integer x, detail::true_)
+ void priv_insert_dispatch(const_iterator p, Integer n, Integer x, detail::true_)
    { this->insert(p, (size_type)n, x); }
 
    void priv_fill_assign(size_type n, const T& val)
@@ -1181,10 +1320,10 @@
       for ( ; i != iend && n > 0; ++i, --n)
          *i = val;
       if (n > 0){
- this->priv_create_and_insert_nodes(this->end(), n, val);
+ this->priv_create_and_insert_nodes(this->cend(), n, val);
       }
       else{
- this->erase(i, end());
+ this->erase(i, cend());
       }
    }
 
@@ -1193,8 +1332,7 @@
    { this->priv_fill_assign((size_type) n, (T) val); }
 
    template <class InputIter>
- void priv_assign_dispatch(InputIter first2, InputIter last2,
- detail::false_)
+ void priv_assign_dispatch(InputIter first2, InputIter last2, detail::false_)
    {
       iterator first1 = this->begin();
       iterator last1 = this->end();

Modified: branches/release/boost/interprocess/containers/map.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/map.hpp (original)
+++ branches/release/boost/interprocess/containers/map.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -530,6 +530,58 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_unique(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with an equivalent key.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_unique(detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container if and only if there is
+ //! no element in the container with an equivalent key.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_unique(hint, detail::forward_impl<Args>(args)...); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));}\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by position.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
@@ -1056,6 +1108,56 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_equal(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_equal(detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the container.
+ //! p is a hint pointing to where the insert should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_equal(hint, detail::forward_impl<Args>(args)...); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by position.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately

Modified: branches/release/boost/interprocess/containers/set.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/set.hpp (original)
+++ branches/release/boost/interprocess/containers/set.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -59,6 +59,9 @@
 #include <boost/interprocess/detail/mpl.hpp>
 #include <boost/interprocess/containers/detail/tree.hpp>
 #include <boost/interprocess/detail/move.hpp>
+#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+#include <boost/interprocess/detail/preprocessor.hpp>
+#endif
 
 namespace boost { namespace interprocess {
 
@@ -263,6 +266,40 @@
    const_reverse_iterator rend() const
    { return m_tree.rend(); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_tree.crend(); }
+
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
    //! <b>Throws</b>: Nothing.
@@ -373,6 +410,57 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_unique(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is
+ //! no element in the container with equivalent value.
+ //! and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_unique(detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... if and only if there is
+ //! no element in the container with equivalent value.
+ //! p is a hint pointing to where the insert
+ //! should start to search.
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_unique(hint, detail::forward_impl<Args>(args)...); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_unique(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_unique(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_unique(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _));}\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by p.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately
@@ -752,6 +840,40 @@
    const_reverse_iterator rend() const
    { return m_tree.rend(); }
 
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return m_tree.cbegin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return m_tree.cend(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin() const
+ { return m_tree.crbegin(); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
+ { return m_tree.crend(); }
+
    //! <b>Effects</b>: Returns true if the container contains no elements.
    //!
    //! <b>Throws</b>: Nothing.
@@ -857,6 +979,51 @@
    void insert(InputIterator first, InputIterator last)
    { m_tree.insert_equal(first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... and returns the iterator pointing to the
+ //! newly inserted element.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ { return m_tree.emplace_equal(detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)...
+ //!
+ //! <b>Returns</b>: An iterator pointing to the element with key equivalent
+ //! to the key of x.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
+ //! is inserted right before p.
+ template <class... Args>
+ iterator emplace_hint(const_iterator hint, Args&&... args)
+ { return m_tree.emplace_hint_equal(hint, detail::forward_impl<Args>(args)...); }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ iterator emplace()
+ { return m_tree.emplace_equal(); }
+
+ iterator emplace_hint(const_iterator hint)
+ { return m_tree.emplace_hint_equal(hint); }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_hint(const_iterator hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { return m_tree.emplace_hint_equal(hint, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); }\
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element pointed to by p.
    //!
    //! <b>Returns</b>: Returns an iterator pointing to the element immediately

Modified: branches/release/boost/interprocess/containers/slist.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/slist.hpp (original)
+++ branches/release/boost/interprocess/containers/slist.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -59,6 +59,12 @@
 #include <boost/interprocess/containers/detail/node_alloc_holder.hpp>
 #include <boost/intrusive/slist.hpp>
 
+
+#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+//Preprocessor library to emulate perfect forwarding
+#include <boost/interprocess/detail/preprocessor.hpp>
+#endif
+
 #include <iterator>
 #include <utility>
 #include <memory>
@@ -67,28 +73,43 @@
 
 namespace boost{ namespace interprocess{
 
-namespace detail {
 /// @cond
+
+namespace detail {
+
+template<class VoidPointer>
+struct slist_hook
+{
+ typedef typename bi::make_slist_base_hook
+ <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type type;
+};
+
 template <class T, class VoidPointer>
 struct slist_node
- : public bi::make_slist_base_hook
- <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type
+ : public slist_hook<VoidPointer>::type
 {
- typedef typename bi::make_slist_base_hook
- <bi::void_pointer<VoidPointer>, bi::link_mode<bi::normal_link> >::type hook_type;
+ #ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
    slist_node()
       : m_data()
    {}
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template<class Convertible>
- slist_node(const Convertible &value)
- : m_data(value){}
- #else
- template<class Convertible>
- slist_node(Convertible &&value)
- : m_data(detail::forward_impl<Convertible>(value)){}
- #endif
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ slist_node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ : m_data(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #else //#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template<class ...Args>
+ slist_node(Args &&...args)
+ : m_data(detail::forward_impl<Args>(args)...)
+ {}
+ #endif//#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
    T m_data;
 };
@@ -104,16 +125,17 @@
 
    typedef typename bi::make_slist
       <node_type
- ,bi::base_hook<typename node_type::hook_type>
+ ,bi::base_hook<typename slist_hook<void_pointer>::type>
       ,bi::constant_time_size<true>
       ,bi::size_type<typename A::size_type>
>::type container_type;
    typedef container_type type ;
 };
 
-/// @endcond
 } //namespace detail {
 
+/// @endcond
+
 //! An slist is a singly linked list: a list where each element is linked to the next
 //! element, but not to the previous element. That is, it is a Sequence that
 //! supports forward but not backward traversal, and (amortized) constant time
@@ -480,7 +502,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator begin() const
- { return const_iterator(this->non_const_icont().begin()); }
+ { return this->cbegin(); }
 
    //! <b>Effects</b>: Returns an iterator to the end of the list.
    //!
@@ -496,7 +518,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return const_iterator(this->non_const_icont().end()); }
+ { return this->cend(); }
 
    //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
    //! when incremented, yields begin(). This iterator may be used
@@ -516,6 +538,32 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator before_begin() const
+ { return this->cbefore_begin(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->non_const_icont().begin()); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->non_const_icont().end()); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+ //! that, when incremented, yields begin(). This iterator may be used
+ //! as the argument toinsert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbefore_begin() const
    { return const_iterator(end()); }
 
    //! <b>Effects</b>: Returns the number of the elements contained in the list.
@@ -638,7 +686,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references of
    //! previous values.
- iterator insert_after(iterator prev_pos, const value_type& x)
+ iterator insert_after(const_iterator prev_pos, const value_type& x)
    { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
@@ -655,10 +703,10 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references of
    //! previous values.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_after(iterator prev_pos, const detail::moved_object<value_type>& x)
+ iterator insert_after(const_iterator prev_pos, const detail::moved_object<value_type>& x)
    { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
    #else
- iterator insert_after(iterator prev_pos, value_type && x)
+ iterator insert_after(const_iterator prev_pos, value_type && x)
    { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(detail::move_impl(x)))); }
    #endif
 
@@ -672,7 +720,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references of
    //! previous values.
- void insert_after(iterator prev_pos, size_type n, const value_type& x)
+ void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
    { this->priv_create_and_insert_nodes(prev_pos, n, x); }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of *this.
@@ -688,7 +736,7 @@
    //! <b>Note</b>: Does not affect the validity of iterators and references of
    //! previous values.
    template <class InIter>
- void insert_after(iterator prev_pos, InIter first, InIter last)
+ void insert_after(const_iterator prev_pos, InIter first, InIter last)
    {
       const bool aux_boolean = detail::is_convertible<InIter, std::size_t>::value;
       typedef detail::bool_<aux_boolean> Result;
@@ -702,7 +750,7 @@
    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to the elements before p.
- iterator insert(iterator p, const value_type& x)
+ iterator insert(const_iterator p, const value_type& x)
    { return this->insert_after(previous(p), x); }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -713,10 +761,10 @@
    //!
    //! <b>Complexity</b>: Linear to the elements before p.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator p, const detail::moved_object<value_type>& x)
+ iterator insert(const_iterator p, const detail::moved_object<value_type>& x)
    { return this->insert_after(previous(p), x); }
    #else
- iterator insert(iterator p, value_type && x)
+ iterator insert(const_iterator p, value_type && x)
    { return this->insert_after(previous(p), detail::move_impl(x)); }
    #endif
 
@@ -727,7 +775,7 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
- void insert(iterator p, size_type n, const value_type& x)
+ void insert(const_iterator p, size_type n, const value_type& x)
    { return this->insert_after(previous(p), n, x); }
       
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -740,9 +788,101 @@
    //! <b>Complexity</b>: Linear to std::distance [first, last) plus
    //! linear to the elements before p.
    template <class InIter>
- void insert(iterator p, InIter first, InIter last)
+ void insert(const_iterator p, InIter first, InIter last)
    { return this->insert_after(previous(p), first, last); }
 
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the front of the list
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ { this->emplace_after(this->cbefore_begin(), detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ { return this->emplace_after(this->previous(p), detail::forward_impl<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... after prev
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace_after(const_iterator prev, Args&&... args)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)detail::get_pointer(d.get())) Node(detail::forward_impl<Args>(args)...);
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert_after(prev.get(), *node));
+ }
+
+ #else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //0 args
+ void emplace_front()
+ { this->emplace_after(this->cbefore_begin()); }
+
+ iterator emplace(const_iterator p)
+ { return this->emplace_after(this->previous(p)); }
+
+ iterator emplace_after(const_iterator prev)
+ {
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator());
+ new ((void*)detail::get_pointer(d.get())) Node();
+ NodePtr node = d.get();
+ d.release();
+ return iterator(this->icont().insert_after(prev.get(), *node));
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace \
+ (this->cbegin(), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace \
+ (const_iterator p, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_after \
+ (this->previous(p), BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace_after \
+ (const_iterator prev, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ typename AllocHolder::Deallocator d(AllocHolder::create_node_and_deallocator()); \
+ new ((void*)detail::get_pointer(d.get())) \
+ Node(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ NodePtr node = d.get(); \
+ d.release(); \
+ return iterator(this->icont().insert_after(prev.get(), *node)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
    //! <b>Effects</b>: Erases the element after the element pointed by prev_pos
    //! of the list.
    //!
@@ -754,7 +894,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
- iterator erase_after(iterator prev_pos)
+ iterator erase_after(const_iterator prev_pos)
    {
       return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
    }
@@ -770,7 +910,7 @@
    //! <b>Complexity</b>: Linear to the number of erased elements.
    //!
    //! <b>Note</b>: Does not invalidate iterators or references to non erased elements.
- iterator erase_after(iterator before_first, iterator last)
+ iterator erase_after(const_iterator before_first, const_iterator last)
    {
       return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
    }
@@ -782,7 +922,7 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements before p.
- iterator erase(iterator p)
+ iterator erase(const_iterator p)
    { return iterator(this->erase_after(previous(p))); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -793,7 +933,7 @@
    //!
    //! <b>Complexity</b>: Linear to the distance between first and last plus
    //! linear to the elements before first.
- iterator erase(iterator first, iterator last)
+ iterator erase(const_iterator first, const_iterator last)
    { return iterator(this->erase_after(previous(first), last)); }
 
    //! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -810,9 +950,9 @@
          cur = cur_next;
       }
       if (cur_next != end_n)
- this->erase_after(iterator(cur), iterator(end_n));
+ this->erase_after(const_iterator(cur), const_iterator(end_n));
       else
- this->insert_after(iterator(cur), new_size, x);
+ this->insert_after(const_iterator(cur), new_size, x);
    }
 
    //! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -832,10 +972,10 @@
          cur = cur_next;
       }
       if (cur_next != end_n){
- this->erase_after(iterator(cur), iterator(end_n));
+ this->erase_after(const_iterator(cur), const_iterator(end_n));
       }
       else{
- this->priv_create_and_insert_nodes(iterator(cur), new_size - len);
+ this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
       }
    }
 
@@ -860,7 +1000,7 @@
    //!
    //! <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_pos, slist& x)
+ void splice_after(const_iterator prev_pos, slist& x)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after(prev_pos.get(), x.icont());
@@ -870,7 +1010,7 @@
       }
    }
 
- //void splice_after(iterator prev_pos, const detail::moved_object<slist>& x)
+ //void splice_after(const_iterator prev_pos, const detail::moved_object<slist>& x)
    //{ this->splice_after(prev_pos, x.get()); }
 
    // Moves the element that follows prev to *this, inserting it immediately
@@ -890,7 +1030,7 @@
    //!
    //! <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_pos, slist& x, iterator prev)
+ void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
@@ -900,7 +1040,7 @@
       }
    }
 
- //void splice_after(iterator prev_pos, const detail::moved_object<slist>& x, iterator prev)
+ //void splice_after(const_iterator prev_pos, const detail::moved_object<slist>& x, iterator prev)
    //{ return splice_after(prev_pos, x.get(), prev); }
 
    // Moves the range [before_first + 1, before_last + 1) to *this,
@@ -921,8 +1061,8 @@
    //!
    //! <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_pos, slist& x,
- iterator before_first, iterator before_last)
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after
@@ -933,8 +1073,8 @@
       }
    }
 
- //void splice_after(iterator prev_pos, const detail::moved_object<slist>& x,
- // iterator before_first, iterator before_last)
+ //void splice_after(const_iterator prev_pos, const detail::moved_object<slist>& x,
+ // const_iterator before_first, const_iterator before_last)
    //{ this->splice_after(prev_pos, x.get(), before_first, before_last); }
 
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
@@ -952,8 +1092,8 @@
    //!
    //! <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_pos, slist& x,
- iterator before_first, iterator before_last,
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last,
                      size_type n)
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
@@ -965,8 +1105,8 @@
       }
    }
 
- //void splice_after(iterator prev_pos, const detail::moved_object<slist>& x,
- // iterator before_first, iterator before_last, size_type n)
+ //void splice_after(const_iterator prev_pos, const detail::moved_object<slist>& x,
+ // const_iterator before_first, const_iterator before_last, size_type n)
    //{ this->splice_after(prev_pos, x.get(), before_first, before_last, n); }
 
    //! <b>Requires</b>: p must point to an element contained
@@ -982,10 +1122,10 @@
    //!
    //! <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 p, slist& x)
+ void splice(const_iterator p, slist& x)
    { this->splice_after(this->previous(p), x); }
 
- //void splice(iterator p, const detail::moved_object<slist>& x)
+ //void splice(const_iterator p, const detail::moved_object<slist>& x)
    //{ return this->splice(p, x.get()); }
 
    //! <b>Requires</b>: p must point to an element contained
@@ -1002,10 +1142,10 @@
    //!
    //! <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 p, slist& x, iterator i)
+ void splice(const_iterator p, slist& x, const_iterator i)
    { this->splice_after(previous(p), x, i); }
 
- //void splice(iterator p, const detail::moved_object<slist>& x, iterator i)
+ //void splice(const_iterator p, const detail::moved_object<slist>& x, const_iterator i)
    //{ this->splice(p, x.get(), i); }
 
    //! <b>Requires</b>: p must point to an element contained
@@ -1022,10 +1162,10 @@
    //!
    //! <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 p, slist& x, iterator first, iterator last)
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
    { this->splice_after(previous(p), x, previous(first), previous(last)); }
 
- //void splice(iterator p, const detail::moved_object<slist>& x, iterator first, iterator last)
+ //void splice(const_iterator p, const detail::moved_object<slist>& x, const_iterator first, const_iterator last)
    //{ this->splice(p, x.get(), first, last); }
 
    //! <b>Effects</b>: Reverses the order of elements in the list.
@@ -1205,10 +1345,10 @@
    class insertion_functor
    {
       Icont &icont_;
- typename Icont::iterator prev_;
+ typename Icont::const_iterator prev_;
 
       public:
- insertion_functor(Icont &icont, typename Icont::iterator prev)
+ insertion_functor(Icont &icont, typename Icont::const_iterator prev)
          : icont_(icont), prev_(prev)
       {}
 
@@ -1241,13 +1381,13 @@
 
    //Dispatch to detect iterator range or integer overloads
    template <class InputIter>
- void priv_insert_dispatch(iterator prev,
+ void priv_insert_dispatch(const_iterator prev,
                              InputIter first, InputIter last,
                              detail::false_)
    { this->priv_create_and_insert_nodes(prev, first, last); }
 
    template<class Integer>
- void priv_insert_dispatch(iterator prev, Integer n, Integer x, detail::true_)
+ void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, detail::true_)
    { this->priv_create_and_insert_nodes(prev, n, x); }
 
    void priv_fill_assign(size_type n, const T& val)
@@ -1271,8 +1411,7 @@
    { this->priv_fill_assign((size_type) n, (T)val); }
 
    template <class InpIt>
- void priv_assign_dispatch(InpIt first, InpIt last,
- detail::false_)
+ void priv_assign_dispatch(InpIt first, InpIt last, detail::false_)
    {
       iterator end_n(this->end());
       iterator prev(this->before_begin());
@@ -1290,11 +1429,11 @@
    }
 
    template <class Int>
- void priv_insert_after_range_dispatch(iterator prev_pos, Int n, Int x, detail::true_)
+ void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, detail::true_)
    { this->priv_create_and_insert_nodes(prev_pos, n, x); }
 
    template <class InIter>
- void priv_insert_after_range_dispatch(iterator prev_pos, InIter first, InIter last, detail::false_)
+ void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, detail::false_)
    { this->priv_create_and_insert_nodes(prev_pos, first, last); }
 
    //Functors for member algorithm defaults

Modified: branches/release/boost/interprocess/containers/string.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/string.hpp (original)
+++ branches/release/boost/interprocess/containers/string.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -50,6 +50,8 @@
 #include <memory>
 #include <algorithm>
 #include <iosfwd>
+#include <istream>
+#include <ostream>
 #include <ios>
 #include <locale>
 #include <cstddef>

Modified: branches/release/boost/interprocess/containers/vector.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/vector.hpp (original)
+++ branches/release/boost/interprocess/containers/vector.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -68,6 +68,7 @@
 #include <boost/interprocess/detail/move_iterator.hpp>
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
+#include <boost/interprocess/detail/advanced_insert_int.hpp>
 
 namespace boost {
 namespace interprocess {
@@ -233,22 +234,72 @@
    { return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; }
 };
 
-//!This struct deallocates and allocated memory
-template <class A>
-struct vector_alloc_holder
+template <class T, class A>
+struct vector_value_traits
 {
- typedef typename A::pointer pointer;
- typedef typename A::size_type size_type;
- typedef typename A::value_type value_type;
-
+ typedef T value_type;
+ typedef A allocator_type;
    static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
    static const bool trivial_dctr_after_move =
- has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
    static const bool trivial_copy = has_trivial_copy<value_type>::value;
    static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
    static const bool trivial_assign = has_trivial_assign<value_type>::value;
    static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
 
+ //This is the anti-exception array destructor
+ //to deallocate values already constructed
+ typedef typename detail::if_c
+ <trivial_dctr
+ ,detail::null_scoped_destructor_n<allocator_type>
+ ,detail::scoped_destructor_n<allocator_type>
+ >::type OldArrayDestructor;
+ //This is the anti-exception array destructor
+ //to destroy objects created with copy construction
+ typedef typename detail::if_c
+ <nothrow_copy
+ ,detail::null_scoped_destructor_n<allocator_type>
+ ,detail::scoped_destructor_n<allocator_type>
+ >::type UCopiedArrayDestructor;
+ //This is the anti-exception array deallocator
+ typedef typename detail::if_c
+ <nothrow_copy
+ ,detail::null_scoped_array_deallocator<allocator_type>
+ ,detail::scoped_array_deallocator<allocator_type>
+ >::type UCopiedArrayDeallocator;
+
+ //This is the optimized move iterator for copy constructors
+ //so that std::copy and similar can use memcpy
+ typedef typename detail::if_c
+ <trivial_copy
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ || !is_movable<value_type>::value
+ #endif
+ ,const T*
+ ,detail::move_iterator<T*>
+ >::type copy_move_it;
+
+ //This is the optimized move iterator for assignments
+ //so that std::uninitialized_copy and similar can use memcpy
+ typedef typename detail::if_c
+ <trivial_assign
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ || !is_movable<value_type>::value
+ #endif
+ ,const T*
+ ,detail::move_iterator<T*>
+ >::type assign_move_it;
+};
+
+//!This struct deallocates and allocated memory
+template <class A>
+struct vector_alloc_holder
+{
+ typedef typename A::pointer pointer;
+ typedef typename A::size_type size_type;
+ typedef typename A::value_type value_type;
+ typedef vector_value_traits<value_type, A> value_traits;
+
    //Constructor, does not throw
    vector_alloc_holder(const A &a)
       : members_(a)
@@ -336,13 +387,13 @@
 
    void destroy(value_type* p)
    {
- if(!trivial_dctr)
+ if(!value_traits::trivial_dctr)
          detail::get_pointer(p)->~value_type();
    }
 
    void destroy_n(value_type* p, size_type n)
    {
- if(!trivial_dctr)
+ if(!value_traits::trivial_dctr)
          for(; n--; ++p) p->~value_type();
    }
 
@@ -398,10 +449,12 @@
    typedef std::reverse_iterator<const_iterator>
       const_reverse_iterator;
    //! The stored allocator type
- typedef allocator_type stored_allocator_type;
+ typedef allocator_type stored_allocator_type;
 
    /// @cond
    private:
+ typedef detail::advanced_insert_aux_int<T, T*> advanced_insert_aux_int_t;
+ typedef detail::vector_value_traits<value_type, A> value_traits;
 
    typedef typename base_t::allocator_v1 allocator_v1;
    typedef typename base_t::allocator_v2 allocator_v2;
@@ -410,48 +463,6 @@
    typedef constant_iterator<T, difference_type> cvalue_iterator;
    typedef repeat_iterator<T, difference_type> repeat_it;
    typedef detail::move_iterator<repeat_it> repeat_move_it;
- //This is the anti-exception array destructor
- //to deallocate values already constructed
- typedef typename detail::if_c
- <base_t::trivial_dctr
- ,detail::null_scoped_destructor_n<allocator_type>
- ,detail::scoped_destructor_n<allocator_type>
- >::type OldArrayDestructor;
- //This is the anti-exception array destructor
- //to destroy objects created with copy construction
- typedef typename detail::if_c
- <base_t::nothrow_copy
- ,detail::null_scoped_destructor_n<allocator_type>
- ,detail::scoped_destructor_n<allocator_type>
- >::type UCopiedArrayDestructor;
- //This is the anti-exception array deallocator
- typedef typename detail::if_c
- <base_t::nothrow_copy
- ,detail::null_scoped_array_deallocator<allocator_type>
- ,detail::scoped_array_deallocator<allocator_type>
- >::type UCopiedArrayDeallocator;
-
- //This is the optimized move iterator for copy constructors
- //so that std::copy and similar can use memcpy
- typedef typename detail::if_c
- <base_t::trivial_copy
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- || !is_movable<value_type>::value
- #endif
- ,T*
- ,detail::move_iterator<T*>
- >::type copy_move_it;
-
- //This is the optimized move iterator for assignments
- //so that std::uninitialized_copy and similar can use memcpy
- typedef typename detail::if_c
- <base_t::trivial_assign
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- || !is_movable<value_type>::value
- #endif
- ,T*
- ,detail::move_iterator<T*>
- >::type assign_move_it;
    /// @endcond
 
    public:
@@ -475,7 +486,7 @@
    vector(size_type n, const T& value = T(),
           const allocator_type& a = allocator_type())
       : base_t(a)
- { this->insert(this->end(), n, value); }
+ { this->insert(this->cend(), n, value); }
 
    //! <b>Effects</b>: Copy constructs a vector.
    //!
@@ -552,7 +563,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_iterator end() const
- { return const_iterator(this->members_.m_start + this->members_.m_size); }
+ { return this->cend(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
    //! of the reversed vector.
@@ -570,7 +581,7 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rbegin()const
- { return const_reverse_iterator(this->end());}
+ { return this->crbegin(); }
 
    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
    //! of the reversed vector.
@@ -588,6 +599,40 @@
    //!
    //! <b>Complexity</b>: Constant.
    const_reverse_iterator rend() const
+ { return this->crend(); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cbegin() const
+ { return const_iterator(this->members_.m_start); }
+
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator cend() const
+ { return const_iterator(this->members_.m_start + this->members_.m_size); }
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crbegin()const
+ { return const_reverse_iterator(this->end());}
+
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const
    { return const_reverse_iterator(this->begin()); }
 
    //! <b>Requires</b>: !empty()
@@ -623,8 +668,6 @@
    reference back()
    { return this->members_.m_start[this->members_.m_size - 1]; }
 
- //! <b>Requires</b>: !empty()
- //!
    //! <b>Effects</b>: Returns a const reference to the first element
    //! from the beginning of the container.
    //!
@@ -634,6 +677,24 @@
    const_reference back() const
    { return this->members_.m_start[this->members_.m_size - 1]; }
 
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ pointer data()
+ { return this->members_.m_start; }
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_pointer data() const
+ { return this->members_.m_start; }
+
    //! <b>Effects</b>: Returns the number of the elements contained in the vector.
    //!
    //! <b>Throws</b>: Nothing.
@@ -754,7 +815,9 @@
          //If there is no forward expansion, move objects
          else{
             //We will reuse insert code, so create a dummy input iterator
- copy_move_it dummy_it(detail::get_pointer(this->members_.m_start));
+ typename value_traits::copy_move_it dummy_it(detail::get_pointer(this->members_.m_start));
+ detail::advanced_insert_aux_proxy<T, typename value_traits::copy_move_it, T*>
+ proxy(dummy_it, dummy_it);
             //Backwards (and possibly forward) expansion
             if(ret.second){
                #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS
@@ -764,9 +827,8 @@
                   ( detail::get_pointer(ret.first)
                   , real_cap
                   , detail::get_pointer(this->members_.m_start)
- , dummy_it
- , dummy_it
- , 0);
+ , 0
+ , proxy);
             }
             //New buffer
             else{
@@ -777,8 +839,8 @@
                   ( detail::get_pointer(ret.first)
                   , real_cap
                   , detail::get_pointer(this->members_.m_start)
- , dummy_it
- , dummy_it);
+ , 0
+ , proxy);
             }
          }
       }
@@ -812,25 +874,16 @@
    vector<T, A>& operator=(const detail::moved_object<vector<T, A> >& mx)
    {
       vector<T, A> &x = mx.get();
-
- if (&x != this){
- this->swap(x);
- x.clear();
- }
- return *this;
- }
    #else
- vector<T, A>& operator=(vector<T, A> && mx)
+ vector<T, A>& operator=(vector<T, A> && x)
    {
- vector<T, A> &x = mx;
-
+ #endif
       if (&x != this){
          this->swap(x);
          x.clear();
       }
       return *this;
    }
- #endif
 
    //! <b>Effects</b>: Assigns the n copies of val to *this.
    //!
@@ -869,7 +922,7 @@
          ++this->members_.m_size;
       }
       else{
- this->insert(this->end(), x);
+ this->insert(this->cend(), x);
       }
    }
 
@@ -882,28 +935,122 @@
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void push_back(const detail::moved_object<T> & mx)
    {
+ value_type &x = mx.get();
+ #else
+ void push_back(T && x)
+ {
+ #endif
+ if (this->members_.m_size < this->members_.m_capacity){
+ //There is more memory, just construct a new object at the end
+ new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(detail::move_impl(x));
+ ++this->members_.m_size;
+ }
+ else{
+ this->insert(this->cend(), detail::move_impl(x));
+ }
+ }
+
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the vector.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ template<class ...Args>
+ void emplace_back(Args &&...args)
+ {
+ T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
       if (this->members_.m_size < this->members_.m_capacity){
          //There is more memory, just construct a new object at the end
- new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx);
+ new((void*)(back_pos))value_type(detail::forward_impl<Args>(args)...);
          ++this->members_.m_size;
       }
       else{
- this->insert(this->end(), mx);
+ detail::advanced_insert_aux_emplace<T, T*, Args...> proxy
+ (detail::forward_impl<Args>(args)...);
+ priv_range_insert(back_pos, 1, proxy);
       }
    }
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
+ //!
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template<class ...Args>
+ iterator emplace(const_iterator position, Args && ...args)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ detail::advanced_insert_aux_emplace<T, T*, Args...> proxy
+ (detail::forward_impl<Args>(args)...);
+ priv_range_insert(position.get_ptr(), 1, proxy);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
    #else
- void push_back(T && mx)
+
+ void emplace_back()
    {
+ T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
       if (this->members_.m_size < this->members_.m_capacity){
          //There is more memory, just construct a new object at the end
- new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(detail::move_impl(mx));
+ new((void*)(back_pos))value_type();
          ++this->members_.m_size;
       }
       else{
- this->insert(this->end(), detail::move_impl(mx));
+ detail::advanced_insert_aux_emplace<value_type, T*> proxy;
+ priv_range_insert(back_pos, 1, proxy);
       }
    }
- #endif
+
+ iterator emplace(const_iterator position)
+ {
+ size_type pos_n = position - cbegin();
+ detail::advanced_insert_aux_emplace<value_type, T*> proxy;
+ priv_range_insert(detail::get_pointer(position.get_ptr()), 1, proxy);
+ return iterator(this->members_.m_start + pos_n);
+ }
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ T* back_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size; \
+ if (this->members_.m_size < this->members_.m_capacity){ \
+ new((void*)(back_pos))value_type \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ ++this->members_.m_size; \
+ } \
+ else{ \
+ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ priv_range_insert(back_pos, 1, proxy); \
+ } \
+ } \
+ \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ iterator emplace(const_iterator pos, BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ { \
+ size_type pos_n = pos - cbegin(); \
+ detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
+ <value_type, T*, BOOST_PP_ENUM_PARAMS(n, P)> \
+ proxy(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ priv_range_insert(detail::get_pointer(pos.get_ptr()), 1, proxy); \
+ return iterator(this->members_.m_start + pos_n); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
   
    //! <b>Effects</b>: Swaps the contents of *this and x.
    //! If this->allocator_type() != x.allocator_type()
@@ -912,7 +1059,11 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void swap(vector<T, A>& x)
+ #else
+ void swap(vector<T, A> && x)
+ #endif
    {
       allocator_type &this_al = this->alloc(), &other_al = x.alloc();
       //Just swap internals
@@ -925,6 +1076,7 @@
       }
    }
 
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    //! <b>Effects</b>: Swaps the contents of *this and x.
    //! If this->allocator_type() != x.allocator_type()
    //! allocators are also swapped.
@@ -932,18 +1084,11 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    void swap(const detail::moved_object<vector<T, A> >& mx)
    {
       vector<T, A> &x = mx.get();
       this->swap(x);
    }
- #else
- void swap(vector<T, A> && mx)
- {
- vector<T, A> &x = mx;
- this->swap(x);
- }
    #endif
 
    //! <b>Requires</b>: position must be a valid iterator of *this.
@@ -952,14 +1097,14 @@
    //!
    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
    //!
- //! <b>Complexity</b>: If position is begin() or end(), amortized constant time
+ //! <b>Complexity</b>: If position is end(), amortized constant time
    //! Linear time otherwise.
- iterator insert(iterator position, const T& x)
+ iterator insert(const_iterator position, const T& x)
    {
       //Just call more general insert(pos, size, value) and return iterator
- size_type n = position - begin();
+ size_type pos_n = position - cbegin();
       this->insert(position, (size_type)1, x);
- return iterator(this->members_.m_start + n);
+ return iterator(this->members_.m_start + pos_n);
    }
 
    //! <b>Requires</b>: position must be a valid iterator of *this.
@@ -968,29 +1113,23 @@
    //!
    //! <b>Throws</b>: If memory allocation throws.
    //!
- //! <b>Complexity</b>: If position is begin() or end(), amortized constant time
+ //! <b>Complexity</b>: If position is end(), amortized constant time
    //! Linear time otherwise.
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<T> &mx)
+ iterator insert(const_iterator position, const detail::moved_object<T> &mx)
    {
- //Just call more general insert(pos, size, value) and return iterator
- size_type n = position - begin();
- this->insert(position
- ,repeat_move_it(repeat_it(mx.get(), 1))
- ,repeat_move_it(repeat_it()));
- return iterator(this->members_.m_start + n);
- }
+ value_type &x = mx.get();
    #else
- iterator insert(iterator position, T &&mx)
+ iterator insert(const_iterator position, T &&x)
    {
+ #endif
       //Just call more general insert(pos, size, value) and return iterator
- size_type n = position - begin();
+ size_type pos_n = position - cbegin();
       this->insert(position
- ,repeat_move_it(repeat_it(mx, 1))
+ ,repeat_move_it(repeat_it(x, 1))
                   ,repeat_move_it(repeat_it()));
- return iterator(this->members_.m_start + n);
+ return iterator(this->members_.m_start + pos_n);
    }
- #endif
 
    //! <b>Requires</b>: pos must be a valid iterator of *this.
    //!
@@ -1001,7 +1140,7 @@
    //!
    //! <b>Complexity</b>: Linear to std::distance [first, last).
    template <class InIt>
- void insert(iterator pos, InIt first, InIt last)
+ void insert(const_iterator pos, InIt first, InIt last)
    {
       //Dispatch depending on integer/iterator
       const bool aux_boolean = detail::is_convertible<InIt, std::size_t>::value;
@@ -1016,7 +1155,7 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to n.
- void insert (iterator p, size_type n, const T& x)
+ void insert(const_iterator p, size_type n, const T& x)
    { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
 
    //! <b>Effects</b>: Removes the last element from the vector.
@@ -1041,7 +1180,7 @@
    {
       T *pos = detail::get_pointer(position.get_ptr());
       T *beg = detail::get_pointer(this->members_.m_start);
-
+ typedef typename value_traits::assign_move_it assign_move_it;
       std::copy(assign_move_it(pos + 1), assign_move_it(beg + this->members_.m_size), pos);
       --this->members_.m_size;
       //Destroy last element
@@ -1056,6 +1195,7 @@
    //! <b>Complexity</b>: Linear to the distance between first and last.
    iterator erase(const_iterator first, const_iterator last)
    {
+ typedef typename value_traits::assign_move_it assign_move_it;
       if (first != last){ // worth doing, copy down over hole
          T* end_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
          T* ptr = detail::get_pointer(std::copy
@@ -1081,11 +1221,11 @@
       pointer finish = this->members_.m_start + this->members_.m_size;
       if (new_size < size()){
          //Destroy last elements
- this->erase(iterator(this->members_.m_start + new_size), this->end());
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
       }
       else{
          //Insert new elements at the end
- this->insert(iterator(finish), new_size - this->size(), x);
+ this->insert(const_iterator(finish), new_size - this->size(), x);
       }
    }
 
@@ -1099,17 +1239,13 @@
    {
       if (new_size < this->size()){
          //Destroy last elements
- this->erase(iterator(this->members_.m_start + new_size), this->end());
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
       }
       else{
          size_type n = new_size - this->size();
          this->reserve(new_size);
- T *ptr = detail::get_pointer(this->members_.m_start + this->members_.m_size);
- while(n--){
- //Default construct
- new((void*)ptr++)T();
- ++this->members_.m_size;
- }
+ detail::default_construct_aux_proxy<T, T*, size_type> proxy(n);
+ priv_range_insert(this->cend().get_ptr(), n, proxy);
       }
    }
 
@@ -1174,76 +1310,86 @@
    }
 
    template <class FwdIt>
- void priv_range_insert(pointer pos, FwdIt first,
- FwdIt last, std::forward_iterator_tag)
+ void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
    {
- if (first != last){
- size_type n = std::distance(first, last);
- //Check if we have enough memory or try to expand current memory
- size_type remaining = this->members_.m_capacity - this->members_.m_size;
- bool same_buffer_start;
- std::pair<pointer, bool> ret;
- size_type real_cap = this->members_.m_capacity;
+ if(first != last){
+ const size_type n = std::distance(first, last);
+ detail::advanced_insert_aux_proxy<T, FwdIt, T*> proxy(first, last);
+ priv_range_insert(pos, n, proxy);
+ }
+ }
 
- //Check if we already have room
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new
- //buffer or expand the old one.
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
-
- //Check for forward expansion
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
- }
- }
-
- //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
- , detail::get_pointer(pos)
- , first
- , last
- , n);
- }
- //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
- , detail::get_pointer(pos)
- , first
- , last);
+ void priv_range_insert(pointer pos, const size_type n,
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+ advanced_insert_aux_int_t &&interf
+ #else
+ advanced_insert_aux_int_t &interf
+ #endif
+ )
+ {
+ //Check if we have enough memory or try to expand current memory
+ size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ bool same_buffer_start;
+ std::pair<pointer, bool> ret;
+ size_type real_cap = this->members_.m_capacity;
+
+ //Check if we already have room
+ if (n <= remaining){
+ same_buffer_start = true;
+ }
+ else{
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ size_type new_cap = this->next_capacity(n);
+ ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
+
+ //Check for forward expansion
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ this->members_.m_capacity = real_cap;
          }
       }
+
+ //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), n, interf);
+ }
+ //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
+ , detail::get_pointer(pos)
+ , n
+ , interf);
+ }
+ //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
+ , detail::get_pointer(pos)
+ , n
+ , interf);
+ }
    }
 
- template <class FwdIt>
- void priv_range_insert_expand_forward
- (T* pos, FwdIt first, FwdIt last, size_type n)
+ void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
    {
+ typedef typename value_traits::copy_move_it copy_move_it;
+ typedef typename value_traits::assign_move_it assign_move_it;
       //There is enough memory
       T* old_finish = detail::get_pointer(this->members_.m_start) + this->members_.m_size;
       const size_type elems_after = old_finish - pos;
@@ -1256,35 +1402,32 @@
          //Copy previous to last objects to the initialized end
          std::copy_backward(assign_move_it(pos), assign_move_it(old_finish - n), old_finish);
          //Insert new objects in the pos
- std::copy(first, last, pos);
+ interf.copy_all_to(pos);
       }
       else {
          //The new elements don't fit in the [pos, end()) range. Copy
          //to the beginning of the unallocated zone the last new elements.
- FwdIt mid = first;
- std::advance(mid, elems_after);
- std::uninitialized_copy(mid, last, old_finish);
+ interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
          this->members_.m_size += n - elems_after;
          //Copy old [pos, end()) elements to the uninitialized memory
          std::uninitialized_copy
- ( copy_move_it(pos)
- , copy_move_it(old_finish)
+ ( copy_move_it(pos), copy_move_it(old_finish)
             , detail::get_pointer(this->members_.m_start) + this->members_.m_size);
          this->members_.m_size += elems_after;
          //Copy first new elements in pos
- std::copy(first, mid, pos);
+ interf.copy_all_to(pos);
       }
    }
 
- template <class FwdIt>
    void priv_range_insert_new_allocation
- (T* new_start, size_type new_cap, T* pos, FwdIt first, FwdIt last)
+ (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
    {
+ typedef typename value_traits::copy_move_it copy_move_it;
       T* new_finish = new_start;
       T *old_finish;
       //Anti-exception rollbacks
- UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
- UCopiedArrayDestructor construted_values_destroyer(new_start, 0u);
+ typename value_traits::UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
+ typename value_traits::UCopiedArrayDestructor constructed_values_destroyer(new_start, 0u);
 
       //Initialize with [begin(), pos) old buffer
       //the start of the new buffer
@@ -1292,11 +1435,11 @@
          ( copy_move_it(detail::get_pointer(this->members_.m_start))
          , copy_move_it(pos)
          , old_finish = new_finish);
- construted_values_destroyer.increment_size(new_finish - old_finish);
+ constructed_values_destroyer.increment_size(new_finish - old_finish);
       //Initialize new objects, starting from previous point
- new_finish = std::uninitialized_copy
- (first, last, old_finish = new_finish);
- construted_values_destroyer.increment_size(new_finish - old_finish);
+ interf.uninitialized_copy_all_to(old_finish = new_finish);
+ new_finish += n;
+ constructed_values_destroyer.increment_size(new_finish - old_finish);
       //Initialize from the rest of the old buffer,
       //starting from previous point
       new_finish = std::uninitialized_copy
@@ -1305,12 +1448,12 @@
          , new_finish);
 
       //All construction successful, disable rollbacks
- construted_values_destroyer.release();
+ constructed_values_destroyer.release();
       scoped_alloc.release();
       //Destroy and deallocate old elements
       //If there is allocated memory, destroy and deallocate
       if(this->members_.m_start != 0){
- if(!base_t::trivial_dctr_after_move)
+ if(!value_traits::trivial_dctr_after_move)
             this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
          this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
       }
@@ -1319,11 +1462,13 @@
       this->members_.m_capacity = new_cap;
    }
 
- template <class FwdIt>
    void priv_range_insert_expand_backwards
          (T* new_start, size_type new_capacity,
- T* pos, FwdIt first, FwdIt last, size_type n)
+ T* pos, const size_type n, advanced_insert_aux_int_t &interf)
    {
+ typedef typename value_traits::copy_move_it copy_move_it;
+ typedef typename value_traits::assign_move_it assign_move_it;
+
       //Backup old data
       T* old_start = detail::get_pointer(this->members_.m_start);
       T* old_finish = old_start + this->members_.m_size;
@@ -1340,74 +1485,70 @@
 
       //If anything goes wrong, this object will destroy
       //all the old objects to fulfill previous vector state
- OldArrayDestructor old_values_destroyer(old_start, old_size);
-
- //Check if s_before is so big that even copying the old data + new data
- //there is a gap between the new data and the old data
- if(s_before >= (old_size + n)){
- //Old situation:
- // _________________________________________________________
- //| raw_mem | old_begin | old_end |
- //| __________________________________|___________|_________|
- //
- //New situation:
- // _________________________________________________________
- //| old_begin | new | old_end | raw_mem |
- //|___________|__________|_________|________________________|
- //
- //Copy first old values before pos, after that the
- //new objects
- boost::interprocess::uninitialized_copy_copy
- (copy_move_it(old_start), copy_move_it(pos), first, last, new_start);
- UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
- //Now initialize the rest of memory with the last old values
- std::uninitialized_copy
- (copy_move_it(pos), copy_move_it(old_finish), new_start + elemsbefore + n);
- //All new elements correctly constructed, avoid new element destruction
- new_values_destroyer.release();
- this->members_.m_size = old_size + n;
- //Old values destroyed automatically with "old_values_destroyer"
- //when "old_values_destroyer" goes out of scope unless the have trivial
- //destructor after move.
- if(base_t::trivial_dctr_after_move)
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
+ //Check if s_before is big enough to hold the beginning of old data + new data
+ if(difference_type(s_before) >= difference_type(elemsbefore + n)){
+ //Copy first old values before pos, after that the new objects
+ std::uninitialized_copy(copy_move_it(old_start), copy_move_it(pos), new_start);
+ this->members_.m_size = elemsbefore;
+ interf.uninitialized_copy_all_to(new_start + elemsbefore);
+ this->members_.m_size += n;
+ //Check if s_before is so big that even copying the old data + new data
+ //there is a gap between the new data and the old data
+ if(s_before >= (old_size + n)){
+ //Old situation:
+ // _________________________________________________________
+ //| raw_mem | old_begin | old_end |
+ //| __________________________________|___________|_________|
+ //
+ //New situation:
+ // _________________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|__________|_________|________________________|
+ //
+ //Now initialize the rest of memory with the last old values
+ std::uninitialized_copy
+ (copy_move_it(pos), copy_move_it(old_finish), new_start + elemsbefore + n);
+ //All new elements correctly constructed, avoid new element destruction
+ this->members_.m_size = old_size + n;
+ //Old values destroyed automatically with "old_values_destroyer"
+ //when "old_values_destroyer" goes out of scope unless the have trivial
+ //destructor after move.
+ if(value_traits::trivial_dctr_after_move)
+ old_values_destroyer.release();
+ }
+ //s_before is so big that divides old_end
+ else{
+ //Old situation:
+ // __________________________________________________
+ //| raw_mem | old_begin | old_end |
+ //| ___________________________|___________|_________|
+ //
+ //New situation:
+ // __________________________________________________
+ //| old_begin | new | old_end | raw_mem |
+ //|___________|__________|_________|_________________|
+ //
+ //Now initialize the rest of memory with the last old values
+ //All new elements correctly constructed, avoid new element destruction
+ size_type raw_gap = s_before - (elemsbefore + n);
+ //Now initialize the rest of s_before memory with the
+ //first of elements after new values
+ std::uninitialized_copy
+ (copy_move_it(pos), copy_move_it(pos + raw_gap), new_start + elemsbefore + n);
+ //Update size since we have a contiguous buffer
+ this->members_.m_size = old_size + s_before;
+ //All new elements correctly constructed, avoid old element destruction
             old_values_destroyer.release();
- }
- //Check if s_before is so big that divides old_end
- else if(difference_type(s_before) >= difference_type(elemsbefore + n)){
- //Old situation:
- // __________________________________________________
- //| raw_mem | old_begin | old_end |
- //| ___________________________|___________|_________|
- //
- //New situation:
- // __________________________________________________
- //| old_begin | new | old_end | raw_mem |
- //|___________|__________|_________|_________________|
- //
- //Copy first old values before pos, after that the
- //new objects
- boost::interprocess::uninitialized_copy_copy
- (copy_move_it(old_start), copy_move_it(pos), first, last, new_start);
- UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
- size_type raw_gap = s_before - (elemsbefore + n);
- //Now initialize the rest of s_before memory with the
- //first of elements after new values
- std::uninitialized_copy
- (copy_move_it(pos), copy_move_it(pos + raw_gap), new_start + elemsbefore + n);
- //All new elements correctly constructed, avoid new element destruction
- new_values_destroyer.release();
- //All new elements correctly constructed, avoid old element destruction
- old_values_destroyer.release();
- //Update size since we have a contiguous buffer
- this->members_.m_size = old_size + s_before;
- //Now copy remaining last objects in the old buffer begin
- T *to_destroy = std::copy(assign_move_it(pos + raw_gap), assign_move_it(old_finish), old_start);
- //Now destroy redundant elements except if they were moved and
- //they have trivial destructor after move
- size_type n_destroy = old_finish - to_destroy;
- if(!base_t::trivial_dctr_after_move)
- this->destroy_n(to_destroy, n_destroy);
- this->members_.m_size -= n_destroy;
+ //Now copy remaining last objects in the old buffer begin
+ T *to_destroy = std::copy(assign_move_it(pos + raw_gap), assign_move_it(old_finish), old_start);
+ //Now destroy redundant elements except if they were moved and
+ //they have trivial destructor after move
+ size_type n_destroy = old_finish - to_destroy;
+ if(!value_traits::trivial_dctr_after_move)
+ this->destroy_n(to_destroy, n_destroy);
+ this->members_.m_size -= n_destroy;
+ }
       }
       else{
          //Check if we have to do the insertion in two phases
@@ -1430,13 +1571,6 @@
          //|____________________________|____________________|
          //
          bool do_after = n > s_before;
- FwdIt before_end = first;
- //If we have to expand both sides,
- //we will play if the first new values so
- //calculate the upper bound of new values
- if(do_after){
- std::advance(before_end, s_before);
- }
 
          //Now we can have two situations: the raw_mem of the
          //beginning divides the old_begin, or the new elements:
@@ -1466,8 +1600,7 @@
             //
             //Copy the first part of old_begin to raw_mem
             T *start_n = old_start + difference_type(s_before);
- std::uninitialized_copy
- (copy_move_it(old_start), copy_move_it(start_n), new_start);
+ std::uninitialized_copy(copy_move_it(old_start), copy_move_it(start_n), new_start);
             //The buffer is all constructed until old_end,
             //release destroyer and update size
             old_values_destroyer.release();
@@ -1476,22 +1609,27 @@
             T* next = std::copy(assign_move_it(start_n), assign_move_it(pos), old_start);
             if(do_after){
                //Now copy the new_beg elements
- std::copy(first, before_end, next);
+ interf.copy_some_and_update(next, s_before, true);
             }
             else{
                //Now copy the all the new elements
- T* move_start = std::copy(first, last, next);
+ interf.copy_all_to(next);
+ T* move_start = next + n;
                //Now displace old_end elements
                T* move_end = std::copy(assign_move_it(pos), assign_move_it(old_finish), move_start);
                //Destroy remaining moved elements from old_end except if
                //they have trivial destructor after being moved
                difference_type n_destroy = s_before - n;
- if(!base_t::trivial_dctr_after_move)
+ if(!value_traits::trivial_dctr_after_move)
                   this->destroy_n(move_end, n_destroy);
                this->members_.m_size -= n_destroy;
             }
          }
          else {
+ //If we have to expand both sides,
+ //we will play if the first new values so
+ //calculate the upper bound of new values
+
             //The raw memory divides the new elements
             //
             //If we need two phase construction (do_after)
@@ -1514,29 +1652,30 @@
             //|___________|_____|_________|__________________________|
             //
             //First copy whole old_begin and part of new to raw_mem
- FwdIt mid = first;
- size_type n_new_init = difference_type(s_before) - elemsbefore;
- std::advance(mid, n_new_init);
- boost::interprocess::uninitialized_copy_copy
- (copy_move_it(old_start), copy_move_it(pos), first, mid, new_start);
+ std::uninitialized_copy(copy_move_it(old_start), copy_move_it(pos), new_start);
+ this->members_.m_size = elemsbefore;
+
+ const size_type mid_n = difference_type(s_before) - elemsbefore;
+ interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
+ this->members_.m_size = old_size + s_before;
             //The buffer is all constructed until old_end,
             //release destroyer and update size
             old_values_destroyer.release();
- this->members_.m_size = old_size + s_before;
 
             if(do_after){
                //Copy new_beg part
- std::copy(mid, before_end, old_start);
+ interf.copy_some_and_update(old_start, s_before - mid_n, true);
             }
             else{
                //Copy all new elements
- T* move_start = std::copy(mid, last, old_start);
+ interf.copy_all_to(old_start);
+ T* move_start = old_start + (n-mid_n);
                //Displace old_end
                T* move_end = std::copy(copy_move_it(pos), copy_move_it(old_finish), move_start);
                //Destroy remaining moved elements from old_end except if they
                //have trivial destructor after being moved
                difference_type n_destroy = s_before - n;
- if(!base_t::trivial_dctr_after_move)
+ if(!value_traits::trivial_dctr_after_move)
                   this->destroy_n(move_end, n_destroy);
                this->members_.m_size -= n_destroy;
             }
@@ -1567,9 +1706,6 @@
             const size_type n_after = n - s_before;
             const difference_type elemsafter = old_size - elemsbefore;
 
- //The new_end part is [first + (n - n_after), last)
- std::advance(first, n - n_after);
-
             //We can have two situations:
             if (elemsafter > difference_type(n_after)){
                //The raw_mem from end will divide displaced old_end
@@ -1592,7 +1728,8 @@
                //Displace the rest of old_end to the new position
                std::copy_backward(assign_move_it(pos), assign_move_it(finish_n), old_finish);
                //Now overwrite with new_end
- std::copy(first, last, pos);
+ //The new_end part is [first + (n - n_after), last)
+ interf.copy_all_to(pos);
             }
             else {
                //The raw_mem from end will divide new_end part
@@ -1607,45 +1744,44 @@
                //| old_begin + new_beg | new_end |old_end | raw_mem |
                //|__________________________|_______________|________|_________|
                //
- FwdIt mid = first;
- std::advance(mid, elemsafter);
+ size_type mid_last_dist = n_after - elemsafter;
                //First initialize data in raw memory
- boost::interprocess::uninitialized_copy_copy
- ( mid, last, copy_move_it(pos), copy_move_it(old_finish), old_finish);
- this->members_.m_size += n_after;
+ //The new_end part is [first + (n - n_after), last)
+ interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ this->members_.m_size += mid_last_dist;
+ std::uninitialized_copy(copy_move_it(pos), copy_move_it(old_finish), old_finish + mid_last_dist);
+ this->members_.m_size += n_after - mid_last_dist;
                //Now copy the part of new_end over constructed elements
- std::copy(first, mid, pos);
+ interf.copy_all_to(pos);
             }
          }
       }
    }
 
    template <class InIt>
- void priv_range_insert(iterator pos,
- InIt first, InIt last,
- std::input_iterator_tag)
+ void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag)
    {
- //Insert range before the pos position
- std::copy(std::inserter(*this, pos), first, last);
+ for(;first != last; ++first){
+ this->insert(pos, detail::move_impl(value_type(*first)));
+ }
    }
 
    template <class InIt>
- void priv_assign_aux(InIt first, InIt last,
- std::input_iterator_tag)
+ void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag)
    {
       //Overwrite all elements we can from [first, last)
       iterator cur = begin();
       for ( ; first != last && cur != end(); ++cur, ++first){
          *cur = *first;
       }
-
+
       if (first == last){
          //There are no more elements in the sequence, erase remaining
- this->erase(cur, end());
+ this->erase(cur, cend());
       }
       else{
          //There are more elements in the range, insert the remaining ones
- this->insert(this->end(), first, last);
+ this->insert(this->cend(), first, last);
       }
    }
 
@@ -1697,7 +1833,7 @@
          }
       }
       else if(!ret.second){
- UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
+ typename value_traits::UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
          std::uninitialized_copy(first, last, detail::get_pointer(ret.first));
          scoped_alloc.release();
          //Destroy and deallocate old buffer
@@ -1711,11 +1847,10 @@
       }
       else{
          //Backwards expansion
- //If anything goes wrong, this object will destroy
- //all old objects
+ //If anything goes wrong, this object will destroy old objects
          T *old_start = detail::get_pointer(this->members_.m_start);
          size_type old_size = this->members_.m_size;
- OldArrayDestructor old_values_destroyer(old_start, old_size);
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, old_size);
          //If something goes wrong size will be 0
          //but holding the whole buffer
          this->members_.m_size = 0;
@@ -1725,9 +1860,10 @@
          //Backup old buffer data
          size_type old_offset = old_start - detail::get_pointer(ret.first);
          size_type first_count = min_value(n, old_offset);
- boost::interprocess::uninitialized_copy_n
- (first, first_count, detail::get_pointer(ret.first));
- FwdIt mid = first + first_count;
+
+ FwdIt mid = first;
+ std::advance(mid, first_count);
+ std::uninitialized_copy(first, mid, detail::get_pointer(ret.first));
 
          if(old_offset > n){
             //All old elements will be destroyed by "old_values_destroyer"
@@ -1741,16 +1877,14 @@
             this->members_.m_size = first_count + old_size;
             //Now overwrite the old values
             size_type second_count = min_value(old_size, n - first_count);
- copy_n(mid, second_count, old_start);
- mid += second_count;
+ FwdIt mid2 = mid;
+ std::advance(mid2, second_count);
+ std::copy(mid, mid2, old_start);
             
             //Check if we still have to append elements in the
             //uninitialized end
             if(second_count == old_size){
- boost::interprocess::uninitialized_copy_n
- ( mid
- , n - first_count - second_count
- , old_start + old_size);
+ std::copy(mid2, last, old_start + old_size);
             }
             else{
                //We have to destroy some old values
@@ -1777,11 +1911,11 @@
    }
 
    template <class Integer>
- void priv_insert_dispatch( iterator pos, Integer n, Integer val, detail::true_)
+ void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, detail::true_)
    { this->insert(pos, (size_type)n, (T)val); }
 
    template <class InIt>
- void priv_insert_dispatch(iterator pos, InIt first,
+ void priv_insert_dispatch(const_iterator pos, InIt first,
                              InIt last, detail::false_)
    {
       //Dispatch depending on integer/iterator

Modified: branches/release/boost/interprocess/detail/algorithms.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/algorithms.hpp (original)
+++ branches/release/boost/interprocess/detail/algorithms.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -73,7 +73,6 @@
    new((void*)dest)T();
 }
 
-
 template<class InIt, class OutIt>
 struct optimize_assign
 {
@@ -108,7 +107,6 @@
    : public optimize_copy<const T*, T*>
 {};
 
-
 template<class InIt, class OutIt> inline
 OutIt copy_n_dispatch(InIt first, typename std::iterator_traits<InIt>::difference_type length, OutIt dest, detail::bool_<false>)
 {
@@ -121,7 +119,7 @@
 T *copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, detail::bool_<true>)
 {
    std::size_t size = length*sizeof(T);
- return ((T*)std::memmove(dest, first, size)) + size;
+ return (static_cast<T*>(std::memmove(dest, first, size))) + size;
 }
 
 template<class InIt, class OutIt> inline
@@ -159,13 +157,11 @@
    BOOST_CATCH_END
    return dest;
 }
-
-
 template<class T> inline
 T *uninitialized_copy_n_dispatch(const T *first, typename std::iterator_traits<const T*>::difference_type length, T *dest, detail::bool_<true>)
 {
    std::size_t size = length*sizeof(T);
- return ((T*)std::memmove(dest, first, size)) + size;
+ return (static_cast<T*>(std::memmove(dest, first, size))) + size;
 }
 
 template<class InIt, class FwdIt> inline
@@ -178,7 +174,6 @@
    return uninitialized_copy_n_dispatch(first, count, dest, detail::bool_<do_optimized_copy>());
 }
 
-
 // uninitialized_copy_copy
 // Copies [first1, last1) into [result, result + (last1 - first1)), and
 // copies [first2, last2) into
@@ -194,7 +189,7 @@
    }
    BOOST_CATCH(...){
       for(;result != mid; ++result){
- result->~value_type();
+ detail::get_pointer(&*result)->~value_type();
       }
       BOOST_RETHROW
    }

Modified: branches/release/boost/interprocess/detail/atomic.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/atomic.hpp (original)
+++ branches/release/boost/interprocess/detail/atomic.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -60,13 +60,13 @@
 //! "mem": pointer to the atomic value
 //! Returns the old value pointed to by mem
 inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem)
-{ return winapi::interlocked_decrement((volatile long*)mem) + 1; }
+{ return winapi::interlocked_decrement(reinterpret_cast<volatile long*>(mem)) + 1; }
 
 //! Atomically increment an apr_uint32_t by 1
 //! "mem": pointer to the object
 //! Returns the old value pointed to by mem
 inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem)
-{ return winapi::interlocked_increment((volatile long*)mem)-1; }
+{ return winapi::interlocked_increment(reinterpret_cast<volatile long*>(mem))-1; }
 
 //! Atomically read an boost::uint32_t from memory
 inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem)
@@ -76,7 +76,7 @@
 //! "mem": pointer to the object
 //! "param": val value that the object will assume
 inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val)
-{ winapi::interlocked_exchange((volatile long*)mem, val); }
+{ winapi::interlocked_exchange(reinterpret_cast<volatile long*>(mem), val); }
 
 //! Compare an boost::uint32_t's value with "cmp".
 //! If they are the same swap the value with "with"
@@ -86,7 +86,7 @@
 //! Returns the old value of *mem
 inline boost::uint32_t atomic_cas32
    (volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp)
-{ return winapi::interlocked_compare_exchange((volatile long*)mem, with, cmp); }
+{ return winapi::interlocked_compare_exchange(reinterpret_cast<volatile long*>(mem), with, cmp); }
 
 } //namespace detail{
 } //namespace interprocess{

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -40,4 +40,8 @@
    #pragma warning (disable : 4786) // identifier truncated in debug info
    #pragma warning (disable : 4996) // "function": was declared deprecated
    #pragma warning (disable : 4197) // top-level volatile in cast is ignored
+ #pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
+ // with /GR-; unpredictable behavior may result
+ #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
+ #pragma warning (disable : 4671) // the copy constructor is inaccessible
 #endif

Modified: branches/release/boost/interprocess/detail/intersegment_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/intersegment_ptr.hpp (original)
+++ branches/release/boost/interprocess/detail/intersegment_ptr.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -128,13 +128,13 @@
    {
       const std::size_t mask = ~(align - 1);
       std::size_t beg = this->members.relative.beg;
- return (void*)((((std::size_t)this) & mask) - (beg << align_bits));
+ return reinterpret_cast<void*>((((std::size_t)this) & mask) - (beg << align_bits));
    }
 
    void relative_set_begin_from_base(void *addr)
    {
- assert(addr < (void*)this);
- std::size_t off = (char*)this - (char*)addr;
+ assert(addr < static_cast<void*>(this));
+ std::size_t off = reinterpret_cast<char*>(this) - reinterpret_cast<char*>(addr);
       members.relative.beg = off >> align_bits;
    }
 
@@ -222,7 +222,7 @@
    typedef flat_map_intersegment<Mutex> self_t;
 
    void set_from_pointer(const volatile void *ptr)
- { this->set_from_pointer((const void *)ptr); }
+ { this->set_from_pointer(const_cast<const void *>(ptr)); }
 
    //!Obtains the address pointed
    //!by the object
@@ -233,7 +233,7 @@
       }
       switch(this->get_mode()){
          case is_relative:
- return (char*)this + members.relative.off;
+ return const_cast<char*>(reinterpret_cast<const char*>(this)) + members.relative.off;
          break;
          case is_segmented:
             {
@@ -241,7 +241,7 @@
             std::size_t offset;
             void *this_base;
             get_segment_info_and_offset(this, segment_info, offset, this_base);
- char *base = (char*)segment_info.group->address_of(this->members.segmented.segment);
+ char *base = static_cast<char*>(segment_info.group->address_of(this->members.segmented.segment));
             return base + this->members.segmented.off;
             }
          break;
@@ -259,7 +259,7 @@
    //!This only works with two basic_intersegment_ptr pointing
    //!to the same segment. Otherwise undefined
    std::ptrdiff_t diff(const self_t &other) const
- { return (char*)this->get_pointer() - (char*)other.get_pointer(); }
+ { return static_cast<char*>(this->get_pointer()) - static_cast<char*>(other.get_pointer()); }
 
    //!Returns true if both point to
    //!the same object
@@ -291,14 +291,14 @@
 
       std::size_t mode = this->get_mode();
       if(mode == is_in_stack){
- members.direct.addr = (void*)ptr;
+ members.direct.addr = const_cast<void*>(ptr);
          return;
       }
       if(mode == is_relative){
- char *beg_addr = (char*)this->relative_calculate_begin_addr();
+ char *beg_addr = static_cast<char*>(this->relative_calculate_begin_addr());
          std::size_t seg_size = this->relative_size();
          if(ptr >= beg_addr && ptr < (beg_addr + seg_size)){
- members.relative.off = (char*)ptr - (char*)this;
+ members.relative.off = static_cast<const char*>(ptr) - reinterpret_cast<const char*>(this);
             return;
          }
       }
@@ -312,21 +312,22 @@
    
       if(!this_info.group){
          this->set_mode(is_in_stack);
- this->members.direct.addr = (void*)ptr;
+ this->members.direct.addr = const_cast<void*>(ptr);
       }
       else{
          get_segment_info_and_offset(ptr, ptr_info, ptr_offset, ptr_base);
 
          if(ptr_info.group != this_info.group){
             this->set_mode(is_pointee_outside);
- this->members.direct.addr = (void*)ptr;
+ this->members.direct.addr = const_cast<void*>(ptr);
          }
          else if(ptr_info.id == this_info.id){
             this->set_mode(is_relative);
- members.relative.off = ((char*)ptr - (char*)this);
+ members.relative.off = (static_cast<const char*>(ptr) - reinterpret_cast<const char*>(this));
             this->relative_set_begin_from_base(this_base);
             std::size_t pow, frc;
             std::size_t s = calculate_size(this_info.size, pow, frc);
+ (void)s;
             assert(this_info.size == s);
             this->members.relative.pow = pow;
             this->members.relative.frc = frc;
@@ -350,14 +351,14 @@
    //!offset
    void inc_offset(std::ptrdiff_t bytes)
    {
- this->set_from_pointer((char*)this->get_pointer()+bytes);
+ this->set_from_pointer(static_cast<char*>(this->get_pointer()) + bytes);
    }
 
    //!Decrements internal
    //!offset
    void dec_offset(std::ptrdiff_t bytes)
    {
- this->set_from_pointer((char*)this->get_pointer()-bytes);
+ this->set_from_pointer(static_cast<char*>(this->get_pointer()) - bytes);
    }
 
    //////////////////////////////////////
@@ -471,7 +472,7 @@
       base = 0;
       if(s_map.m_ptr_to_segment_info.empty()){
          segment = segment_info_t();
- offset = detail::char_ptr_cast(ptr) - detail::char_ptr_cast();
+ offset = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);
          return;
       }
       //Find the first base address greater than ptr
@@ -479,22 +480,22 @@
          = s_map.m_ptr_to_segment_info.upper_bound(ptr);
       if(it == s_map.m_ptr_to_segment_info.begin()){
          segment = segment_info_t();
- offset = detail::char_ptr_cast(ptr) - detail::char_ptr_cast();
+ offset = reinterpret_cast<const char*>(ptr) - static_cast<const char *>(0);
       }
       //Go to the previous one
       --it;
- char * segment_base = detail::char_ptr_cast(it->first);
+ char * segment_base = const_cast<char*>(reinterpret_cast<const char*>(it->first));
       std::size_t segment_size = it->second.size;
       
- if(segment_base <= detail::char_ptr_cast(ptr) &&
- (segment_base + segment_size) >= detail::char_ptr_cast(ptr)){
+ if(segment_base <= reinterpret_cast<const char*>(ptr) &&
+ (segment_base + segment_size) >= reinterpret_cast<const char*>(ptr)){
          segment = it->second;
- offset = detail::char_ptr_cast(ptr) - segment_base;
+ offset = reinterpret_cast<const char*>(ptr) - segment_base;
          base = segment_base;
       }
       else{
          segment = segment_info_t();
- offset = detail::char_ptr_cast(ptr) - detail::char_ptr_cast();
+ offset = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);
       }
    }
 
@@ -535,6 +536,7 @@
          void *addr = group_id->address_of(group_id->get_size()-1);
          group_id->pop_back();
          std::size_t erased = s_map.m_ptr_to_segment_info.erase(addr);
+ (void)erased;
          assert(erased);
          return true;
       }
@@ -635,21 +637,6 @@
    template<class U>
    intersegment_ptr(const intersegment_ptr<U> &r, detail::static_cast_tag)
    { base_t::set_from_pointer(static_cast<T*>(r.get())); }
-/*
- {
- if(r.is_null()){
- base_t::set_from_pointer(0);
- }
- else{
- //Some dirty tricks to safe segment operations.
- //Calculate pointer adjustment and adjust offset.
- pointer ptr = reinterpret_cast<pointer>(this);
- std::ptrdiff_t difference = detail::char_ptr_cast(static_cast<T*>(ptr)) -
- detail::char_ptr_cast(ptr);
- base_t::set_from_other(r);
- base_t::inc_offset(difference*sizeof(T));
- }
- }*/
 
    //!Emulates const_cast operator.
    //!Never throws.
@@ -672,7 +659,7 @@
    //!Obtains raw pointer from offset.
    //!Never throws.
    pointer get()const
- { return (pointer)base_t::get_pointer(); }
+ { return static_cast<pointer>(base_t::get_pointer()); }
 
    //!Pointer-like -> operator. It can return 0 pointer.
    //!Never throws.
@@ -1001,11 +988,11 @@
       return raw_address();
    }
    else if(this->is_relative()){
- return ((char*)this) + this->relative_pointee_offset();
+ return (const_cast<char*>(reinterpret_cast<const char*>(this))) + this->relative_pointee_offset();
    }
    else{
       group_manager *m = get_segment_group_manager(addr);
- char *base = (char*)m->get_id_address(this->segmented_id());
+ char *base = static_cast<char*>(m->get_id_address(this->segmented_id()));
       return base + this->segmented_offset();
    }
 }
@@ -1039,7 +1026,7 @@
       else if(ptr_info.segment_id == this_info.segment_id){
          set_relative();
          this->relative_size (ptr_info.size);
- this->relative_offset((char*)ptr - (char*)this);
+ this->relative_offset(static_cast<const char*>(ptr) - reinterpret_cast<const char*>(this));
          this->relative_start (ptr_info.base);
       }
    }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -225,7 +225,7 @@
 
    //!Returns the base address of the memory in this process. Never throws.
    void * get_address () const
- { return (char*)mp_header - Offset; }
+ { return reinterpret_cast<char*>(mp_header) - Offset; }
 
    //!Returns the size of memory segment. Never throws.
    std::size_t get_size () const
@@ -255,21 +255,21 @@
    //!The address must belong to the memory segment. Never throws.
    handle_t get_handle_from_address (const void *ptr) const
    {
- return detail::char_ptr_cast(ptr) -
- detail::char_ptr_cast(this->get_address());
+ return reinterpret_cast<const char*>(ptr) -
+ reinterpret_cast<const char*>(this->get_address());
    }
 
    //!Returns true if the address belongs to the managed memory segment
    bool belongs_to_segment (const void *ptr) const
    {
       return ptr >= this->get_address() &&
- ptr < (detail::char_ptr_cast(ptr) + this->get_size());
+ ptr < (reinterpret_cast<const char*>(ptr) + this->get_size());
    }
 
    //!Transforms previously obtained offset into an absolute address in the
    //!process space of the current process. Never throws.*/
    void * get_address_from_handle (handle_t offset) const
- { return detail::char_ptr_cast(this->get_address()) + offset; }
+ { return reinterpret_cast<char*>(this->get_address()) + offset; }
 
    //!Searches for nbytes of free memory in the segment, marks the
    //!memory as used and return the pointer to the memory. If no

Modified: branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/detail/managed_multi_shared_memory.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -117,7 +117,7 @@
             shmem_list_t::value_type &m_impl = *mp_frontend->m_shmem_list.rbegin();
             return result_type(m_impl.get_real_address(), m_impl.get_real_size()-1);
          }
- return result_type((void *)0, 0);
+ return result_type(static_cast<void *>(0), 0);
       }
 
       virtual bool update_segments ()
@@ -169,7 +169,7 @@
          //segment id = 0 of this group
          void_pointer::insert_mapping
             ( group
- , (char*)addr - managed_impl::ManagedOpenOrCreateUserOffset
+ , static_cast<char*>(addr) - managed_impl::ManagedOpenOrCreateUserOffset
             , size + managed_impl::ManagedOpenOrCreateUserOffset);
          //Check if this is the master segment
          if(!m_segment_number){

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -189,13 +189,13 @@
    { return m_mapped_region.get_size() - ManagedOpenOrCreateUserOffset; }
 
    void *get_user_address() const
- { return (char*)m_mapped_region.get_address() + ManagedOpenOrCreateUserOffset; }
+ { return static_cast<char*>(m_mapped_region.get_address()) + ManagedOpenOrCreateUserOffset; }
 
    std::size_t get_real_size() const
    { return m_mapped_region.get_size(); }
 
    void *get_real_address() const
- { return (char*)m_mapped_region.get_address(); }
+ { return m_mapped_region.get_address(); }
 
    void swap(managed_open_or_create_impl &other)
    {
@@ -360,7 +360,7 @@
             if(previous == UninitializedSegment){
                try{
                   write_whole_device<FileBased>(dev, size, file_like_t());
- construct_func((char*)region.get_address() + ManagedOpenOrCreateUserOffset, size - ManagedOpenOrCreateUserOffset, true);
+ construct_func(static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset, size - ManagedOpenOrCreateUserOffset, true);
                   //All ok, just move resources to the external mapped region
                   m_mapped_region.swap(region);
                }
@@ -413,7 +413,7 @@
          if(value != InitializedSegment)
             throw interprocess_exception(error_info(corrupted_error));
 
- construct_func( (char*)region.get_address() + ManagedOpenOrCreateUserOffset
+ construct_func( static_cast<char*>(region.get_address()) + ManagedOpenOrCreateUserOffset
                         , region.get_size() - ManagedOpenOrCreateUserOffset
                         , false);
          //All ok, just move resources to the external mapped region

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -1,110 +1,110 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Stephen Cleary 2000.
-// (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)
-//
-// See http://www.boost.org/libs/interprocess for documentation.
-//
-// This file is a slightly modified file from Boost.Pool
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP
-#define BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP
-
-#include <climits>
-#include <boost/static_assert.hpp>
-
-namespace boost {
-namespace interprocess {
-namespace detail {
-
-// Greatest common divisor and least common multiple
-
-//
-// gcd is an algorithm that calculates the greatest common divisor of two
-// integers, using Euclid's algorithm.
-//
-// Pre: A > 0 && B > 0
-// Recommended: A > B
-template <typename Integer>
-inline Integer gcd(Integer A, Integer B)
-{
- do
- {
- const Integer tmp(B);
- B = A % B;
- A = tmp;
- } while (B != 0);
-
- return A;
-}
-
-//
-// lcm is an algorithm that calculates the least common multiple of two
-// integers.
-//
-// Pre: A > 0 && B > 0
-// Recommended: A > B
-template <typename Integer>
-inline Integer lcm(const Integer & A, const Integer & B)
-{
- Integer ret = A;
- ret /= gcd(A, B);
- ret *= B;
- return ret;
-}
-
-template <typename Integer>
-inline Integer log2_ceil(const Integer & A)
-{
- Integer i = 0;
- Integer power_of_2 = 1;
-
- while(power_of_2 < A){
- power_of_2 <<= 1;
- ++i;
- }
- return i;
-}
-
-template <typename Integer>
-inline Integer upper_power_of_2(const Integer & A)
-{
- Integer power_of_2 = 1;
-
- while(power_of_2 < A){
- power_of_2 <<= 1;
- }
- return power_of_2;
-}
-
-//This function uses binary search to discover the
-//highest set bit of the integer
-inline std::size_t floor_log2 (std::size_t x)
-{
- const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
- const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
- BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
-
- std::size_t n = x;
- std::size_t log2 = 0;
-
- for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
- std::size_t tmp = n >> shift;
- if (tmp)
- log2 += shift, n = tmp;
- }
-
- return log2;
-}
-
-} // namespace detail
-} // namespace interprocess
-} // namespace boost
-
-#endif
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Stephen Cleary 2000.
+// (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)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+// This file is a slightly modified file from Boost.Pool
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP
+#define BOOST_INTERPROCESS_DETAIL_MATH_FUNCTIONS_HPP
+
+#include <climits>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace interprocess {
+namespace detail {
+
+// Greatest common divisor and least common multiple
+
+//
+// gcd is an algorithm that calculates the greatest common divisor of two
+// integers, using Euclid's algorithm.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer gcd(Integer A, Integer B)
+{
+ do
+ {
+ const Integer tmp(B);
+ B = A % B;
+ A = tmp;
+ } while (B != 0);
+
+ return A;
+}
+
+//
+// lcm is an algorithm that calculates the least common multiple of two
+// integers.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template <typename Integer>
+inline Integer lcm(const Integer & A, const Integer & B)
+{
+ Integer ret = A;
+ ret /= gcd(A, B);
+ ret *= B;
+ return ret;
+}
+
+template <typename Integer>
+inline Integer log2_ceil(const Integer & A)
+{
+ Integer i = 0;
+ Integer power_of_2 = 1;
+
+ while(power_of_2 < A){
+ power_of_2 <<= 1;
+ ++i;
+ }
+ return i;
+}
+
+template <typename Integer>
+inline Integer upper_power_of_2(const Integer & A)
+{
+ Integer power_of_2 = 1;
+
+ while(power_of_2 < A){
+ power_of_2 <<= 1;
+ }
+ return power_of_2;
+}
+
+//This function uses binary search to discover the
+//highest set bit of the integer
+inline std::size_t floor_log2 (std::size_t x)
+{
+ const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
+ const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
+ BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
+
+ std::size_t n = x;
+ std::size_t log2 = 0;
+
+ for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
+ std::size_t tmp = n >> shift;
+ if (tmp)
+ log2 += shift, n = tmp;
+ }
+
+ return log2;
+}
+
+} // namespace detail
+} // namespace interprocess
+} // namespace boost
+
+#endif

Modified: branches/release/boost/interprocess/detail/move.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/move.hpp (original)
+++ branches/release/boost/interprocess/detail/move.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -119,6 +119,18 @@
    return type(object);
 }
 
+template <class T>
+inline const T& forward_impl(const T &t)
+{ return t; }
+
+template <class T>
+inline T& forward_impl(T &t)
+{ return t; }
+
+template <class T>
+inline detail::moved_object<T> forward_impl(detail::moved_object<T> &t)
+{ return t; }
+
 } //namespace detail {
 
 //!A function that converts an object to a moved object so that

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -19,14 +19,16 @@
 #include <boost/interprocess/detail/workaround.hpp>
 
 #include <new>
+#include <iterator>
 #include <boost/interprocess/detail/in_place_interface.hpp>
-#include <boost/preprocessor/iteration/local.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
-#include <iterator>
+
+#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+#include <boost/interprocess/detail/preprocessor.hpp>
+#else
+#include <boost/interprocess/detail/move.hpp>
+#include <boost/interprocess/detail/variadic_templates_tools.hpp>
+#endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
 
 //!\file
 //!Describes a proxy class that implements named allocation syntax.
@@ -35,6 +37,101 @@
 namespace interprocess {
 namespace detail {
 
+#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+template<class T, bool is_iterator, class ...Args>
+struct CtorNArg : public placement_destroy<T>
+{
+ typedef detail::bool_<is_iterator> IsIterator;
+ typedef CtorNArg<T, is_iterator, Args...> self_t;
+ typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
+
+ self_t& operator++()
+ {
+ this->do_increment(IsIterator(), index_tuple_t());
+ return *this;
+ }
+
+ self_t operator++(int) { return ++*this; *this; }
+
+ CtorNArg(Args && ...args)
+ : args_(args...)
+ {}
+
+ virtual void construct_n(void *mem
+ , std::size_t num
+ , std::size_t &constructed)
+ {
+ T* memory = static_cast<T*>(mem);
+ for(constructed = 0; constructed < num; ++constructed){
+ this->construct(memory++, IsIterator(), index_tuple_t());
+ this->do_increment(IsIterator(), index_tuple_t());
+ }
+ }
+
+ private:
+ template<int ...IdxPack>
+ void construct(void *mem, detail::true_, const index_tuple<IdxPack...>&)
+ { new((void*)mem)T(*detail::forward_impl<Args>(get<IdxPack>(args_))...); }
+
+ template<int ...IdxPack>
+ void construct(void *mem, detail::false_, const index_tuple<IdxPack...>&)
+ { new((void*)mem)T(detail::forward_impl<Args>(get<IdxPack>(args_))...); }
+
+ template<int ...IdxPack>
+ void do_increment(detail::true_, const index_tuple<IdxPack...>&)
+ {
+ this->expansion_helper(++get<IdxPack>(args_)...);
+ }
+
+ template<class ...ExpansionArgs>
+ void expansion_helper(ExpansionArgs &&...)
+ {}
+
+ template<int ...IdxPack>
+ void do_increment(detail::false_, const index_tuple<IdxPack...>&)
+ {}
+
+ tuple<Args&&...> args_;
+};
+
+//!Describes a proxy class that implements named
+//!allocation syntax.
+template
+ < class SegmentManager //segment manager to construct the object
+ , class T //type of object to build
+ , bool is_iterator //passing parameters are normal object or iterators?
+ >
+class named_proxy
+{
+ typedef typename SegmentManager::char_type char_type;
+ const char_type * mp_name;
+ SegmentManager * mp_mngr;
+ mutable std::size_t m_num;
+ const bool m_find;
+ const bool m_dothrow;
+
+ public:
+ named_proxy(SegmentManager *mngr, const char_type *name, bool find, bool dothrow)
+ : mp_name(name), mp_mngr(mngr), m_num(1)
+ , m_find(find), m_dothrow(dothrow)
+ {}
+
+ template<class ...Args>
+ T *operator()(Args &&...args) const
+ {
+ CtorNArg<T, is_iterator, Args...> ctor_obj(detail::forward_impl<Args>(args)...);
+ return mp_mngr->template
+ generic_construct<T>(mp_name, m_num, m_find, m_dothrow, ctor_obj);
+ }
+
+ //This operator allows --> named_new("Name")[3]; <-- syntax
+ const named_proxy &operator[](std::size_t num) const
+ { m_num *= num; return *this; }
+};
+
+#else //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
 //!Function object that makes placement new
 //!without arguments
 template<class T>
@@ -52,21 +149,18 @@
 
    virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)
    {
- T* memory = (T*)(mem);
+ T* memory = static_cast<T*>(mem);
       for(constructed = 0; constructed < num; ++constructed)
          new((void*)memory++)T;
    }
 };
 
-#ifndef BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS
-# define BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS 10
-#endif
-
 ////////////////////////////////////////////////////////////////
 // What the macro should generate (n == 2):
 //
 // template<class T, bool is_iterator, class P1, class P2>
 // struct Ctor2Arg
+// : public placement_destroy<T>
 // {
 // typedef detail::bool_<is_iterator> IsIterator;
 // typedef Ctor2Arg self_t;
@@ -94,7 +188,7 @@
 // , std::size_t num
 // , std::size_t &constructed)
 // {
-// T* memory = (T*)(mem);
+// T* memory = static_cast<T*>(mem);
 // for(constructed = 0; constructed < num; ++constructed){
 // this->construct(memory++, IsIterator());
 // this->do_increment(IsIterator());
@@ -118,22 +212,6 @@
 //This cast is ugly but it is necessary until "perfect forwarding"
 //is achieved in C++0x. Meanwhile, if we want to be able to
 //bind rvalues with non-const references, we have to be ugly
-#define BOOST_INTERPROCESS_AUX_PARAM_LIST(z, n, data) \
- const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
-//!
-
-#define BOOST_INTERPROCESS_AUX_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
-//!
-
-#define BOOST_INTERPROCESS_AUX_PARAM_INC(z, n, data) \
- BOOST_PP_CAT(++m_p, n) \
-//!
-
-#define BOOST_INTERPROCESS_AUX_PARAM_DEFINE(z, n, data) \
- BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
-//!
-
 #define BOOST_PP_LOCAL_MACRO(n) \
    template<class T, bool is_iterator, BOOST_PP_ENUM_PARAMS(n, class P) > \
    struct BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
@@ -156,14 +234,14 @@
       self_t operator++(int) { return ++*this; *this; } \
                                                                            \
       BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
- ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _) ) \
+ ( BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _) ) \
          : BOOST_PP_ENUM(n, BOOST_INTERPROCESS_AUX_PARAM_INIT, _) {} \
                                                                            \
       virtual void construct_n(void *mem \
                         , std::size_t num \
                         , std::size_t &constructed) \
       { \
- T* memory = (T*)(mem); \
+ T* memory = static_cast<T*>(mem); \
          for(constructed = 0; constructed < num; ++constructed){ \
             this->construct(memory++, IsIterator()); \
             this->do_increment(IsIterator()); \
@@ -172,24 +250,23 @@
                                                                            \
       private: \
       void construct(void *mem, detail::true_) \
- { new((void*)mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \
+ { \
+ new((void*)mem) T \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_IT_FORWARD, _)); \
+ } \
                                                                            \
       void construct(void *mem, detail::false_) \
- { new((void*)mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
+ { \
+ new((void*)mem) T \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_MEMBER_FORWARD, _)); \
+ } \
                                                                            \
- BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
+ BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
    }; \
 //!
-
-
 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
 #include BOOST_PP_LOCAL_ITERATE()
 
-#undef BOOST_INTERPROCESS_AUX_PARAM_LIST
-#undef BOOST_INTERPROCESS_AUX_PARAM_INIT
-#undef BOOST_INTERPROCESS_AUX_PARAM_DEFINE
-#undef BOOST_INTERPROCESS_AUX_PARAM_INC
-
 //!Describes a proxy class that implements named
 //!allocation syntax.
 template
@@ -222,32 +299,22 @@
    }
    //!
 
- // Boost preprocessor used to create operator() overloads
- #define BOOST_INTERPROCESS_AUX_TYPE_LIST(z, n, data) \
- BOOST_PP_CAT(P, n) \
- //!
-
- #define BOOST_INTERPROCESS_AUX_PARAM_LIST(z, n, data) \
- const BOOST_PP_CAT(P, n) BOOST_PP_CAT(&p, n) \
- //!
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<BOOST_PP_ENUM_PARAMS(n, class P)> \
- T *operator()(BOOST_PP_ENUM (n, BOOST_INTERPROCESS_AUX_PARAM_LIST, _)) const \
- { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
- <T, is_iterator, BOOST_PP_ENUM (n, BOOST_INTERPROCESS_AUX_TYPE_LIST, _)> \
- ctor_obj_t; \
- ctor_obj_t ctor_obj (BOOST_PP_ENUM_PARAMS(n, p)); \
- return mp_mngr->template generic_construct<T> \
- (mp_name, m_num, m_find, m_dothrow, ctor_obj); \
- } \
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<BOOST_PP_ENUM_PARAMS(n, class P)> \
+ T *operator()(BOOST_PP_ENUM (n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) const\
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(Ctor, n), Arg) \
+ <T, is_iterator, BOOST_PP_ENUM_PARAMS(n, P)> \
+ ctor_obj_t; \
+ ctor_obj_t ctor_obj \
+ (BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)); \
+ return mp_mngr->template generic_construct<T> \
+ (mp_name, m_num, m_find, m_dothrow, ctor_obj); \
+ } \
    //!
 
    #define BOOST_PP_LOCAL_LIMITS ( 1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS )
    #include BOOST_PP_LOCAL_ITERATE()
- #undef BOOST_INTERPROCESS_AUX_PARAM_LIST
- #undef BOOST_INTERPROCESS_AUX_TYPE_LIST
 
    ////////////////////////////////////////////////////////////////////////
    // What the macro should generate (n == 2)
@@ -272,6 +339,8 @@
       { m_num *= num; return *this; }
 };
 
+#endif //#ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
 }}} //namespace boost { namespace interprocess { namespace detail {
 
 #include <boost/interprocess/detail/config_end.hpp>

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -101,6 +101,9 @@
 inline bool delete_file(const char *name)
 { return winapi::delete_file(name); }
 
+inline bool delete_file_on_reboot_if_possible(const char *filename)
+{ return winapi::move_file_ex(filename, 0, winapi::movefile_delay_until_reboot); }
+
 inline bool truncate_file (file_handle_t hnd, std::size_t size)
 {
    if(!winapi::set_file_pointer_ex(hnd, size, 0, winapi::file_begin)){
@@ -260,6 +263,12 @@
 inline bool delete_file(const char *name)
 { return ::unlink(name) == 0; }
 
+
+inline bool delete_file_on_reboot_if_possible(const char *)
+{ //Function not implemented in POSIX functions
+ return false;
+}
+
 inline bool truncate_file (file_handle_t hnd, std::size_t size)
 { return 0 == ::ftruncate(hnd, size); }
 
@@ -274,11 +283,11 @@
 }
 
 inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
-{ return off == lseek(hnd, off, (int)pos); }
+{ return off == ::lseek(hnd, off, (int)pos); }
 
 inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
 {
- off = lseek(hnd, 0, SEEK_CUR);
+ off = ::lseek(hnd, 0, SEEK_CUR);
    return off != ((off_t)-1);
 }
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -123,8 +123,8 @@
    template<class CharType>
    CharType *name() const
    {
- return reinterpret_cast<CharType*>
- (detail::char_ptr_cast(this) + name_offset());
+ return const_cast<CharType*>(reinterpret_cast<const CharType*>
+ (reinterpret_cast<const char*>(this) + name_offset()));
    }
 
    std::size_t name_length() const
@@ -137,7 +137,7 @@
 
    void *value() const
    {
- return detail::char_ptr_cast(this) + value_offset();
+ return const_cast<char*>((reinterpret_cast<const char*>(this) + value_offset()));
    }
 
    std::size_t value_offset() const
@@ -169,8 +169,9 @@
    static block_header *block_header_from_value(const void *value, std::size_t sz, std::size_t algn)
    {
       block_header * hdr =
- reinterpret_cast<block_header*>(detail::char_ptr_cast(value) -
- get_rounded_size(sizeof(block_header), algn));
+ const_cast<block_header*>
+ (reinterpret_cast<const block_header*>(reinterpret_cast<const char*>(value) -
+ get_rounded_size(sizeof(block_header), algn)));
       (void)sz;
       //Some sanity checks
       assert(hdr->m_value_alignment == algn);
@@ -182,8 +183,8 @@
    static block_header *from_first_header(Header *header)
    {
       block_header * hdr =
- reinterpret_cast<block_header*>(detail::char_ptr_cast(header) +
- get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
+ reinterpret_cast<block_header*>(reinterpret_cast<char*>(header) +
+ get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
       //Some sanity checks
       return hdr;
    }
@@ -192,7 +193,7 @@
    static Header *to_first_header(block_header *bheader)
    {
       Header * hdr =
- reinterpret_cast<Header*>(detail::char_ptr_cast(bheader) -
+ reinterpret_cast<Header*>(reinterpret_cast<char*>(bheader) -
          get_rounded_size(sizeof(Header), detail::alignment_of<block_header>::value));
       //Some sanity checks
       return hdr;
@@ -269,8 +270,9 @@
 
    block_header *get_block_header() const
    {
- return (block_header *)(detail::char_ptr_cast(this) +
- get_rounded_size(sizeof(*this), BlockHdrAlignment));
+ return const_cast<block_header*>
+ (reinterpret_cast<const block_header *>(reinterpret_cast<const char*>(this) +
+ get_rounded_size(sizeof(*this), BlockHdrAlignment)));
    }
 
    bool operator <(const intrusive_value_type_impl<Hook, CharType> & other) const
@@ -281,7 +283,7 @@
 
    static intrusive_value_type_impl *get_intrusive_value_type(block_header *hdr)
    {
- return (intrusive_value_type_impl *)(detail::char_ptr_cast(hdr) -
+ return reinterpret_cast<intrusive_value_type_impl *>(reinterpret_cast<char*>(hdr) -
          get_rounded_size(sizeof(intrusive_value_type_impl), BlockHdrAlignment));
    }
 
@@ -304,11 +306,11 @@
    {}
 
    char_ptr_holder(const detail::anonymous_instance_t *)
- : m_name((CharType*)0)
+ : m_name(static_cast<CharType*>(0))
    {}
 
    char_ptr_holder(const detail::unique_instance_t *)
- : m_name((CharType*)-1)
+ : m_name(reinterpret_cast<CharType*>(-1))
    {}
 
    operator const CharType *()
@@ -380,7 +382,7 @@
    index_data(void *ptr) : m_ptr(ptr){}
 
    void *value() const
- { return (void*)detail::get_pointer(m_ptr); }
+ { return static_cast<void>(detail::get_pointer(m_ptr)); }
 };
 
 template<class MemoryAlgorithm>

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -128,6 +128,15 @@
 {
     typedef const nat& type;
 };
+
+template <class T>
+struct add_const_reference
+{ typedef const T &type; };
+
+template <class T>
+struct add_const_reference<T&>
+{ typedef T& type; };
+
 template <typename T, typename U>
 struct is_same
 {
@@ -146,38 +155,6 @@
 
    static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
 };
-/*
-template <template<class P> typename T, template<typename P2> typename U>
-struct is_same
-{
- typedef char yes_type;
- struct no_type
- {
- char padding[8];
- };
-
- template <template<class P3> typename V>
- static yes_type is_same_tester(V<P3>*, V<P3>*);
- static no_type is_same_tester(...);
-
- static T<int> *t;
- static U<int> *u;
-
- static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
-};*/
-/*
-template< typename T >
-struct is_pointer_impl
-{
- static const bool value =
- (::boost::type_traits::ice_and<
- ::boost::detail::is_pointer_helper<typename remove_cv<T>::type>::value
- , ::boost::type_traits::ice_not<
- ::boost::is_member_pointer<T>::value
- >::value
- >::value)
- );
-};*/
 
 } // namespace detail
 } //namespace interprocess {

Modified: branches/release/boost/interprocess/detail/utilities.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/utilities.hpp (original)
+++ branches/release/boost/interprocess/detail/utilities.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -28,6 +28,9 @@
 #include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/detail/iterators.hpp>
 #include <boost/interprocess/detail/version_type.hpp>
+#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING
+#include <boost/interprocess/detail/preprocessor.hpp>
+#endif
 #include <utility>
 #include <algorithm>
 
@@ -115,6 +118,9 @@
    void priv_deallocate(allocator_v2)
    { m_alloc.deallocate_one(m_ptr); }
 
+ scoped_deallocator(const scoped_deallocator &);
+ scoped_deallocator& operator=(const scoped_deallocator &);
+
    public:
    pointer m_ptr;
    Allocator& m_alloc;
@@ -125,10 +131,36 @@
    ~scoped_deallocator()
    { if (m_ptr)priv_deallocate(alloc_version()); }
 
+ #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ scoped_deallocator(scoped_deallocator &&o)
+ : m_ptr(o.m_ptr), m_alloc(o.m_alloc)
+ {
+ #else
+ scoped_deallocator(moved_object<scoped_deallocator> mo)
+ : m_ptr(mo.get().m_ptr), m_alloc(mo.get().m_alloc)
+ {
+ scoped_deallocator &o = mo.get();
+ #endif
+ o.release();
+ }
+
+ pointer get() const
+ { return m_ptr; }
+
    void release()
    { m_ptr = 0; }
 };
 
+} //namespace detail {
+
+template <class Allocator>
+struct is_movable<boost::interprocess::detail::scoped_deallocator<Allocator> >
+{
+ static const bool value = true;
+};
+
+namespace detail {
+
 //!A deleter for scoped_ptr that deallocates the memory
 //!allocated for an array of objects using a STL allocator.
 template <class Allocator>
@@ -353,20 +385,6 @@
    { m_itbeg = multiallocation_iterator(); }
 };
 
-//!Forces a cast from any pointer to char *pointer
-template<class T>
-inline char* char_ptr_cast(T *ptr)
-{
- //This is nasty, but we like it a lot!
- return (char*)(ptr);
-}
-
-inline char* char_ptr_cast()
-{
- //This is nasty, but we like it a lot!
- return (char*)(0);
-}
-
 //Rounds "orig_size" by excess to round_to bytes
 inline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to)
 {
@@ -510,19 +528,18 @@
    T1 first;
    T2 second;
 
- pair()
- : first(), second()
- {}
-
- pair(const T1& x, const T2& y)
- : first(x), second(y)
- {}
-
+ //std::pair compatibility
    template <class D, class S>
    pair(const std::pair<D, S>& p)
       : first(p.first), second(p.second)
    {}
 
+ //To resolve ambiguity with the variadic constructor of 1 argument
+ //and the previous constructor
+ pair(std::pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template <class D, class S>
    pair(const detail::moved_object<std::pair<D, S> >& p)
@@ -535,49 +552,78 @@
    {}
    #endif
 
+ pair()
+ : first(), second()
+ {}
+
+ pair(const pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
+ //To resolve ambiguity with the variadic constructor of 1 argument
+ //and the copy constructor
+ pair(pair<T1, T2>& x)
+ : first(x.first), second(x.second)
+ {}
+
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template <class D, class S>
- pair(const detail::moved_object<pair<D, S> >& p)
+ pair(const detail::moved_object<pair<T1, T2> >& p)
       : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
    {}
    #else
- template <class D, class S>
- pair(pair<D, S> && p)
+ pair(pair<T1, T2> && p)
       : first(detail::move_impl(p.first)), second(detail::move_impl(p.second))
    {}
    #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- template <class U, class V>
- pair(const detail::moved_object<U> &x, const detail::moved_object<V> &y)
- : first(detail::move_impl(x.get())), second(detail::move_impl(y.get()))
+ template <class D, class S>
+ pair(const detail::moved_object<pair<D, S> >& p)
+ : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
    {}
    #else
- template <class U, class V>
- pair(U &&x, V &&y)
- : first(detail::move_impl(x)), second(detail::move_impl(y))
+ template <class D, class S>
+ pair(pair<D, S> && p)
+ : first(detail::move_impl(p.first)), second(detail::move_impl(p.second))
    {}
    #endif
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair(const detail::moved_object<pair> &p)
- : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
+ #ifdef BOOST_INTERPROCESS_PERFECT_FORWARDING
+
+ template<class U, class ...Args>
+ pair(U &&u, Args &&... args)
+ : first(detail::forward_impl<U>(u))
+ , second(detail::forward_impl<Args>(args)...)
    {}
+
    #else
- pair(pair &&p)
- : first(detail::move_impl(p.first)), second(detail::move_impl(p.second))
- {}
+
+ template<class U>
+ pair(BOOST_INTERPROCESS_PARAM(U, u))
+ : first(detail::forward_impl<U>(u))
+ {}
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
+ pair(BOOST_INTERPROCESS_PARAM(U, u) \
+ ,BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_LIST, _)) \
+ : first(detail::forward_impl<U>(u)) \
+ , second(BOOST_PP_ENUM(n, BOOST_INTERPROCESS_PP_PARAM_FORWARD, _)) \
+ {} \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_INTERPROCESS_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
    #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair& operator=(const detail::moved_object<pair> &p)
+ pair& operator=(const detail::moved_object<pair<T1, T2> > &p)
    {
       first = detail::move_impl(p.get().first);
       second = detail::move_impl(p.get().second);
       return *this;
    }
    #else
- pair& operator=(pair &&p)
+ pair& operator=(pair<T1, T2> &&p)
    {
       first = detail::move_impl(p.first);
       second = detail::move_impl(p.second);
@@ -585,12 +631,21 @@
    }
    #endif
 
- pair& operator=(const pair &p)
+ #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ pair& operator=(const detail::moved_object<std::pair<T1, T2> > &p)
+ {
+ first = detail::move_impl(p.get().first);
+ second = detail::move_impl(p.get().second);
+ return *this;
+ }
+ #else
+ pair& operator=(std::pair<T1, T2> &&p)
    {
- first = p.first;
- second = p.second;
+ first = detail::move_impl(p.first);
+ second = detail::move_impl(p.second);
       return *this;
    }
+ #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template <class D, class S>
@@ -737,6 +792,16 @@
    { return chain_.size(); }
 };
 
+template<class T>
+struct value_init
+{
+ value_init()
+ : m_t()
+ {}
+
+ T m_t;
+};
+
 } //namespace detail {
 
 //!The pair is movable if any of its members is movable

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -63,8 +63,16 @@
 static const unsigned long file_map_read = section_map_read;
 static const unsigned long file_map_all_access = section_all_access;
 
+static const unsigned long movefile_copy_allowed = 0x02;
+static const unsigned long movefile_delay_until_reboot = 0x04;
+static const unsigned long movefile_replace_existing = 0x01;
+static const unsigned long movefile_write_through = 0x08;
+static const unsigned long movefile_create_hardlink = 0x10;
+static const unsigned long movefile_fail_if_not_trackable = 0x20;
+
 static const unsigned long file_share_read = 0x00000001;
 static const unsigned long file_share_write = 0x00000002;
+static const unsigned long file_share_delete = 0x00000004;
 
 static const unsigned long generic_read = 0x80000000L;
 static const unsigned long generic_write = 0x40000000L;
@@ -94,7 +102,7 @@
 static const unsigned long lang_neutral = (unsigned long)0x00;
 static const unsigned long sublang_default = (unsigned long)0x01;
 static const unsigned long invalid_file_size = (unsigned long)0xFFFFFFFF;
-static void * const invalid_handle_value = (void*)(long*)-1;
+static void * const invalid_handle_value = (void*)(long)(-1);
 static const unsigned long create_new = 1;
 static const unsigned long create_always = 2;
 static const unsigned long open_existing = 3;
@@ -227,6 +235,7 @@
 extern "C" __declspec(dllimport) void * __stdcall OpenFileMappingA (unsigned long, int, const char *);
 extern "C" __declspec(dllimport) void * __stdcall CreateFileA (const char *, unsigned long, unsigned long, struct interprocess_security_attributes*, unsigned long, unsigned long, void *);
 extern "C" __declspec(dllimport) int __stdcall DeleteFileA (const char *);
+extern "C" __declspec(dllimport) int __stdcall MoveFileExA (const char *, const char *, unsigned long);
 extern "C" __declspec(dllimport) void __stdcall GetSystemInfo (struct system_info *);
 extern "C" __declspec(dllimport) int __stdcall FlushViewOfFile (void *, std::size_t);
 extern "C" __declspec(dllimport) int __stdcall GetFileSizeEx (void *, __int64 *size);
@@ -355,11 +364,14 @@
 { return MapViewOfFileEx(handle, file_access, highoffset, lowoffset, numbytes, base_addr); }
 
 static inline void *create_file(const char *name, unsigned long access, unsigned long creation_flags, unsigned long attributes = 0)
-{ return CreateFileA(name, access, file_share_read | file_share_write, 0, creation_flags, attributes, 0); }
+{ return CreateFileA(name, access, file_share_read | file_share_write | file_share_delete, 0, creation_flags, attributes, 0); }
 
 static inline bool delete_file(const char *name)
 { return 0 != DeleteFileA(name); }
 
+static inline bool move_file_ex(const char *source_filename, const char *destination_filename, unsigned long flags)
+{ return 0 != MoveFileExA(source_filename, destination_filename, flags); }
+
 static inline void get_system_info(system_info *info)
 { GetSystemInfo(info); }
 
@@ -400,10 +412,10 @@
 { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(addr, val1, val2); }
 
 static inline long interlocked_exchange_add(long volatile* addend, long value)
-{ return BOOST_INTERLOCKED_EXCHANGE_ADD((long*)addend, value); }
+{ return BOOST_INTERLOCKED_EXCHANGE_ADD(const_cast<long*>(addend), value); }
 
 static inline long interlocked_exchange(long volatile* addend, long value)
-{ return BOOST_INTERLOCKED_EXCHANGE((long*)addend, value); }
+{ return BOOST_INTERLOCKED_EXCHANGE(const_cast<long*>(addend), value); }
 
 } //namespace winapi
 } //namespace interprocess

Modified: branches/release/boost/interprocess/errors.hpp
==============================================================================
--- branches/release/boost/interprocess/errors.hpp (original)
+++ branches/release/boost/interprocess/errors.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -71,7 +71,7 @@
       0,
       sys_err_code,
       winapi::make_lang_id(winapi::lang_neutral, winapi::sublang_default), // Default language
- (char *) &lpMsgBuf,
+ reinterpret_cast<char *>(&lpMsgBuf),
       0,
       0
    );

Modified: branches/release/boost/interprocess/file_mapping.hpp
==============================================================================
--- branches/release/boost/interprocess/file_mapping.hpp (original)
+++ branches/release/boost/interprocess/file_mapping.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -181,7 +181,7 @@
 
 ///@endcond
 
-//!A class that stores the name of a a file
+//!A class that stores the name of a file
 //!and call std::remove(name) in its destructor
 //!Useful to remove temporary files in the presence
 //!of exceptions

Modified: branches/release/boost/interprocess/interprocess_fwd.hpp
==============================================================================
--- branches/release/boost/interprocess/interprocess_fwd.hpp (original)
+++ branches/release/boost/interprocess/interprocess_fwd.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -391,6 +391,11 @@
          ,class A = std::allocator<T> >
 class vector;
 
+//vector class
+template <class T
+,class A = std::allocator<T> >
+class deque;
+
 //list class
 template <class T
          ,class A = std::allocator<T> >

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -52,7 +52,7 @@
 
    //!Creates a process shared message queue with name "name". For this message queue,
    //!the maximum number of messages will be "max_num_msg" and the maximum message size
- //!will be "max_msg_size".
+ //!will be "max_msg_size". Throws on error and if the queue was previously created.
    message_queue(create_only_t create_only,
                  const char *name,
                  std::size_t max_num_msg,
@@ -62,15 +62,15 @@
    //!If the queue is created, the maximum number of messages will be "max_num_msg"
    //!and the maximum message size will be "max_msg_size". If queue was previously
    //!created the queue will be opened and "max_num_msg" and "max_msg_size" parameters
- //!are ignored.
+ //!are ignored. Throws on error.
    message_queue(open_or_create_t open_or_create,
                  const char *name,
                  std::size_t max_num_msg,
                  std::size_t max_msg_size);
 
    //!Opens a previously created process shared message queue with name "name".
- //!If the was not previously created or there are no free resources, the
- //!function returns false.
+ //!If the was not previously created or there are no free resources,
+ //!throws an error.
    message_queue(open_only_t open_only,
                  const char *name);
 
@@ -302,11 +302,11 @@
 
       //Pointer to the index
       msg_hdr_ptr_t *index = reinterpret_cast<msg_hdr_ptr_t*>
- (detail::char_ptr_cast(this)+r_hdr_size);
+ (reinterpret_cast<char*>(this)+r_hdr_size);
 
       //Pointer to the first message header
       detail::msg_hdr_t *msg_hdr = reinterpret_cast<detail::msg_hdr_t*>
- (detail::char_ptr_cast(this)+r_hdr_size+r_index_size);
+ (reinterpret_cast<char*>(this)+r_hdr_size+r_index_size);
 
       //Initialize the pointer to the index
       mp_index = index;
@@ -315,7 +315,7 @@
       for(std::size_t i = 0; i < m_max_num_msg; ++i){
          index[i] = msg_hdr;
          msg_hdr = reinterpret_cast<detail::msg_hdr_t*>
- (detail::char_ptr_cast(msg_hdr)+r_max_msg_size);
+ (reinterpret_cast<char*>(msg_hdr)+r_max_msg_size);
       }
    }
 
@@ -385,7 +385,7 @@
               name,
               get_mem_size(max_msg_size, max_num_msg),
               read_write,
- (void*)0,
+ static_cast<void*>(0),
               //Prepare initialization functor
               detail::initialization_func_t (max_num_msg, max_msg_size))
 {}
@@ -399,7 +399,7 @@
               name,
               get_mem_size(max_msg_size, max_num_msg),
               read_write,
- (void*)0,
+ static_cast<void*>(0),
               //Prepare initialization functor
               detail::initialization_func_t (max_num_msg, max_msg_size))
 {}
@@ -410,7 +410,7 @@
    : m_shmem(open_only,
               name,
               read_write,
- (void*)0,
+ static_cast<void*>(0),
               //Prepare initialization functor
               detail::initialization_func_t ())
 {}
@@ -426,7 +426,13 @@
 inline bool message_queue::timed_send
    (const void *buffer, std::size_t buffer_size
    ,unsigned int priority, const boost::posix_time::ptime &abs_time)
-{ return this->do_send(timed, buffer, buffer_size, priority, abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->send(buffer, buffer_size, priority);
+ return true;
+ }
+ return this->do_send(timed, buffer, buffer_size, priority, abs_time);
+}
 
 inline bool message_queue::do_send(block_t block,
                                 const void *buffer, std::size_t buffer_size,
@@ -508,7 +514,13 @@
    message_queue::timed_receive(void *buffer, std::size_t buffer_size,
                                 std::size_t &recvd_size, unsigned int &priority,
                                 const boost::posix_time::ptime &abs_time)
-{ return this->do_receive(timed, buffer, buffer_size, recvd_size, priority, abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->receive(buffer, buffer_size, recvd_size, priority);
+ return true;
+ }
+ return this->do_receive(timed, buffer, buffer_size, recvd_size, priority, abs_time);
+}
 
 inline bool
    message_queue::do_receive(block_t block,

Modified: branches/release/boost/interprocess/mapped_region.hpp
==============================================================================
--- branches/release/boost/interprocess/mapped_region.hpp (original)
+++ branches/release/boost/interprocess/mapped_region.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -109,7 +109,7 @@
    //!mapped memory. Never throws.
    offset_t get_offset() const;
 
- //!Returns the mode of the mapping used to contruct the mapped file.
+ //!Returns the mode of the mapping used to construct the mapped file.
    //!Never throws.
    mode_t get_mode() const;
 
@@ -327,7 +327,7 @@
                                 foffset_high,
                                 foffset_low,
                                 m_size ? static_cast<std::size_t>(m_extra_offset + m_size) : 0,
- (void*)address);
+ const_cast<void*>(address));
 
    if(!mhandle.is_shm){
       //For files we don't need the file mapping anymore
@@ -482,8 +482,7 @@
    }
 
    //Map it to the address space
-// m_base = mmap64( (void*)address
- m_base = mmap ( (void*)address
+ m_base = mmap ( const_cast<void*>(address)
                     , static_cast<std::size_t>(m_extra_offset + m_size)
                     , prot
                     , flags
@@ -498,13 +497,13 @@
    }
 
    //Calculate new base for the user
- void *old_base = m_base;
+ const void *old_base = m_base;
    m_base = static_cast<char*>(m_base) + m_extra_offset;
    m_offset = offset;
    m_size = size;
 
    //Check for fixed mapping error
- if(address && (old_base != (void*)address)){
+ if(address && (old_base != address)){
       error_info err = system_error_code();
       this->priv_close();
       throw interprocess_exception(err);

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -95,7 +95,7 @@
    { return !operator== (other); }
 
    reference operator*() const
- { return *((char*)detail::get_pointer(next_alloc_.next_)); }
+ { return *reinterpret_cast<char*>(detail::get_pointer(next_alloc_.next_)); }
 
    operator unspecified_bool_type() const
    { return next_alloc_.next_? &basic_multiallocation_iterator::unspecified_bool_type_func : 0; }
@@ -113,6 +113,9 @@
       return it;
    }
 
+ multi_allocation_next<VoidPointer> &get_multi_allocation_next()
+ { return *next_alloc_.next_; }
+
    private:
    multi_allocation_next<VoidPointer> next_alloc_;
 };
@@ -170,7 +173,7 @@
          this->last_mem_ = tmp_mem;
       }
       else{
- next_impl_t * old_first = (next_impl_t*)(&*this->it_);
+ next_impl_t * old_first = &this->it_.get_multi_allocation_next();
          tmp_mem->next_ = old_first;
          this->it_ = basic_multiallocation_iterator<VoidPointer>(tmp_mem);
       }
@@ -197,7 +200,7 @@
       }
       else{
          static_cast<next_impl_t*>(detail::get_pointer(this->last_mem_))->next_
- = (next_impl_t*)&*other_chain.it_;
+ = &other_chain.it_.get_multi_allocation_next();
          this->last_mem_ = other_chain.last_mem_;
          this->num_mem_ += other_chain.num_mem_;
       }
@@ -438,8 +441,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 = (block_ctrl *)((char*)first + Alignment*first_min_units);
+ block_ctrl *second = reinterpret_cast<block_ctrl *>
+ (reinterpret_cast<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);
@@ -458,8 +461,8 @@
       // -----------------------------------------------------
       // | MBU +more | ACB |
       // -----------------------------------------------------
- char *pos = (char*)
- ((std::size_t)((char*)buffer +
+ char *pos = reinterpret_cast<char*>
+ (reinterpret_cast<std::size_t>(static_cast<char*>(buffer) +
             //This is the minimum size of (2)
             (MinBlockUnits*Alignment - AllocatedCtrlBytes) +
             //This is the next MBU for the aligned memory
@@ -470,12 +473,13 @@
       //Now obtain the address of the blocks
       block_ctrl *first = memory_algo->priv_get_block(buffer);
       block_ctrl *second = memory_algo->priv_get_block(pos);
- assert(pos <= ((char*)first + first->m_size*Alignment));
+ assert(pos <= (reinterpret_cast<char*>(first) + first->m_size*Alignment));
       assert(first->m_size >= 2*MinBlockUnits);
- assert((pos + MinBlockUnits*Alignment - AllocatedCtrlBytes + nbytes*Alignment/Alignment) <= ((char*)first + first->m_size*Alignment));
+ assert((pos + MinBlockUnits*Alignment - AllocatedCtrlBytes + nbytes*Alignment/Alignment) <=
+ (reinterpret_cast<char*>(first) + first->m_size*Alignment));
       //Set the new size of the first block
       std::size_t old_size = first->m_size;
- first->m_size = ((char*)second - (char*)first)/Alignment;
+ first->m_size = (reinterpret_cast<char*>(second) - reinterpret_cast<char*>(first))/Alignment;
       memory_algo->priv_mark_new_allocated_block(first);
 
       //Now check if we can create a new buffer in the end
@@ -494,7 +498,7 @@
       //Check if we can create a new block (of size MinBlockUnits) in the end of the segment
       if((old_size - first->m_size) >= (second_min_units + MinBlockUnits)){
          //Now obtain the address of the end block
- block_ctrl *third = new ((char*)second + Alignment*second_min_units)block_ctrl;
+ block_ctrl *third = new (reinterpret_cast<char*>(second) + Alignment*second_min_units)block_ctrl;
          second->m_size = second_min_units;
          third->m_size = old_size - first->m_size - second->m_size;
          BOOST_ASSERT(third->m_size >= MinBlockUnits);
@@ -591,10 +595,8 @@
       BOOST_ASSERT(block->m_size >= BlockCtrlUnits);
 
       //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 = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + block->m_size*Alignment);
+ (reinterpret_cast<char*>(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;
@@ -650,7 +652,7 @@
 
          block_ctrl *block = memory_algo->priv_get_block(ret.first);
          std::size_t received_units = block->m_size;
- char *block_address = (char*)block;
+ char *block_address = reinterpret_cast<char*>(block);
 
          std::size_t total_used_units = 0;
 // block_ctrl *prev_block = 0;
@@ -663,10 +665,7 @@
                break;
             total_request_units -= elem_units;
             //This is the position where the new block must be created
-// 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;
+ block_ctrl *new_block = reinterpret_cast<block_ctrl *>(block_address);
             assert_alignment(new_block);
 
             //The last block should take all the remaining space

Modified: branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp
==============================================================================
--- branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp (original)
+++ branches/release/boost/interprocess/mem_algo/detail/multi_simple_seq_fit_impl.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -88,13 +88,13 @@
       static block_ctrl *get_block_from_addr(void *addr)
       {
          return reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(addr) - BlockCtrlBytes);
+ (reinterpret_cast<char*>(addr) - BlockCtrlBytes);
       }
 
       void *get_addr() const
       {
          return reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(this) + BlockCtrlBytes);
+ (reinterpret_cast<const char*>(this) + BlockCtrlBytes);
       }
 
    };
@@ -235,7 +235,7 @@
    //Initialize pointers
    std::size_t block1_off = detail::get_rounded_size(sizeof(*this)+extra_hdr_bytes, Alignment);
    m_header.m_root.m_next = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(this) + block1_off);
+ (reinterpret_cast<char*>(this) + block1_off);
    m_header.m_root.m_next->m_size = (size - block1_off)/Alignment;
    m_header.m_root.m_next->m_next = &m_header.m_root;
 }
@@ -264,12 +264,12 @@
 
    //We'll create a new free block with extra_size bytes
    block_ctrl *new_block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(this) + old_end);
+ (reinterpret_cast<char*>(this) + old_end);
 
    new_block->m_next = 0;
    new_block->m_size = (m_header.m_size - old_end)/Alignment;
    m_header.m_allocated += new_block->m_size*Alignment;
- this->priv_deallocate(detail::char_ptr_cast(new_block) + BlockCtrlBytes);
+ this->priv_deallocate(reinterpret_cast<char*>(new_block) + BlockCtrlBytes);
 }
 
 template<class MutexFamily, class VoidPointer>
@@ -286,7 +286,7 @@
    //Simulate this block was previously allocated
    m_header.m_allocated += new_block->m_size*Alignment;
    //Return block and insert it in the free block list
- this->priv_deallocate(detail::char_ptr_cast(new_block) + BlockCtrlBytes);
+ this->priv_deallocate(reinterpret_cast<char*>(new_block) + BlockCtrlBytes);
 }
 
 template<class MutexFamily, class VoidPointer>
@@ -324,7 +324,7 @@
    //Iterate through all free portions
    do{
       //Just clear user the memory part reserved for the user
- std::memset( detail::char_ptr_cast(block) + BlockCtrlBytes
+ std::memset( reinterpret_cast<char*>(block) + BlockCtrlBytes
                  , 0
                  , block->m_size*Alignment - BlockCtrlBytes);
       block = detail::get_pointer(block->m_next);
@@ -412,7 +412,7 @@
    //to be modified
    //Obtain the real size of the block
    block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) - BlockCtrlBytes);
+ (reinterpret_cast<char*>(ptr) - BlockCtrlBytes);
    return block->m_size*Alignment - BlockCtrlBytes;
 }
 
@@ -505,7 +505,7 @@
          //We need a minimum size to split the previous one
          if((prev->get_user_bytes() - needs_backwards) > 2*BlockCtrlBytes){
             block_ctrl *new_block = reinterpret_cast<block_ctrl *>
- (detail::char_ptr_cast(reuse) - needs_backwards - BlockCtrlBytes);
+ (reinterpret_cast<char*>(reuse) - needs_backwards - BlockCtrlBytes);
             new_block->m_next = 0;
             new_block->m_size =
                BlockCtrlSize + (needs_backwards + extra_forward)/Alignment;
@@ -615,10 +615,10 @@
 {
    //Take the address where the next block should go
    block_ctrl *next_block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) + ptr->m_size*Alignment);
+ (reinterpret_cast<char*>(ptr) + ptr->m_size*Alignment);
 
    //Check if the adjacent block is in the managed segment
- std::size_t distance = (detail::char_ptr_cast(next_block) - detail::char_ptr_cast(this))/Alignment;
+ std::size_t distance = (reinterpret_cast<char*>(next_block) - reinterpret_cast<char*>(this))/Alignment;
    if(distance >= (m_header.m_size/Alignment)){
       //"next_block" does not exist so we can't expand "block"
       return 0;
@@ -643,8 +643,8 @@
    block_ctrl *root = &m_header.m_root;
    block_ctrl *prev_2_block = root;
    block_ctrl *prev_block = detail::get_pointer(root->m_next);
- while((detail::char_ptr_cast(prev_block) + prev_block->m_size*Alignment)
- != (detail::char_ptr_cast(ptr))
+ while((reinterpret_cast<char*>(prev_block) + prev_block->m_size*Alignment)
+ != (reinterpret_cast<char*>(ptr))
          && prev_block != root){
       prev_2_block = prev_block;
       prev_block = detail::get_pointer(prev_block->m_next);
@@ -654,7 +654,7 @@
       return prev_pair_t(0, 0);
 
    //Check if the previous block is in the managed segment
- std::size_t distance = (detail::char_ptr_cast(prev_block) - detail::char_ptr_cast(this))/Alignment;
+ std::size_t distance = (reinterpret_cast<char*>(prev_block) - reinterpret_cast<char*>(this))/Alignment;
    if(distance >= (m_header.m_size/Alignment)){
       //"previous_block" does not exist so we can't expand "block"
       return prev_pair_t(0, 0);
@@ -672,7 +672,7 @@
 {
    //Obtain the real size of the block
    block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) - BlockCtrlBytes);
+ (reinterpret_cast<char*>(ptr) - BlockCtrlBytes);
    std::size_t old_block_size = block->m_size;
 
    //All used blocks' next is marked with 0 so check it
@@ -747,7 +747,7 @@
 {
    //Obtain the real size of the block
    block_ctrl *block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) - BlockCtrlBytes);
+ (reinterpret_cast<char*>(ptr) - BlockCtrlBytes);
    std::size_t block_size = block->m_size;
 
    //All used blocks' next is marked with 0 so check it
@@ -785,14 +785,14 @@
 
    //We create the new block
    block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + block->m_size*Alignment);
+ (reinterpret_cast<char*>(block) + block->m_size*Alignment);
 
    //Write control data to simulate this new block was previously allocated
    block->m_next = 0;
    block->m_size = data_size - preferred_size;
 
    //Now deallocate the new block to insert it in the free list
- this->priv_deallocate(detail::char_ptr_cast(block)+BlockCtrlBytes);
+ this->priv_deallocate(reinterpret_cast<char*>(block)+BlockCtrlBytes);
    return true;
 }
 
@@ -820,30 +820,28 @@
    else if ((((std::size_t)(buffer)) % alignment) == 0)
       return buffer;
 
- char *aligned_portion = (char*)
- ((std::size_t)((char*)buffer + alignment - 1) & -alignment);
+ char *aligned_portion = reinterpret_cast<char*>
+ (reinterpret_cast<std::size_t>(static_cast<char*>(buffer) + alignment - 1) & -alignment);
 
- char *pos = ((aligned_portion - (char*)buffer) >= (MinBlockSize*Alignment)) ?
+ char *pos = ((aligned_portion - reinterpret_cast<char*>(buffer)) >= (MinBlockSize*Alignment)) ?
       aligned_portion : (aligned_portion + alignment);
 
-
    block_ctrl *first = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(buffer) - BlockCtrlBytes);
+ (reinterpret_cast<char*>(buffer) - BlockCtrlBytes);
 
- block_ctrl *second = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(pos) - BlockCtrlBytes);
+ block_ctrl *second = reinterpret_cast<block_ctrl*>(pos - BlockCtrlBytes);
 
    std::size_t old_size = first->m_size;
 
- first->m_size = ((char*)second - (char*)first)/Alignment;
+ first->m_size = (reinterpret_cast<char*>(second) - reinterpret_cast<char*>(first))/Alignment;
    second->m_size = old_size - first->m_size;
 
    //Write control data to simulate this new block was previously allocated
    second->m_next = 0;
 
    //Now deallocate the new block to insert it in the free list
- this->priv_deallocate(detail::char_ptr_cast(first) + BlockCtrlBytes);
- return detail::char_ptr_cast(second) + BlockCtrlBytes;
+ this->priv_deallocate(reinterpret_cast<char*>(first) + BlockCtrlBytes);
+ return reinterpret_cast<char*>(second) + BlockCtrlBytes;
 }
 
 template<class MutexFamily, class VoidPointer> inline
@@ -863,7 +861,7 @@
       std::size_t total_size = block->m_size;
       block->m_size = nunits;
       block_ctrl *new_block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + Alignment*nunits);
+ (reinterpret_cast<char*>(block) + Alignment*nunits);
       new_block->m_size = total_size - nunits;
       new_block->m_next = block->m_next;
       prev->m_next = new_block;
@@ -884,9 +882,9 @@
       //Mark the block as allocated
       block->m_next = 0;
       //Check alignment
- assert(((detail::char_ptr_cast(block) - detail::char_ptr_cast(this))
+ assert(((reinterpret_cast<char*>(block) - reinterpret_cast<char*>(this))
                % Alignment) == 0 );
- return detail::char_ptr_cast(block)+BlockCtrlBytes;
+ return reinterpret_cast<char*>(block) + BlockCtrlBytes;
    }
    return 0;
 }
@@ -913,13 +911,13 @@
    block_ctrl_ptr prev = &m_header.m_root;
    block_ctrl_ptr pos = m_header.m_root.m_next;
    block_ctrl_ptr block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(addr) - BlockCtrlBytes);
+ (reinterpret_cast<char*>(addr) - BlockCtrlBytes);
 
    //All used blocks' next is marked with 0 so check it
    assert(block->m_next == 0);
 
    //Check if alignment and block size are right
- assert((detail::char_ptr_cast(addr) - detail::char_ptr_cast(this))
+ assert((reinterpret_cast<char*>(addr) - reinterpret_cast<char*>(this))
             % Alignment == 0 );
 
    std::size_t total_size = Alignment*block->m_size;
@@ -938,9 +936,9 @@
    }
 
    //Try to combine with upper block
- if ((detail::char_ptr_cast(detail::get_pointer(block))
+ if ((reinterpret_cast<char*>(detail::get_pointer(block))
             + Alignment*block->m_size) ==
- detail::char_ptr_cast(detail::get_pointer(pos))){
+ reinterpret_cast<char*>(detail::get_pointer(pos))){
 
       block->m_size += pos->m_size;
       block->m_next = pos->m_next;
@@ -950,9 +948,9 @@
    }
 
    //Try to combine with lower block
- if ((detail::char_ptr_cast(detail::get_pointer(prev))
+ if ((reinterpret_cast<char*>(detail::get_pointer(prev))
             + Alignment*prev->m_size) ==
- detail::char_ptr_cast(detail::get_pointer(block))){
+ reinterpret_cast<char*>(detail::get_pointer(block))){
       prev->m_size += block->m_size;
       prev->m_next = block->m_next;
    }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -313,8 +313,9 @@
 
    //Initialize pointers
    std::size_t block1_off = priv_first_block_offset(this, extra_hdr_bytes);
+
    m_header.m_root.m_next = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(this) + block1_off);
+ ((reinterpret_cast<char*>(this) + block1_off));
    algo_impl_t::assert_alignment(detail::get_pointer(m_header.m_root.m_next));
    m_header.m_root.m_next->m_size = (size - block1_off)/Alignment;
    m_header.m_root.m_next->m_next = &m_header.m_root;
@@ -343,8 +344,9 @@
    }
 
    //We'll create a new free block with extra_size bytes
+
    block_ctrl *new_block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(this) + old_end);
+ (reinterpret_cast<char*>(this) + old_end);
 
    algo_impl_t::assert_alignment(new_block);
    new_block->m_next = 0;
@@ -372,8 +374,8 @@
       block = detail::get_pointer(block->m_next);
    }
 
- char *last_free_end_address = (char*)last + last->m_size*Alignment;
- if(last_free_end_address != ((char*)this + priv_block_end_offset())){
+ char *last_free_end_address = reinterpret_cast<char*>(last) + last->m_size*Alignment;
+ if(last_free_end_address != (reinterpret_cast<char*>(this) + priv_block_end_offset())){
       //there is an allocated block in the end of this block
       //so no shrinking is possible
       return;
@@ -388,7 +390,7 @@
       if(!unique_block)
          return;
       last = detail::get_pointer(m_header.m_root.m_next);
- assert(last_free_end_address == ((char*)last + last->m_size*Alignment));
+ assert(last_free_end_address == (reinterpret_cast<char*>(last) + last->m_size*Alignment));
    }
    std::size_t last_units = last->m_size;
 
@@ -420,14 +422,17 @@
 typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *
    simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_get_block(const void *ptr)
 {
- return reinterpret_cast<block_ctrl*>(detail::char_ptr_cast(ptr) - AllocatedCtrlBytes);
+ return const_cast<block_ctrl*>(reinterpret_cast<const block_ctrl*>
+ (reinterpret_cast<const char*>(ptr) - AllocatedCtrlBytes));
 }
 
 template<class MutexFamily, class VoidPointer>
 inline
 void *simple_seq_fit_impl<MutexFamily, VoidPointer>::
       priv_get_user_buffer(const typename simple_seq_fit_impl<MutexFamily, VoidPointer>::block_ctrl *block)
-{ return detail::char_ptr_cast(block) + AllocatedCtrlBytes; }
+{
+ return const_cast<char*>(reinterpret_cast<const char*>(block) + AllocatedCtrlBytes);
+}
 
 template<class MutexFamily, class VoidPointer>
 inline void simple_seq_fit_impl<MutexFamily, VoidPointer>::priv_add_segment(void *addr, std::size_t size)
@@ -564,7 +569,7 @@
                         T *reuse_ptr)
 {
    std::pair<void*, bool> ret = priv_allocation_command
- (command, limit_size, preferred_size, received_size, (void*)reuse_ptr, sizeof(T));
+ (command, limit_size, preferred_size, received_size, static_cast<void*>(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);
@@ -577,7 +582,7 @@
                         void *reuse_ptr, std::size_t sizeof_object)
 {
    if(!sizeof_object)
- return std::pair<void *, bool>((void*)0, 0);
+ return std::pair<void *, bool>(static_cast<void*>(0), 0);
    if(command & try_shrink_in_place){
       bool success = algo_impl_t::try_shrink
          ( this, reuse_ptr, limit_objects*sizeof_object
@@ -596,7 +601,7 @@
                        void *reuse_ptr, std::size_t sizeof_object)
 {
    command &= ~expand_bwd;
- if(!command) return std::pair<void *, bool>((void*)0, false);
+ if(!command) return std::pair<void *, bool>(static_cast<void*>(0), false);
 
    std::pair<void*, bool> ret;
    std::size_t max_count = m_header.m_size/sizeof_object;
@@ -623,8 +628,7 @@
    //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(const_cast<void*>(ptr))));
+ const block_ctrl *block = static_cast<const block_ctrl*>(priv_get_block(ptr));
    return block->get_user_bytes();
 }
 
@@ -678,8 +682,9 @@
          
          //We need a minimum size to split the previous one
          if((prev->get_user_bytes() - needs_backwards) > 2*BlockCtrlBytes){
- block_ctrl *new_block = reinterpret_cast<block_ctrl *>
- (detail::char_ptr_cast(reuse) - needs_backwards - BlockCtrlBytes);
+ block_ctrl *new_block = reinterpret_cast<block_ctrl*>
+ (reinterpret_cast<char*>(reuse) - needs_backwards - BlockCtrlBytes);
+
             new_block->m_next = 0;
             new_block->m_size =
                BlockCtrlUnits + (needs_backwards + extra_forward)/Alignment;
@@ -769,7 +774,7 @@
    received_size = 0;
 
    if(limit_size > preferred_size)
- return return_type((void*)0, false);
+ return return_type(static_cast<void*>(0), false);
 
    //Number of units to request (including block_ctrl header)
    std::size_t nunits = detail::get_rounded_size(preferred_size, Alignment)/Alignment + BlockCtrlUnits;
@@ -819,7 +824,7 @@
       if(biggest_block){
          std::size_t limit_units = detail::get_rounded_size(limit_size, Alignment)/Alignment + BlockCtrlUnits;
          if(biggest_block->m_size < limit_units)
- return return_type((void*)0, false);
+ return return_type(static_cast<void*>(0), false);
 
          received_size = biggest_block->m_size*Alignment - BlockCtrlUnits;
          void *ret = this->priv_check_and_allocate
@@ -836,7 +841,7 @@
       algo_impl_t::assert_alignment(ret.first);
       return ret;
    }
- return return_type((void*)0, false);
+ return return_type(static_cast<void*>(0), false);
 }
 
 template<class MutexFamily, class VoidPointer> inline
@@ -852,10 +857,13 @@
 {
    //Take the address where the next block should go
    block_ctrl *next_block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(ptr) + ptr->m_size*Alignment);
+ (reinterpret_cast<char*>(ptr) + ptr->m_size*Alignment);
 
    //Check if the adjacent block is in the managed segment
- std::size_t distance = (detail::char_ptr_cast(next_block) - detail::char_ptr_cast(this))/Alignment;
+ char *this_char_ptr = reinterpret_cast<char*>(this);
+ char *next_char_ptr = reinterpret_cast<char*>(next_block);
+ std::size_t distance = (next_char_ptr - this_char_ptr)/Alignment;
+
    if(distance >= (m_header.m_size/Alignment)){
       //"next_block" does not exist so we can't expand "block"
       return 0;
@@ -880,21 +888,25 @@
    block_ctrl *root = &m_header.m_root;
    block_ctrl *prev_2_block = root;
    block_ctrl *prev_block = detail::get_pointer(root->m_next);
- while((detail::char_ptr_cast(prev_block) + prev_block->m_size*Alignment)
- != (detail::char_ptr_cast(ptr))
+
+ while((reinterpret_cast<char*>(prev_block) + prev_block->m_size*Alignment)
+ != reinterpret_cast<char*>(ptr)
          && prev_block != root){
       prev_2_block = prev_block;
       prev_block = detail::get_pointer(prev_block->m_next);
    }
 
    if(prev_block == root || !prev_block->m_next)
- return prev_pair_t((block_ctrl*)0, (block_ctrl*)0);
+ return prev_pair_t(static_cast<block_ctrl*>(0), static_cast<block_ctrl*>(0));
 
    //Check if the previous block is in the managed segment
- std::size_t distance = (detail::char_ptr_cast(prev_block) - detail::char_ptr_cast(this))/Alignment;
+ char *this_char_ptr = reinterpret_cast<char*>(this);
+ char *prev_char_ptr = reinterpret_cast<char*>(prev_block);
+ std::size_t distance = (prev_char_ptr - this_char_ptr)/Alignment;
+
    if(distance >= (m_header.m_size/Alignment)){
       //"previous_block" does not exist so we can't expand "block"
- return prev_pair_t((block_ctrl*)0, (block_ctrl*)0);
+ return prev_pair_t(static_cast<block_ctrl*>(0), static_cast<block_ctrl*>(0));
    }
    return prev_pair_t(prev_2_block, prev_block);
 }
@@ -990,8 +1002,9 @@
       //the second's size will be "block->m_size-units"
       std::size_t total_size = block->m_size;
       block->m_size = nunits;
+
       block_ctrl *new_block = reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + Alignment*nunits);
+ (reinterpret_cast<char*>(block) + Alignment*nunits);
       new_block->m_size = total_size - nunits;
       new_block->m_next = block->m_next;
       prev->m_next = new_block;
@@ -1063,10 +1076,10 @@
    }
 
    //Try to combine with upper block
- if ((detail::char_ptr_cast(detail::get_pointer(block))
- + Alignment*block->m_size) ==
- detail::char_ptr_cast(detail::get_pointer(pos))){
+ char *block_char_ptr = reinterpret_cast<char*>(detail::get_pointer(block));
 
+ if ((block_char_ptr + Alignment*block->m_size) ==
+ reinterpret_cast<char*>(detail::get_pointer(pos))){
       block->m_size += pos->m_size;
       block->m_next = pos->m_next;
    }
@@ -1075,9 +1088,11 @@
    }
 
    //Try to combine with lower block
- if ((detail::char_ptr_cast(detail::get_pointer(prev))
+ if ((reinterpret_cast<char*>(detail::get_pointer(prev))
             + Alignment*prev->m_size) ==
- detail::char_ptr_cast(detail::get_pointer(block))){
+ block_char_ptr){
+
+
       prev->m_size += block->m_size;
       prev->m_next = block->m_next;
    }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -331,7 +331,7 @@
       ;
 
    private:
- //Due to embedded bits in size, Alignment must be at least 2
+ //Due to embedded bits in size, Alignment must be at least 4
    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));
@@ -380,7 +380,7 @@
    //cover the whole segment
    assert(get_min_size(extra_hdr_bytes) <= size);
    std::size_t block1_off = priv_first_block_offset(this, extra_hdr_bytes);
- priv_add_segment(detail::char_ptr_cast(this) + block1_off, size - block1_off);
+ priv_add_segment(reinterpret_cast<char*>(this) + block1_off, size - block1_off);
 }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
@@ -399,11 +399,11 @@
       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);
+ (reinterpret_cast<char*>(this) + block1_off);
    block_ctrl *old_end_block = priv_end_block(first_block);
    assert(priv_is_allocated_block(old_end_block));
- std::size_t old_border_offset = (detail::char_ptr_cast(old_end_block) -
- detail::char_ptr_cast(this)) + EndCtrlBlockBytes;
+ std::size_t old_border_offset = (reinterpret_cast<char*>(old_end_block) -
+ reinterpret_cast<char*>(this)) + EndCtrlBlockBytes;
 
    //Update managed buffer's size
    m_header.m_size += extra_size;
@@ -417,9 +417,9 @@
    //Now create a new block between the old end and the new end
    std::size_t align_offset = (m_header.m_size - old_border_offset)/Alignment;
    block_ctrl *new_end_block = reinterpret_cast<block_ctrl*>
- (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;
+ (reinterpret_cast<char*>(old_end_block) + align_offset*Alignment);
+ new_end_block->m_size = (reinterpret_cast<char*>(first_block) -
+ reinterpret_cast<char*>(new_end_block))/Alignment;
    first_block->m_prev_size = new_end_block->m_size;
    assert(first_block == priv_next_block(new_end_block));
    priv_mark_new_allocated_block(new_end_block);
@@ -428,8 +428,8 @@
 
    //The old end block is the new block
    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_size = (reinterpret_cast<char*>(new_end_block) -
+ reinterpret_cast<char*>(new_block))/Alignment;
    assert(new_block->m_size >= BlockCtrlUnits);
    priv_mark_new_allocated_block(new_block);
    assert(priv_next_block(new_block) == new_end_block);
@@ -448,7 +448,7 @@
       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);
+ (reinterpret_cast<char*>(this) + block1_off);
    algo_impl_t::assert_alignment(first_block);
 
    block_ctrl *old_end_block = priv_end_block(first_block);
@@ -485,8 +485,8 @@
    //Erase block from the free tree, since we will erase it
    m_header.m_imultiset.erase(Imultiset::s_iterator_to(*last_block));
 
- std::size_t shrunk_border_offset = (detail::char_ptr_cast(last_block) -
- detail::char_ptr_cast(this)) + EndCtrlBlockBytes;
+ std::size_t shrunk_border_offset = (reinterpret_cast<char*>(last_block) -
+ reinterpret_cast<char*>(this)) + EndCtrlBlockBytes;
    
    block_ctrl *new_end_block = last_block;
    algo_impl_t::assert_alignment(new_end_block);
@@ -521,13 +521,12 @@
 
    //The "end" node is just a node of size 0 with the "end" bit set
    block_ctrl *end_block = static_cast<block_ctrl*>
- (new (reinterpret_cast<SizeHolder*>
- (detail::char_ptr_cast(addr) + first_big_block->m_size*Alignment))SizeHolder);
+ (new (reinterpret_cast<char*>(addr) + first_big_block->m_size*Alignment)SizeHolder);
 
    //This will overwrite the prev part of the "end" node
    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;
+ (reinterpret_cast<char*>(first_big_block) - reinterpret_cast<char*>(end_block))/Alignment;
    priv_mark_as_allocated_block(end_block);
 
    assert(priv_next_block(first_big_block) == end_block);
@@ -539,7 +538,8 @@
    //to optimize the space wasted in bookkeeping:
 
    //Check that the sizes of the header are placed before the rbtree
- assert((void*)(SizeHolder*)first_big_block < (void*)(TreeHook*)first_big_block);
+ assert(static_cast<void*>(static_cast<SizeHolder*>(first_big_block))
+ < static_cast<void*>(static_cast<TreeHook*>(first_big_block)));
 
    //Check that the alignment is power of two (we use some optimizations based on this)
    //assert((Alignment % 2) == 0);
@@ -653,7 +653,7 @@
                         T *reuse_ptr)
 {
    std::pair<void*, bool> ret = priv_allocation_command
- (command, limit_size, preferred_size, received_size, (void*)reuse_ptr, sizeof(T));
+ (command, limit_size, preferred_size, received_size, static_cast<void*>(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);
@@ -666,7 +666,7 @@
                         void *reuse_ptr, std::size_t sizeof_object)
 {
    if(!sizeof_object)
- return std::pair<void *, bool>((void *)0, 0);
+ return std::pair<void *, bool>(static_cast<void*>(0), 0);
    if(command & try_shrink_in_place){
       bool success = algo_impl_t::try_shrink
          ( this, reuse_ptr, limit_objects*sizeof_object
@@ -724,7 +724,7 @@
    //Iterate through all blocks obtaining their size
    for(; ib != ie; ++ib){
       //Just clear user the memory part reserved for the user
- std::memset( detail::char_ptr_cast(&*ib) + BlockCtrlBytes
+ std::memset( reinterpret_cast<char*>(&*ib) + BlockCtrlBytes
                  , 0
                  , ib->m_size*Alignment - BlockCtrlBytes);
    }
@@ -801,7 +801,7 @@
          //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);
+ (reinterpret_cast<char*>(reuse) - needs_backwards_aligned);
 
             //Free old previous buffer
             new_block->m_size =
@@ -809,8 +809,8 @@
             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;
+ prev_block->m_size = (reinterpret_cast<char*>(new_block) -
+ reinterpret_cast<char*>(prev_block))/Alignment;
             assert(prev_block->m_size >= BlockCtrlUnits);
             priv_mark_as_free_block(prev_block);
 
@@ -836,8 +836,8 @@
             //If the backwards expansion has remaining bytes in the
             //first bytes, fill them with a pattern
             void *p = priv_get_user_buffer(new_block);
- void *user_ptr = detail::char_ptr_cast(p);
- assert(((char*)reuse_ptr - (char*)user_ptr) % backwards_multiple == 0);
+ void *user_ptr = reinterpret_cast<char*>(p);
+ assert((static_cast<char*>(reuse_ptr) - static_cast<char*>(user_ptr)) % backwards_multiple == 0);
             algo_impl_t::assert_alignment(user_ptr);
             return user_ptr;
          }
@@ -860,9 +860,8 @@
 
             //If the backwards expansion has remaining bytes in the
             //first bytes, fill them with a pattern
- void *p = priv_get_user_buffer(prev_block);
- void *user_ptr = detail::char_ptr_cast(p);
- assert(((char*)reuse_ptr - (char*)user_ptr) % backwards_multiple == 0);
+ void *user_ptr = priv_get_user_buffer(prev_block);
+ assert((static_cast<char*>(reuse_ptr) - static_cast<char*>(user_ptr)) % backwards_multiple == 0);
             algo_impl_t::assert_alignment(user_ptr);
             return user_ptr;
          }
@@ -932,7 +931,7 @@
    received_size = 0;
 
    if(limit_size > preferred_size)
- return return_type((void*)0, false);
+ return return_type(static_cast<void*>(0), false);
 
    //Number of units to request (including block_ctrl header)
    std::size_t preferred_units = priv_get_total_units(preferred_size);
@@ -971,7 +970,7 @@
          (command, limit_size, preferred_size, received_size, reuse_ptr, false, backwards_multiple), true);
    }
 
- return return_type((void*)0, false);
+ return return_type(static_cast<void*>(0), false);
 }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
@@ -979,14 +978,16 @@
 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);
+ return const_cast<block_ctrl*>
+ (reinterpret_cast<const block_ctrl*>
+ (reinterpret_cast<const char*>(ptr) - AllocatedCtrlBytes));
 }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 inline
 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; }
+{ return const_cast<char*>(reinterpret_cast<const char*>(block) + AllocatedCtrlBytes); }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
 inline
@@ -1077,7 +1078,7 @@
       }
       //This is the remaining block
       block_ctrl *rem_block = new(reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + intended_units*Alignment))block_ctrl;
+ (reinterpret_cast<char*>(block) + intended_units*Alignment))block_ctrl;
       rem_block->m_size = rem_units;
       algo_impl_t::assert_alignment(rem_block);
       assert(rem_block->m_size >= BlockCtrlUnits);
@@ -1116,7 +1117,7 @@
 {
    assert(!ptr->m_prev_allocated);
    return reinterpret_cast<block_ctrl *>
- (detail::char_ptr_cast(ptr) - ptr->m_prev_size*Alignment);
+ (reinterpret_cast<char*>(ptr) - ptr->m_prev_size*Alignment);
 }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
@@ -1141,7 +1142,7 @@
 {
    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);
+ (reinterpret_cast<char*>(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);
@@ -1154,7 +1155,7 @@
       (typename rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::block_ctrl *ptr)
 {
    return reinterpret_cast<block_ctrl *>
- (detail::char_ptr_cast(ptr) + ptr->m_size*Alignment);
+ (reinterpret_cast<char*>(ptr) + ptr->m_size*Alignment);
 }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
@@ -1162,8 +1163,8 @@
       (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);
+ block_ctrl *next_block = reinterpret_cast<block_ctrl *>
+ (reinterpret_cast<char*>(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);
@@ -1176,7 +1177,8 @@
 {
    //assert(!priv_is_allocated_block(block));
    block->m_allocated = 1;
- ((block_ctrl *)(((char*)block) + block->m_size*Alignment))->m_prev_allocated = 1;
+ reinterpret_cast<block_ctrl *>
+ (reinterpret_cast<char*>(block)+ block->m_size*Alignment)->m_prev_allocated = 1;
 }
 
 template<class MutexFamily, class VoidPointer, std::size_t MemAlignment> inline
@@ -1184,7 +1186,8 @@
       (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;
+ reinterpret_cast<block_ctrl *>
+ (reinterpret_cast<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;
 }
@@ -1209,7 +1212,7 @@
 
       //This is the remaining block
       block_ctrl *rem_block = new(reinterpret_cast<block_ctrl*>
- (detail::char_ptr_cast(block) + Alignment*nunits))block_ctrl;
+ (reinterpret_cast<char*>(block) + Alignment*nunits))block_ctrl;
       algo_impl_t::assert_alignment(rem_block);
       rem_block->m_size = block_old_size - nunits;
       assert(rem_block->m_size >= BlockCtrlUnits);

Modified: branches/release/boost/interprocess/offset_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/offset_ptr.hpp (original)
+++ branches/release/boost/interprocess/offset_ptr.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -61,17 +61,17 @@
    __declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0
    #endif
    void set_offset(const volatile void *ptr)
- { set_offset((const void*)ptr); }
+ { set_offset(const_cast<const void*>(ptr)); }
 
    void set_offset(const void *ptr)
    {
- const char *p = static_cast<const char*>(const_cast<const void*>(ptr));
+ const char *p = static_cast<const char*>(ptr);
       //offset == 1 && ptr != 0 is not legal for this pointer
       if(!ptr){
          m_offset = 1;
       }
       else{
- m_offset = p - detail::char_ptr_cast(this);
+ m_offset = p - reinterpret_cast<const char*>(this);
          BOOST_ASSERT(m_offset != 1);
       }
    }
@@ -80,7 +80,7 @@
    __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); }
+ { return (m_offset == 1) ? 0 : (const_cast<char*>(reinterpret_cast<const char*>(this)) + m_offset); }
 
    void inc_offset(std::ptrdiff_t bytes)
    { m_offset += bytes; }
@@ -149,7 +149,7 @@
    //!Obtains raw pointer from offset.
    //!Never throws.
    pointer get()const
- { return (pointer)this->get_pointer(); }
+ { return static_cast<pointer>(this->get_pointer()); }
 
    std::ptrdiff_t get_offset()
    { return m_offset; }
@@ -425,13 +425,13 @@
    static const std::size_t Mask = ((std::size_t(1) << NumBits)-1)<<1u;
 
    static pointer get_pointer(const pointer &n)
- { return (T*)(std::size_t(n.get()) & ~std::size_t(Mask)); }
+ { return reinterpret_cast<T*>(std::size_t(n.get()) & ~std::size_t(Mask)); }
 
    static void set_pointer(pointer &n, pointer p)
    {
       std::size_t pint = std::size_t(p.get());
       assert(0 == (std::size_t(pint) & Mask));
- n = (T*)(pint | (std::size_t(n.get()) & std::size_t(Mask)));
+ n = reinterpret_cast<T*>(pint | (std::size_t(n.get()) & std::size_t(Mask)));
    }
 
    static std::size_t get_bits(const pointer &n)
@@ -440,7 +440,7 @@
    static void set_bits(pointer &n, std::size_t b)
    {
       assert(b < (std::size_t(1) << NumBits));
- n = (T*)(std::size_t(get_pointer(n).get()) | (b << 1u));
+ n = reinterpret_cast<T*>(std::size_t(get_pointer(n).get()) | (b << 1u));
    }
 };
 

Modified: branches/release/boost/interprocess/segment_manager.hpp
==============================================================================
--- branches/release/boost/interprocess/segment_manager.hpp (original)
+++ branches/release/boost/interprocess/segment_manager.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -305,7 +305,7 @@
       //Call destructors and free memory
       //Build scoped ptr to avoid leaks with destructor exception
       std::size_t destroyed = 0;
- table.destroy_n((void*)object, ctrl_data->m_value_bytes/table.size, destroyed);
+ table.destroy_n(const_cast<void*>(object), ctrl_data->m_value_bytes/table.size, destroyed);
       this->deallocate(ctrl_data);
    }
    /// @endcond
@@ -410,40 +410,38 @@
    segment_manager(std::size_t size)
       : Base(size, priv_get_reserved_bytes())
       , m_header(static_cast<Base*>(get_this_pointer()))
- { (void) anonymous_instance; (void) unique_instance; }
+ {
+ (void) anonymous_instance; (void) unique_instance;
+ assert(static_cast<const void*>(this) == static_cast<const void*>(static_cast<Base*>(this)));
+ }
 
    //!Tries to find a previous named allocation. Returns the address
    //!and the object count. On failure the first member of the
    //!returned pair is 0.
    template <class T>
    std::pair<T*, std::size_t> find (const CharType* name)
- {
- //The name can't be null, no anonymous object can be found by name
- assert(name != 0);
- detail::placement_destroy<T> table;
- std::size_t size;
- void *ret;
-
- if(name == reinterpret_cast<const CharType*>(-1)){
- ret = priv_generic_find<char> (typeid(T).name(), m_header.m_unique_index, table, size, is_intrusive_t(), true);
- }
- else{
- ret = priv_generic_find<CharType> (name, m_header.m_named_index, table, size, is_intrusive_t(), true);
- }
- return std::pair<T*, std::size_t>(static_cast<T*>(ret), size);
- }
+ { return this->priv_find_impl<T>(name, true); }
 
    //!Tries to find a previous unique allocation. Returns the address
    //!and the object count. On failure the first member of the
    //!returned pair is 0.
    template <class T>
    std::pair<T*, std::size_t> find (const detail::unique_instance_t* name)
- {
- detail::placement_destroy<T> table;
- std::size_t size;
- void *ret = priv_generic_find<char>(name, m_header.m_unique_index, table, size, is_intrusive_t(), true);
- return std::pair<T*, std::size_t>(static_cast<T*>(ret), size);
- }
+ { return this->priv_find_impl<T>(name, true); }
+
+ //!Tries to find a previous named allocation. Returns the address
+ //!and the object count. On failure the first member of the
+ //!returned pair is 0. This search is not mutex-protected!
+ template <class T>
+ std::pair<T*, std::size_t> find_no_lock (const CharType* name)
+ { return this->priv_find_impl<T>(name, false); }
+
+ //!Tries to find a previous unique allocation. Returns the address
+ //!and the object count. On failure the first member of the
+ //!returned pair is 0. This search is not mutex-protected!
+ template <class T>
+ std::pair<T*, std::size_t> find_no_lock (const detail::unique_instance_t* name)
+ { return this->priv_find_impl<T>(name, false); }
 
    //!Returns throwing "construct" proxy
    //!object
@@ -690,11 +688,12 @@
          (priv_generic_construct(name, num, try2find, dothrow, table));
    }
 
+ private:
    //!Tries to find a previous named allocation. Returns the address
    //!and the object count. On failure the first member of the
    //!returned pair is 0.
    template <class T>
- std::pair<T*, std::size_t> find_no_lock (const CharType* name)
+ std::pair<T*, std::size_t> priv_find_impl (const CharType* name, bool lock)
    {
       //The name can't be null, no anonymous object can be found by name
       assert(name != 0);
@@ -703,10 +702,10 @@
       void *ret;
 
       if(name == reinterpret_cast<const CharType*>(-1)){
- ret = priv_generic_find<char> (typeid(T).name(), m_header.m_unique_index, table, size, is_intrusive_t(), false);
+ ret = priv_generic_find<char> (typeid(T).name(), m_header.m_unique_index, table, size, is_intrusive_t(), lock);
       }
       else{
- ret = priv_generic_find<CharType> (name, m_header.m_named_index, table, size, is_intrusive_t(), false);
+ ret = priv_generic_find<CharType> (name, m_header.m_named_index, table, size, is_intrusive_t(), lock);
       }
       return std::pair<T*, std::size_t>(static_cast<T*>(ret), size);
    }
@@ -715,15 +714,14 @@
    //!and the object count. On failure the first member of the
    //!returned pair is 0.
    template <class T>
- std::pair<T*, std::size_t> find_no_lock (const detail::unique_instance_t* name)
+ std::pair<T*, std::size_t> priv_find__impl (const detail::unique_instance_t* name, bool lock)
    {
       detail::placement_destroy<T> table;
       std::size_t size;
- void *ret = priv_generic_find<char>(name, m_header.m_unique_index, table, size, is_intrusive_t(), false);
+ void *ret = priv_generic_find<char>(name, m_header.m_unique_index, table, size, is_intrusive_t(), lock);
       return std::pair<T*, std::size_t>(static_cast<T*>(ret), size);
    }
 
- private:
    void *priv_generic_construct(const CharType *name,
                          std::size_t num,
                          bool try2find,
@@ -815,8 +813,7 @@
    {
       //Get the number of bytes until the end of (*this)
       //beginning in the end of the Base base.
- return (detail::char_ptr_cast((segment_manager*)0) + sizeof(segment_manager)) -
- (detail::char_ptr_cast(static_cast<Base*>((segment_manager*)0)) + sizeof(Base));
+ return sizeof(segment_manager) - sizeof(Base);
    }
 
    template <class CharT>
@@ -1014,7 +1011,7 @@
       //Get allocation parameters
       block_header_t *ctrl_data = reinterpret_cast<block_header_t*>
                                  (detail::get_pointer(it->second.m_ptr));
- char *stored_name = detail::char_ptr_cast(it->first.name());
+ char *stored_name = static_cast<char*>(static_cast<void*>(const_cast<CharT*>(it->first.name())));
       (void)stored_name;
 
       //Check if the distance between the name pointer and the memory pointer
@@ -1024,7 +1021,7 @@
 
       //Sanity check
       assert((ctrl_data->m_value_bytes % table.size) == 0);
- assert((void*)stored_name == ctrl_data->template name<CharT>());
+ assert(static_cast<void*>(stored_name) == static_cast<void*>(ctrl_data->template name<CharT>()));
       assert(sizeof(CharT) == ctrl_data->sizeof_char());
 
       //Erase node from index
@@ -1113,7 +1110,12 @@
          if(try2find){
             return it->get_block_header()->value();
          }
- return 0;
+ if(dothrow){
+ throw interprocess_exception(already_exists_error);
+ }
+ else{
+ return 0;
+ }
       }
 
       //Allocates buffer for name + data, this can throw (it hurts)
@@ -1153,22 +1155,23 @@
       }
       BOOST_CATCH_END
 
- //Initialize the node value_eraser to erase inserted node
- //if something goes wrong
- value_eraser<index_type> v_eraser(index, it);
-
       //Avoid constructions if constructor is trivial
       //Build scoped ptr to avoid leaks with constructor exception
       detail::mem_algo_deallocator<segment_manager_base_type> mem
          (buffer_ptr, *static_cast<segment_manager_base_type*>(this));
 
+ //Initialize the node value_eraser to erase inserted node
+ //if something goes wrong. This will be executed *before*
+ //the memory allocation as the intrusive value is built in that
+ //memory
+ value_eraser<index_type> v_eraser(index, it);
+
       //Construct array, this can throw
       detail::array_construct(ptr, num, table);
 
- //All constructors successful, we don't want to release memory
- mem.release();
- //Release node v_eraser since construction was successful
+ //Release rollbacks since construction was successful
       v_eraser.release();
+ mem.release();
       return ptr;
    }
 
@@ -1216,8 +1219,7 @@
       //the key (which is a smart pointer) to an equivalent one
       index_ib insert_ret;
       BOOST_TRY{
- insert_ret = index.insert(value_type(key_type (name, namelen),
- mapped_type(0)));
+ insert_ret = index.insert(value_type(key_type (name, namelen), mapped_type(0)));
       }
       //Ignore exceptions
       BOOST_CATCH(...){

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -220,6 +220,7 @@
       throw interprocess_exception(err);
    }
 
+ //detail::delete_file_on_reboot_if_possible(shmfile.c_str());
    m_mode = mode;
    return true;
 }

Modified: branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -593,7 +593,7 @@
> type;
 };
 
-//!Returns an instance of the a unique pointer constructed
+//!Returns an instance of a unique pointer constructed
 //!with boost::interproces::deleter from a pointer
 //!of type T that has been allocated in the passed managed segment
 template<class T, class ManagedMemory>

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -236,7 +236,7 @@
> type;
 };
 
-//!Returns an instance of the a weak pointer constructed
+//!Returns an instance of a weak pointer constructed
 //!with the default allocator and deleter from a pointer
 //!of type T that has been allocated in the passed managed segment
 template<class T, class ManagedMemory>

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -53,12 +53,12 @@
    }
 
    //Notify that all threads should execute wait logic
- while(SLEEP != detail::atomic_cas32((boost::uint32_t*)&m_command, command, SLEEP)){
+ while(SLEEP != detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), command, SLEEP)){
       detail::thread_yield();
    }
 /*
    //Wait until the threads are woken
- while(SLEEP != detail::atomic_cas32((boost::uint32_t*)&m_command, 0)){
+ while(SLEEP != detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), 0)){
       detail::thread_yield();
    }
 */
@@ -107,7 +107,7 @@
       //We increment the waiting thread count protected so that it will be
       //always constant when another thread enters the notification logic.
       //The increment marks this thread as "waiting on interprocess_condition"
- detail::atomic_inc32((boost::uint32_t*)&m_num_waiters);
+ detail::atomic_inc32(const_cast<boost::uint32_t*>(&m_num_waiters));
 
       //We unlock the external interprocess_mutex atomically with the increment
       mut.unlock();
@@ -150,7 +150,7 @@
       //If a timeout occurred, the interprocess_mutex will not execute checking logic
       if(tout_enabled && timed_out){
          //Decrement wait count
- detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
+ detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
          unlock_enter_mut = true;
          break;
       }
@@ -172,7 +172,7 @@
             return false;
          //---------------------------------------------------------------
          boost::uint32_t result = detail::atomic_cas32
- ((boost::uint32_t*)&m_command, SLEEP, NOTIFY_ONE);
+ (const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ONE);
          if(result == SLEEP){
             //Other thread has been notified and since it was a NOTIFY one
             //command, this thread must sleep again
@@ -184,17 +184,17 @@
             //so no other thread will exit.
             //Decrement wait count.
             unlock_enter_mut = true;
- detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
+ detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
             break;
          }
          else{
             //If it is a NOTIFY_ALL command, all threads should return
             //from do_timed_wait function. Decrement wait count.
- unlock_enter_mut = 1 == detail::atomic_dec32((boost::uint32_t*)&m_num_waiters);
+ unlock_enter_mut = 1 == detail::atomic_dec32(const_cast<boost::uint32_t*>(&m_num_waiters));
             //Check if this is the last thread of notify_all waiters
             //Only the last thread will release the interprocess_mutex
             if(unlock_enter_mut){
- detail::atomic_cas32((boost::uint32_t*)&m_command, SLEEP, NOTIFY_ALL);
+ detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_command), SLEEP, NOTIFY_ALL);
             }
             break;
          }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -30,7 +30,7 @@
 inline void interprocess_mutex::lock(void)
 {
    do{
- boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0);
+ boost::uint32_t prev_s = detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
 
       if (m_s == 1 && prev_s == 0){
             break;
@@ -42,12 +42,16 @@
 
 inline bool interprocess_mutex::try_lock(void)
 {
- boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0);
+ boost::uint32_t prev_s = detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 1, 0);
    return m_s == 1 && prev_s == 0;
 }
 
 inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
    //Obtain current count and target time
    boost::posix_time::ptime now = microsec_clock::universal_time();
 
@@ -70,7 +74,7 @@
 }
 
 inline void interprocess_mutex::unlock(void)
-{ detail::atomic_cas32((boost::uint32_t*)&m_s, 0, 1); }
+{ detail::atomic_cas32(const_cast<boost::uint32_t*>(&m_s), 0, 1); }
 
 } //namespace interprocess {
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -75,6 +75,10 @@
 
 inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
    detail::OS_thread_id_t th_id = detail::get_current_thread_id();
    if(detail::equal_thread_id(th_id, m_nOwner)) { // we own it
       if((unsigned int)(m_nLockCount+1) == 0){

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -52,6 +52,10 @@
 
 inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait();
+ return true;
+ }
    scoped_lock<interprocess_mutex> lock(m_mut);
    while(m_count == 0){
       if(!m_cond.timed_wait(lock, abs_time))

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -205,6 +205,10 @@
 
 inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
    bool result;
    if(!this->timed_acquire_file_lock(m_file_hnd, result, abs_time)){
       error_info err(system_error_code());
@@ -241,6 +245,10 @@
 
 inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock_sharable();
+ return true;
+ }
    bool result;
    if(!this->timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
       error_info err(system_error_code());

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -26,7 +26,7 @@
 #include <boost/limits.hpp>
 #include <cassert>
 
-#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
    #include <pthread.h>
    #include <errno.h>
    #include <boost/interprocess/sync/posix/pthread_helpers.hpp>
@@ -107,9 +107,12 @@
    template <typename L>
    bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time)
    {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock);
+ return true;
+ }
       if (!lock)
             throw lock_exception();
-
       return do_timed_wait(abs_time, *lock.mutex());
    }
 
@@ -119,9 +122,12 @@
    template <typename L, typename Pr>
    bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
    {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock, pred);
+ return true;
+ }
       if (!lock)
             throw lock_exception();
-
       while (!pred()){
          if (!do_timed_wait(abs_time, *lock.mutex()))
             return pred();

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -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_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
    #include <pthread.h>
    #include <errno.h>
    #include <boost/interprocess/sync/posix/pthread_helpers.hpp>

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -36,7 +36,8 @@
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 #include <cassert>
 
-#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED && defined BOOST_INTERPROCESS_POSIX_RECURSIVE_MUTEXES
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
+ (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>

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -21,8 +21,8 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 
-#if defined BOOST_INTERPROCESS_POSIX_PROCESS_SHARED &&\
- defined BOOST_INTERPROCESS_POSIX_SEMAPHORES
+#if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && \
+ (defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) && defined(BOOST_INTERPROCESS_POSIX_SEMAPHORES))
    #include <fcntl.h> //O_CREAT, O_*...
    #include <unistd.h> //close
    #include <string> //std::string

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -322,6 +322,10 @@
 inline bool interprocess_upgradable_mutex::timed_lock
    (const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
    scoped_lock_t lock(m_mut, abs_time);
    if(!lock.owns()) return false;
 
@@ -399,6 +403,10 @@
 inline bool interprocess_upgradable_mutex::timed_lock_upgradable
    (const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock_upgradable();
+ return true;
+ }
    scoped_lock_t lock(m_mut, abs_time);
    if(!lock.owns()) return false;
 
@@ -471,6 +479,10 @@
 inline bool interprocess_upgradable_mutex::timed_lock_sharable
    (const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock_sharable();
+ return true;
+ }
    scoped_lock_t lock(m_mut, abs_time);
    if(!lock.owns()) return false;
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -41,7 +41,7 @@
 //!must be deferred.
 static const detail::defer_lock_type defer_lock = detail::defer_lock_type();
 
-//!An object indicating that the a try_lock()
+//!An object indicating that a try_lock()
 //!operation must be executed.
 static const detail::try_to_lock_type try_to_lock = detail::try_to_lock_type();
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -259,6 +259,10 @@
 inline bool named_condition::timed_wait
    (L& lock, const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock);
+ return true;
+ }
    if (!lock)
       throw lock_exception();
    return this->do_timed_wait(lock, abs_time);
@@ -268,6 +272,10 @@
 inline bool named_condition::timed_wait
    (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock, pred);
+ return true;
+ }
    if (!lock)
       throw lock_exception();
 
@@ -309,6 +317,10 @@
 inline bool named_condition::timed_wait
    (L& lock, const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock);
+ return true;
+ }
    if (!lock)
       throw lock_exception();
    return this->condition()->do_timed_wait(abs_time, *lock.mutex()->mutex());
@@ -318,6 +330,10 @@
 inline bool named_condition::timed_wait
    (L& lock, const boost::posix_time::ptime &abs_time, Pr pred)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait(lock, pred);
+ return true;
+ }
    if (!lock)
       throw lock_exception();
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -150,7 +150,13 @@
 { return m_sem.try_wait(); }
 
 inline bool named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{ return m_sem.timed_wait(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
+ return m_sem.timed_wait(abs_time);
+}
 
 inline bool named_mutex::remove(const char *name)
 { return detail::named_semaphore_wrapper::remove(name); }
@@ -203,7 +209,13 @@
 { return this->mutex()->try_lock(); }
 
 inline bool named_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{ return this->mutex()->timed_lock(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
+ return this->mutex()->timed_lock(abs_time);
+}
 
 inline bool named_mutex::remove(const char *name)
 { return shared_memory_object::remove(name); }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -156,7 +156,13 @@
 { return this->mutex()->try_lock(); }
 
 inline bool named_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
-{ return this->mutex()->timed_lock(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
+ return this->mutex()->timed_lock(abs_time);
+}
 
 inline bool named_recursive_mutex::remove(const char *name)
 { return shared_memory_object::remove(name); }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -154,7 +154,13 @@
 { return m_sem.try_wait(); }
 
 inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
-{ return m_sem.timed_wait(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait();
+ return true;
+ }
+ return m_sem.timed_wait(abs_time);
+}
 
 inline bool named_semaphore::remove(const char *name)
 { return detail::named_semaphore_wrapper::remove(name); }
@@ -210,7 +216,13 @@
 { return semaphore()->try_wait(); }
 
 inline bool named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
-{ return semaphore()->timed_wait(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait();
+ return true;
+ }
+ return semaphore()->timed_wait(abs_time);
+}
 
 inline bool named_semaphore::remove(const char *name)
 { return shared_memory_object::remove(name); }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -185,7 +185,7 @@
    //!Precondition: The thread must have upgradable ownership of the mutex.
    //!Effects: The thread atomically releases upgradable ownership and acquires
    //! exclusive ownership. This operation will block until all threads with
- //! sharable ownership releas it.
+ //! sharable ownership release it.
    //!Throws: An exception derived from interprocess_exception on error.
    void unlock_upgradable_and_lock();
 
@@ -285,7 +285,13 @@
 
 inline bool named_upgradable_mutex::timed_lock
    (const boost::posix_time::ptime &abs_time)
-{ return this->mutex()->timed_lock(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
+ return this->mutex()->timed_lock(abs_time);
+}
 
 inline void named_upgradable_mutex::lock_upgradable()
 { this->mutex()->lock_upgradable(); }
@@ -298,7 +304,13 @@
 
 inline bool named_upgradable_mutex::timed_lock_upgradable
    (const boost::posix_time::ptime &abs_time)
-{ return this->mutex()->timed_lock_upgradable(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock_upgradable();
+ return true;
+ }
+ return this->mutex()->timed_lock_upgradable(abs_time);
+}
 
 inline void named_upgradable_mutex::lock_sharable()
 { this->mutex()->lock_sharable(); }
@@ -311,7 +323,13 @@
 
 inline bool named_upgradable_mutex::timed_lock_sharable
    (const boost::posix_time::ptime &abs_time)
-{ return this->mutex()->timed_lock_sharable(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock_sharable();
+ return true;
+ }
+ return this->mutex()->timed_lock_sharable(abs_time);
+}
 
 inline void named_upgradable_mutex::unlock_and_lock_upgradable()
 { this->mutex()->unlock_and_lock_upgradable(); }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -63,6 +63,10 @@
 
 inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
    #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
 
    timespec ts = detail::ptime_to_timespec(abs_time);

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -64,6 +64,10 @@
 
 inline bool interprocess_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
 {
+ if(abs_time == boost::posix_time::pos_infin){
+ this->lock();
+ return true;
+ }
    #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
 
    timespec ts = detail::ptime_to_timespec(abs_time);

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -32,7 +32,13 @@
 { return m_sem.try_wait(); }
 
 inline bool interprocess_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
-{ return m_sem.timed_wait(abs_time); }
+{
+ if(abs_time == boost::posix_time::pos_infin){
+ this->wait();
+ return true;
+ }
+ return m_sem.timed_wait(abs_time);
+}
 /*
 inline int interprocess_semaphore::get_count() const
 { return m_sem.get_count(); }

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -22,7 +22,7 @@
 #ifdef SEM_FAILED
 #define BOOST_INTERPROCESS_POSIX_SEM_FAILED SEM_FAILED
 #else
-#define BOOST_INTERPROCESS_POSIX_SEM_FAILED ((sem_t*)(-1))
+#define BOOST_INTERPROCESS_POSIX_SEM_FAILED (reinterpret_cast<sem_t*>(-1))
 #endif
 
 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -48,7 +48,7 @@
 //!the Mutex does not supply, no harm is done. Mutex ownership can be shared among
 //!sharable_locks, and a single upgradable_lock. sharable_lock does not support
 //!copy semantics. But sharable_lock supports ownership transfer from an sharable_lock,
-//!upgradable_lock and scoped_lock via trasfer_lock syntax.*/
+//!upgradable_lock and scoped_lock via transfer_lock syntax.*/
 template <class SharableMutex>
 class sharable_lock
 {

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -43,12 +43,12 @@
 //!upgradable_lock is meant to carry out the tasks for read-locking, unlocking,
 //!try-read-locking and timed-read-locking (recursive or not) for the Mutex.
 //!Additionally the upgradable_lock can transfer ownership to a scoped_lock
-//!using trasfer_lock syntax. The Mutex need not supply all of the functionality.
+//!using transfer_lock syntax. The Mutex need not supply all of the functionality.
 //!If the client of upgradable_lock<Mutex> does not use functionality which the
 //!Mutex does not supply, no harm is done. Mutex ownership can be shared among
 //!read_locks, and a single upgradable_lock. upgradable_lock does not support
 //!copy semantics. However upgradable_lock supports ownership transfer from
-//!a upgradable_locks or scoped_locks via trasfer_lock syntax.
+//!a upgradable_locks or scoped_locks via transfer_lock syntax.
 template <class UpgradableMutex>
 class upgradable_lock
 {

Modified: branches/release/boost/intrusive/any_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/any_hook.hpp (original)
+++ branches/release/boost/intrusive/any_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -34,7 +34,7 @@
 
 //! Helper metafunction to define a \c \c any_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -43,8 +43,14 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
-
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
+
    typedef detail::generic_hook
    < get_any_node_algo<typename packed_options::void_pointer>
    , typename packed_options::tag
@@ -70,15 +76,21 @@
 //!
 //! \c void_pointer<> is the pointer type that will be used internally in the hook
 //! and the the container configured to use this hook.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class any_base_hook
- : public make_any_base_hook<O1, O2, O3>::type
+ : public make_any_base_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    public:
    //! <b>Effects</b>: If link_mode is or \c safe_link
    //! initializes the node to an unlinked state.
@@ -127,7 +139,7 @@
 
 //! Helper metafunction to define a \c \c any_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -136,7 +148,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_any_node_algo<typename packed_options::void_pointer>
@@ -158,15 +176,21 @@
 //!
 //! \c void_pointer<> is the pointer type that will be used internally in the hook
 //! and the the container configured to use this hook.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class any_member_hook
- : public make_any_member_hook<O1, O2, O3>::type
+ : public make_any_member_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    public:
    //! <b>Effects</b>: If link_mode is or \c safe_link
    //! initializes the node to an unlinked state.

Modified: branches/release/boost/intrusive/avl_set.hpp
==============================================================================
--- branches/release/boost/intrusive/avl_set.hpp (original)
+++ branches/release/boost/intrusive/avl_set.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -31,7 +31,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -323,18 +323,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const avl_set_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -996,65 +997,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_set_impl<T, Options...> &x, const avl_set_impl<T, Options...> &y)
 #else
 (const avl_set_impl<Config> &x, const avl_set_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_set_impl<T, Options...> &x, const avl_set_impl<T, Options...> &y)
 #else
 (const avl_set_impl<Config> &x, const avl_set_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_set_impl<T, Options...> &x, const avl_set_impl<T, Options...> &y)
 #else
 (const avl_set_impl<Config> &x, const avl_set_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_set_impl<T, Options...> &x, const avl_set_impl<T, Options...> &y)
 #else
 (const avl_set_impl<Config> &x, const avl_set_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (avl_set_impl<T, Options...> &x, avl_set_impl<T, Options...> &y)
 #else
 (avl_set_impl<Config> &x, avl_set_impl<Config> &y)
@@ -1063,7 +1064,7 @@
 
 //! Helper metafunction to define a \c avl_set that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1073,19 +1074,41 @@
 {
    /// @cond
    typedef avl_set_impl
- < typename make_avltree_opt<T, O1, O2, O3, O4>::type
+ < typename make_avltree_opt
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <T, O1, O2, O3, O4>
+ #else
+ <T, Options...>
+ #endif
+ ::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class avl_set
- : public make_avl_set<T, O1, O2, O3, O4>::type
+ : public make_avl_set
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <T, O1, O2, O3, O4>
+ #else
+ <T, Options...>
+ #endif
+ ::type
 {
    typedef typename make_avl_set
- <T, O1, O2, O3, O4>::type Base;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <T, O1, O2, O3, O4>
+ #else
+ <T, Options...>
+ #endif
+ ::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;
@@ -1134,7 +1157,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1422,18 +1445,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const avl_multiset_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -2002,65 +2026,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_multiset_impl<T, Options...> &x, const avl_multiset_impl<T, Options...> &y)
 #else
 (const avl_multiset_impl<Config> &x, const avl_multiset_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_multiset_impl<T, Options...> &x, const avl_multiset_impl<T, Options...> &y)
 #else
 (const avl_multiset_impl<Config> &x, const avl_multiset_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_multiset_impl<T, Options...> &x, const avl_multiset_impl<T, Options...> &y)
 #else
 (const avl_multiset_impl<Config> &x, const avl_multiset_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avl_multiset_impl<T, Options...> &x, const avl_multiset_impl<T, Options...> &y)
 #else
 (const avl_multiset_impl<Config> &x, const avl_multiset_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (avl_multiset_impl<T, Options...> &x, avl_multiset_impl<T, Options...> &y)
 #else
 (avl_multiset_impl<Config> &x, avl_multiset_impl<Config> &y)
@@ -2069,7 +2093,7 @@
 
 //! Helper metafunction to define a \c avl_multiset that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -2079,19 +2103,41 @@
 {
    /// @cond
    typedef avl_multiset_impl
- < typename make_avltree_opt<T, O1, O2, O3, O4>::type
+ < typename make_avltree_opt
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <T, O1, O2, O3, O4>
+ #else
+ <T, Options...>
+ #endif
+ ::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class avl_multiset
- : public make_avl_multiset<T, O1, O2, O3, O4>::type
+ : public make_avl_multiset<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_avl_multiset
- <T, O1, O2, O3, O4>::type Base;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <T, O1, O2, O3, O4>
+ #else
+ <T, Options...>
+ #endif
+ ::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/avl_set_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/avl_set_hook.hpp (original)
+++ branches/release/boost/intrusive/avl_set_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -34,7 +34,7 @@
 
 //! Helper metafunction to define a \c avl_set_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
@@ -43,7 +43,12 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3, O4>::type packed_options;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <hook_defaults, O1, O2, O3, O4>
+ #else
+ <hook_defaults, Options...>
+ #endif
+ ::type packed_options;
 
    typedef detail::generic_hook
    < get_avl_set_node_algo<typename packed_options::void_pointer
@@ -76,15 +81,21 @@
 //!
 //! \c optimize_size<> will tell the hook to optimize the hook for size instead
 //! of speed.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3, class O4>
 #endif
 class avl_set_base_hook
- : public make_avl_set_base_hook<O1, O2, O3, O4>::type
+ : public make_avl_set_base_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3, O4>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -153,7 +164,7 @@
 
 //! Helper metafunction to define a \c avl_set_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
@@ -162,7 +173,12 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3, O4>::type packed_options;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <hook_defaults, O1, O2, O3, O4>
+ #else
+ <hook_defaults, Options...>
+ #endif
+ ::type packed_options;
 
    typedef detail::generic_hook
    < get_avl_set_node_algo<typename packed_options::void_pointer
@@ -190,15 +206,21 @@
 //!
 //! \c optimize_size<> will tell the hook to optimize the hook for size instead
 //! of speed.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3, class O4>
 #endif
 class avl_set_member_hook
- : public make_avl_set_member_hook<O1, O2, O3, O4>::type
+ : public make_avl_set_member_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3, O4>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: branches/release/boost/intrusive/avltree.hpp
==============================================================================
--- branches/release/boost/intrusive/avltree.hpp (original)
+++ branches/release/boost/intrusive/avltree.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -36,20 +36,6 @@
 
 /// @cond
 
-template <class T>
-struct internal_default_avl_set_hook
-{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_avl_set_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
-};
-
-template <class T>
-struct get_default_avl_set_hook
-{
- typedef typename T::default_avl_set_hook type;
-};
-
 template <class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
 struct avl_setopt
 {
@@ -63,13 +49,7 @@
 struct avl_set_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < internal_default_avl_set_hook<T>::value
- , get_default_avl_set_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_avl_set_hook>
       , constant_time_size<true>
       , size_type<std::size_t>
       , compare<std::less<T> >
@@ -91,7 +71,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1055,29 +1035,34 @@
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
       if(!src.empty()){
+ detail::exception_disposer<avltree_impl, Disposer>
+ rollback(*this, disposer);
          node_algorithms::clone
             (const_node_ptr(&src.priv_header())
             ,node_ptr(&this->priv_header())
             ,detail::node_cloner<Cloner, avltree_impl>(cloner, this)
             ,detail::node_disposer<Disposer, avltree_impl>(disposer, this));
          this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_comp() = src.priv_comp();
+ rollback.release();
       }
    }
 
@@ -1260,26 +1245,26 @@
    { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y)
 #else
 (const avltree_impl<Config> &x, const avltree_impl<Config> &y)
 #endif
 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 bool operator==
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y)
 #else
 (const avltree_impl<Config> &x, const avltree_impl<Config> &y)
@@ -1311,65 +1296,65 @@
    }
 }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y)
 #else
 (const avltree_impl<Config> &x, const avltree_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y)
 #else
 (const avltree_impl<Config> &x, const avltree_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y)
 #else
 (const avltree_impl<Config> &x, const avltree_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y)
 #else
 (const avltree_impl<Config> &x, const avltree_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (avltree_impl<T, Options...> &x, avltree_impl<T, Options...> &y)
 #else
 (avltree_impl<Config> &x, avltree_impl<Config> &y)
@@ -1377,15 +1362,24 @@
 { x.swap(y); }
 
 /// @cond
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
- , class O5 = none, class O6 = none
- , class O7 = none
>
+#else
+template<class T, class ...Options>
+#endif
 struct make_avltree_opt
 {
    typedef typename pack_options
- < avl_set_defaults<T>, O1, O2, O3, O4>::type packed_options;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ < avl_set_defaults<T>, O1, O2, O3, O4>
+ #else
+ < avl_set_defaults<T>, Options...>
+ #endif
+ ::type packed_options;
+
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
 
@@ -1400,7 +1394,7 @@
 
 //! Helper metafunction to define a \c avltree that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1410,19 +1404,37 @@
 {
    /// @cond
    typedef avltree_impl
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
       < typename make_avltree_opt<T, O1, O2, O3, O4>::type
+ #else
+ < typename make_avltree_opt<T, Options...>::type
+ #endif
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class avltree
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
    : public make_avltree<T, O1, O2, O3, O4>::type
+ #else
+ : public make_avltree<T, Options...>::type
+ #endif
 {
    typedef typename make_avltree
- <T, O1, O2, O3, O4>::type Base;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <T, O1, O2, O3, O4>
+ #else
+ <T, Options...>
+ #endif
+ ::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/avltree_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/avltree_algorithms.hpp (original)
+++ branches/release/boost/intrusive/avltree_algorithms.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -682,10 +682,10 @@
                // x is right child
                // a is left child
                node_ptr a = NodeTraits::get_left(x_parent);
- assert(a);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
                if (NodeTraits::get_balance(a) == NodeTraits::positive()) {
                   // a MUST have a right child
- assert(NodeTraits::get_right(a));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(a));
                   rotate_left_right(x_parent, root);
                   
                   x = NodeTraits::get_parent(x_parent);
@@ -714,10 +714,10 @@
                // x is left child
                // a is right child
                node_ptr a = NodeTraits::get_right(x_parent);
- assert(a);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
                if (NodeTraits::get_balance(a) == NodeTraits::negative()) {
                   // a MUST have then a left child
- assert(NodeTraits::get_left(a));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(a));
                   rotate_right_left(x_parent, root);
 
                   x = NodeTraits::get_parent(x_parent);
@@ -735,7 +735,7 @@
             }
          }
          else{
- assert(false); // never reached
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
          }
       }
       NodeTraits::set_parent(header, root);
@@ -784,7 +784,7 @@
             break;
          }
          else{
- assert(false); // never reached
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
          }
       }
       NodeTraits::set_parent(header, root);
@@ -842,7 +842,7 @@
          NodeTraits::set_balance(b, NodeTraits::negative());
       }
       else{
- assert(false); // never reached
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
       }
       NodeTraits::set_balance(c, NodeTraits::zero());
    }
@@ -899,7 +899,7 @@
          NodeTraits::set_balance(b, NodeTraits::zero());
       }
       else{
- assert(false);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(false);
       }
       NodeTraits::set_balance(c, NodeTraits::zero());
    }

Modified: branches/release/boost/intrusive/bs_set_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/bs_set_hook.hpp (original)
+++ branches/release/boost/intrusive/bs_set_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -34,7 +34,7 @@
 
 //! Helper metafunction to define a \c bs_set_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -43,7 +43,12 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ < hook_defaults, O1, O2, O3>
+ #else
+ < hook_defaults, Options...>
+ #endif
+ ::type packed_options;
 
    //Scapegoat trees can't be auto unlink trees
    BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink));
@@ -75,15 +80,22 @@
 //!
 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
 //! \c auto_unlink or \c safe_link).
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class bs_set_base_hook
- : public make_bs_set_base_hook<O1, O2, O3>::type
+ : public make_bs_set_base_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3>
+ #else
+ <Options...>
+ #endif
+ ::type
+
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -152,7 +164,7 @@
 
 //! Helper metafunction to define a \c bs_set_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -161,7 +173,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ < hook_defaults, O1, O2, O3>
+ #else
+ < hook_defaults, Options...>
+ #endif
+
+ ::type packed_options;
 
    //Scapegoat trees can't be auto unlink trees
    BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink));
@@ -187,15 +205,21 @@
 //!
 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
 //! \c auto_unlink or \c safe_link).
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class bs_set_member_hook
- : public make_bs_set_member_hook<O1, O2, O3>::type
+ : public make_bs_set_member_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -262,24 +286,6 @@
    #endif
 };
 
-/// @cond
-
-template <class T>
-struct internal_default_bs_set_hook
-{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_bs_set_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
-};
-
-template <class T>
-struct get_default_bs_set_hook
-{
- typedef typename T::default_bs_set_hook type;
-};
-
-/// @endcond
-
 } //namespace intrusive
 } //namespace boost
 

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -59,7 +59,7 @@
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;
 
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Constructs an non-used list element, putting the next
    //! pointer to null:
@@ -128,7 +128,7 @@
    //! <b>Throws</b>: Nothing.
    static void transfer_after(node_ptr p, node_ptr b, node_ptr e);
 
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Constructs an empty list, making this_node the only
    //! node of the circular list:

Modified: branches/release/boost/intrusive/detail/any_node_and_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/any_node_and_algorithms.hpp (original)
+++ branches/release/boost/intrusive/detail/any_node_and_algorithms.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -18,6 +18,7 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <cstddef>
+#include <boost/intrusive/detail/mpl.hpp>
 
 namespace boost {
 namespace intrusive {
@@ -238,6 +239,10 @@
 template<class VoidPointer>
 class any_algorithms
 {
+ template <class T>
+ static void function_not_available_for_any_hooks(typename detail::enable_if<detail::is_same<T, bool> >::type)
+ {}
+
    public:
    typedef any_node<VoidPointer> node;
    typedef typename boost::pointer_to_other
@@ -269,28 +274,18 @@
    static bool unique(const_node_ptr node)
    { return 0 == node->node_ptr_1; }
 
-
-#if defined(__EDG__) && defined(__STD_STRICT_ANSI)
- // For compilers checking the full source code at compile time, regardless
- // of whether the code is instantiated or not, we turn the compile error
- // below into a link error.
- static void unlink(node_ptr);
- static void swap_nodes(node_ptr l, node_ptr r);
-#else
    static void unlink(node_ptr)
    {
- //Auto-unlink hooks and unlink() call for safe hooks are not
- //available for any hooks!!!
- any_algorithms<VoidPointer>::unlink_not_available_for_any_hooks();
+ //Auto-unlink hooks and unlink() are not available for any hooks
+ any_algorithms<VoidPointer>::template function_not_available_for_any_hooks<node_ptr>();
    }
 
    static void swap_nodes(node_ptr l, node_ptr r)
    {
       //Any nodes have no swap_nodes capability because they don't know
- //what algorithm they must use from unlink them from the container
- any_algorithms<VoidPointer>::swap_nodes_not_available_for_any_hooks();
+ //what algorithm they must use to unlink the node from the container
+ any_algorithms<VoidPointer>::template function_not_available_for_any_hooks<node_ptr>();
    }
-#endif
 };
 
 } //namespace intrusive

Modified: branches/release/boost/intrusive/detail/assert.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/assert.hpp (original)
+++ branches/release/boost/intrusive/detail/assert.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -18,18 +18,24 @@
 #endif
 
 #if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT)
-#include <boost/assert.hpp>
-#define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT
+ #include <boost/assert.hpp>
+ #define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT
+#elif defined(BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE)
+ #include BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE
 #endif
 
 #if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT)
-#include <boost/assert.hpp>
-#define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT
+ #include <boost/assert.hpp>
+ #define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT
+#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE)
+ #include BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE
 #endif
 
 #if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT)
-#include <boost/assert.hpp>
-#define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT
+ #include <boost/assert.hpp>
+ #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT
+#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE)
+ #include BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE
 #endif
 
 #endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP

Modified: branches/release/boost/intrusive/detail/list_node.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/list_node.hpp (original)
+++ branches/release/boost/intrusive/detail/list_node.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -161,6 +161,9 @@
          return 0;
    }
 
+ list_iterator<Container, false> unconst() const
+ { return list_iterator<Container, false>(this->pointed_node(), this->get_container()); }
+
    private:
    struct members
       : public detail::select_constptr

Modified: branches/release/boost/intrusive/detail/mpl.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/mpl.hpp (original)
+++ branches/release/boost/intrusive/detail/mpl.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -51,6 +51,12 @@
 template <class Cond, class T = void>
 struct enable_if : public enable_if_c<Cond::value, T>{};
 
+template<class F, class Param>
+struct apply
+{
+ typedef typename F::template apply<Param>::type type;
+};
+
 template <class T, class U>
 class is_convertible
 {
@@ -127,83 +133,127 @@
 #define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
 #endif
 
-no_type BOOST_INTRUSIVE_TT_DECL is_function_ptr_tester(...);
-
-template <class R >
-yes_type is_function_ptr_tester(R (*)());
-
-template <class R >
-yes_type is_function_ptr_tester(R (*)( ...));
+template <typename T>
+struct is_unary_or_binary_function_impl
+{ static const bool value = false; };
 
+template <typename R>
+struct is_unary_or_binary_function_impl<R (*)()>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (*)(...)>
+{ static const bool value = true; };
+/*
 #ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
-template <class R >
-yes_type is_function_ptr_tester(R (__stdcall*)());
-template <class R >
-yes_type is_function_ptr_tester(R (__stdcall*)( ...));
-
-template <class R >
-yes_type is_function_ptr_tester(R (__fastcall*)());
-template <class R >
-yes_type is_function_ptr_tester(R (__fastcall*)( ...));
-
-template <class R >
-yes_type is_function_ptr_tester(R (__cdecl*)());
-template <class R >
-yes_type is_function_ptr_tester(R (__cdecl*)( ...));
-#endif
-
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (*)( T0));
 
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (*)( T0 ...));
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__stdcall*)()>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__stdcall*)(...)>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__stdcall*)(...)>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__fastcall*)()>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__fastcall*)(...)>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__cdecl*)()>
+{ static const bool value = true; };
+
+template <typename R>
+struct is_unary_or_binary_function_impl<R (__cdecl*)(...)>
+{ static const bool value = true; };
+#endif
+*/
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (*)(T0)>
+{ static const bool value = true; };
+
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (*)(T0...)>
+{ static const bool value = true; };
 
 #ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (__stdcall*)( T0));
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (__stdcall*)( T0 ...));
-
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (__fastcall*)( T0));
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (__fastcall*)( T0 ...));
 
-template <class R , class T0 >
-yes_type is_function_ptr_tester(R (__cdecl*)( T0));
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)>
+{ static const bool value = true; };
+/*
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (__stdcall*)(T0...)>
+{ static const bool value = true; };
+
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
+{ static const bool value = true; };
+
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (__fastcall*)(T0...)>
+{ static const bool value = true; };
+
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
+{ static const bool value = true; };
+
+template <typename R, class T0>
+struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)>
+{ static const bool value = true; };
+*/
 #endif
-template <class R , class T0 , class T1 >
-yes_type is_function_ptr_tester(R (*)( T0 , T1));
 
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
+{ static const bool value = true; };
+
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (*)(T0, T1...)>
+{ static const bool value = true; };
+/*
 #ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
-template <class R , class T0 , class T1 >
-yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1));
-
-template <class R , class T0 , class T1 >
-yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1));
 
-template <class R , class T0 , class T1 >
-yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1));
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
+{ static const bool value = true; };
+
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1...)>
+{ static const bool value = true; };
+
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
+{ static const bool value = true; };
+
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1...)>
+{ static const bool value = true; };
+
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
+{ static const bool value = true; };
+
+template <typename R, class T0, class T1>
+struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
+{ static const bool value = true; };
 #endif
-
-template <typename T>
-struct is_unary_or_binary_function_impl
-{
- static T* t;
- static const bool value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type);
-};
-
+*/
 template <typename T>
 struct is_unary_or_binary_function_impl<T&>
-{
- static const bool value = false;
-};
+{ static const bool value = false; };
 
 template<typename T>
 struct is_unary_or_binary_function
-{
- static const bool value = is_unary_or_binary_function_impl<T>::value;
-};
+{ static const bool value = is_unary_or_binary_function_impl<T>::value; };
 
 //boost::alignment_of yields to 10K lines of preprocessed code, so we
 //need an alternative

Modified: branches/release/boost/intrusive/detail/slist_node.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/slist_node.hpp (original)
+++ branches/release/boost/intrusive/detail/slist_node.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -128,6 +128,9 @@
          return 0;
    }
 
+ slist_iterator<Container, false> unconst() const
+ { return slist_iterator<Container, false>(this->pointed_node(), this->get_container()); }
+
    const real_value_traits *get_real_value_traits() const
    {
       if(store_container_ptr)

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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -1391,14 +1391,14 @@
       //Taken from:
       //"Tree rebalancing in optimal time and space"
       //Quentin F. Stout and Bette L. Warren
- std::size_t len;
+ std::size_t len = 0;
       subtree_to_vine(NodeTraits::get_parent(header), &len);
       vine_to_subtree(NodeTraits::get_parent(header), len);
    }
 
    static node_ptr rebalance_subtree(node_ptr old_root)
    {
- std::size_t len;
+ std::size_t len = 0;
       node_ptr new_root = subtree_to_vine(old_root, &len);
       return vine_to_subtree(new_root, len);
    }

Modified: branches/release/boost/intrusive/hashtable.hpp
==============================================================================
--- branches/release/boost/intrusive/hashtable.hpp (original)
+++ branches/release/boost/intrusive/hashtable.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -43,6 +43,50 @@
 
 namespace detail {
 
+struct hash_bool_flags
+{
+ static const std::size_t unique_keys_pos = 1u;
+ static const std::size_t constant_time_size_pos = 2u;
+ static const std::size_t power_2_buckets_pos = 4u;
+ static const std::size_t cache_begin_pos = 8u;
+ static const std::size_t compare_hash_pos = 16u;
+ static const std::size_t incremental_pos = 32u;
+};
+
+template
+ < class ValueTraits
+ , class Hash
+ , class Equal
+ , class SizeType
+ , class BucketTraits
+ , std::size_t BoolFlags
+ >
+struct usetopt
+{
+ typedef ValueTraits value_traits;
+ typedef Hash hash;
+ typedef Equal equal;
+ typedef SizeType size_type;
+ typedef BucketTraits bucket_traits;
+ static const std::size_t bool_flags = BoolFlags;
+};
+
+template
+ < class UsetOpt
+ , std::size_t BoolMask
+ >
+struct usetopt_mask
+{
+ typedef usetopt
+ <typename UsetOpt::value_traits
+ ,typename UsetOpt::hash
+ ,typename UsetOpt::equal
+ ,typename UsetOpt::size_type
+ ,typename UsetOpt::bucket_traits
+ ,UsetOpt::bool_flags & BoolMask
+ > type;
+};
+
 template <class NodeTraits>
 struct hash_reduced_slist_node_traits
 {
@@ -109,7 +153,6 @@
>::type type;
 };
 
-
 template<class SupposedValueTraits>
 struct unordered_bucket_impl
 {
@@ -173,11 +216,11 @@
 template<class Config>
 struct bucket_plus_size
    : public detail::size_holder
- < Config::constant_time_size
+ < 0 != (Config::bool_flags & hash_bool_flags::constant_time_size_pos)
       , typename Config::size_type>
 {
    typedef detail::size_holder
- < Config::constant_time_size
+ < 0 != (Config::bool_flags & hash_bool_flags::constant_time_size_pos)
       , typename Config::size_type> size_traits;
    typedef typename Config::bucket_traits bucket_traits;
 
@@ -188,11 +231,12 @@
 };
 
 template<class Config>
-struct bucket_hash_t : public detail::ebo_functor_holder<typename Config::hash>
+struct bucket_hash_t
+ : public detail::ebo_functor_holder<typename Config::hash>
 {
    typedef typename Config::hash hasher;
    typedef detail::size_holder
- < Config::constant_time_size
+ < 0 != (Config::bool_flags & hash_bool_flags::constant_time_size_pos)
       , typename Config::size_type> size_traits;
    typedef typename Config::bucket_traits bucket_traits;
 
@@ -236,6 +280,7 @@
 template<class Config>
 struct hashtable_data_t : public Config::value_traits
 {
+ static const std::size_t bool_flags = Config::bool_flags;
    typedef typename Config::value_traits value_traits;
    typedef typename Config::equal equal;
    typedef typename Config::hash hasher;
@@ -243,9 +288,27 @@
 
    hashtable_data_t( const bucket_traits &b_traits, const hasher & h
                    , const equal &e, const value_traits &val_traits)
- : Config::value_traits(val_traits), bucket_hash_equal_(b_traits, h, e)
+ : Config::value_traits(val_traits), internal_(b_traits, h, e)
    {}
- bucket_hash_equal_t<Config, Config::cache_begin> bucket_hash_equal_;
+ typedef typename detail::usetopt_mask
+ < Config
+ , detail::hash_bool_flags::constant_time_size_pos
+ | detail::hash_bool_flags::incremental_pos
+ >::type masked_config_t;
+ struct internal
+ : public detail::size_holder
+ < 0 != (Config::bool_flags & hash_bool_flags::incremental_pos)
+ , typename Config::size_type>
+ {
+ internal(const bucket_traits &b_traits, const hasher & h, const equal &e)
+ : bucket_hash_equal_(b_traits, h, e)
+ {}
+
+ bucket_hash_equal_t
+ < masked_config_t
+ , 0 != (bool_flags & hash_bool_flags::cache_begin_pos)
+ > bucket_hash_equal_;
+ } internal_;
 };
 
 struct insert_commit_data_impl
@@ -253,12 +316,154 @@
    std::size_t hash;
 };
 
-template <class T>
-struct internal_default_uset_hook
+template<class NodeTraits>
+struct group_functions
 {
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_uset_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
+ typedef NodeTraits node_traits;
+ typedef unordered_group_adapter<node_traits> group_traits;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::node node;
+ typedef typename reduced_slist_node_traits
+ <node_traits>::type reduced_node_traits;
+ typedef typename reduced_node_traits::node_ptr slist_node_ptr;
+ typedef typename reduced_node_traits::node slist_node;
+ typedef circular_slist_algorithms<group_traits> group_algorithms;
+
+ static node_ptr dcast_bucket_ptr(slist_node_ptr p)
+ { return node_ptr(&static_cast<node&>(*p)); }
+
+ static slist_node_ptr priv_get_bucket_before_begin
+ (slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p)
+ {
+ //First find the last node of p's group.
+ //This requires checking the first node of the next group or
+ //the bucket node.
+ node_ptr prev_node = p;
+ node_ptr nxt(node_traits::get_next(p));
+ while(!(bucket_beg <= nxt && nxt <= bucket_end) &&
+ (group_traits::get_next(nxt) == prev_node)){
+ prev_node = nxt;
+ nxt = node_traits::get_next(nxt);
+ }
+
+ //If we've reached the bucket node just return it.
+ if(bucket_beg <= nxt && nxt <= bucket_end){
+ return nxt;
+ }
+
+ //Otherwise, iterate using group links until the bucket node
+ node_ptr first_node_of_group = nxt;
+ node_ptr last_node_group = group_traits::get_next(first_node_of_group);
+ slist_node_ptr possible_end = node_traits::get_next(last_node_group);
+
+ while(!(bucket_beg <= possible_end && possible_end <= bucket_end)){
+ first_node_of_group = dcast_bucket_ptr(possible_end);
+ last_node_group = group_traits::get_next(first_node_of_group);
+ possible_end = node_traits::get_next(last_node_group);
+ }
+ return possible_end;
+ }
+
+ static node_ptr priv_get_prev_to_first_in_group(slist_node_ptr bucket_node, node_ptr first_in_group)
+ {
+ //Just iterate using group links and obtain the node
+ //before "first_in_group)"
+ node_ptr prev_node = dcast_bucket_ptr(bucket_node);
+ node_ptr nxt(node_traits::get_next(prev_node));
+ while(nxt != first_in_group){
+ prev_node = group_traits::get_next(nxt);
+ nxt = node_traits::get_next(prev_node);
+ }
+ return prev_node;
+ }
+
+ static node_ptr priv_get_first_in_group_of_last_in_group(node_ptr last_in_group)
+ {
+ //Just iterate using group links and obtain the node
+ //before "last_in_group"
+ node_ptr possible_first = group_traits::get_next(last_in_group);
+ node_ptr possible_first_prev = group_traits::get_next(possible_first);
+ // The deleted node is at the end of the group, so the
+ // node in the group pointing to it is at the beginning
+ // of the group. Find that to change its pointer.
+ while(possible_first_prev != last_in_group){
+ possible_first = possible_first_prev;
+ possible_first_prev = group_traits::get_next(possible_first);
+ }
+ return possible_first;
+ }
+
+
+ static void priv_erase_from_group(slist_node_ptr end_ptr, node_ptr to_erase_ptr, detail::true_)
+ {
+ node_ptr nxt_ptr(node_traits::get_next(to_erase_ptr));
+ node_ptr prev_in_group_ptr(group_traits::get_next(to_erase_ptr));
+ bool last_in_group = (end_ptr == nxt_ptr) ||
+ (group_traits::get_next(nxt_ptr) != to_erase_ptr);
+ bool first_in_group = node_traits::get_next(prev_in_group_ptr) != to_erase_ptr;
+
+ if(first_in_group && last_in_group){
+ group_algorithms::init(to_erase_ptr);
+ }
+ else if(first_in_group){
+ group_algorithms::unlink_after(nxt_ptr);
+ }
+ else if(last_in_group){
+ node_ptr first_in_group =
+ priv_get_first_in_group_of_last_in_group(to_erase_ptr);
+ group_algorithms::unlink_after(first_in_group);
+ }
+ else{
+ group_algorithms::unlink_after(nxt_ptr);
+ }
+ }
+
+ static void priv_erase_from_group(slist_node_ptr, node_ptr, detail::false_)
+ {}
+
+ static node_ptr priv_get_last_in_group(node_ptr first_in_group, detail::true_)
+ { return group_traits::get_next(first_in_group); }
+
+ static node_ptr priv_get_last_in_group(node_ptr n, detail::false_)
+ { return n; }
+};
+
+template<class BucketType, class SplitTraits>
+class incremental_rehash_rollback
+{
+ private:
+ typedef BucketType bucket_type;
+ typedef SplitTraits split_traits;
+
+ incremental_rehash_rollback();
+ incremental_rehash_rollback & operator=(const incremental_rehash_rollback &);
+ incremental_rehash_rollback (const incremental_rehash_rollback &);
+
+ public:
+ incremental_rehash_rollback
+ (bucket_type &source_bucket, bucket_type &destiny_bucket, split_traits &split_traits)
+ : source_bucket_(source_bucket), destiny_bucket_(destiny_bucket)
+ , split_traits_(split_traits), released_(false)
+ {}
+
+ void release()
+ { released_ = true; }
+
+ ~incremental_rehash_rollback()
+ {
+ if(!released_){
+ //If an exception is thrown, just put all moved nodes back in the old bucket
+ //and move back the split mark.
+ destiny_bucket_.splice_after(destiny_bucket_.before_begin(), source_bucket_);
+ split_traits_.decrement();
+ }
+ }
+
+ private:
+ bucket_type &source_bucket_;
+ bucket_type &destiny_bucket_;
+ split_traits &split_traits_;
+ bool released_;
 };
 
 } //namespace detail {
@@ -304,50 +509,13 @@
    typedef implementation_defined type;
 };
 
-template <class T>
-struct get_default_uset_hook
-{
- typedef typename T::default_uset_hook type;
-};
-
-template < class ValueTraits
- , bool UniqueKeys
- , class Hash
- , class Equal
- , class SizeType
- , bool ConstantTimeSize
- , class BucketTraits
- , bool Power2Buckets
- , bool CacheBegin
- , bool CompareHash
- >
-struct usetopt
-{
- typedef ValueTraits value_traits;
- typedef Hash hash;
- typedef Equal equal;
- typedef SizeType size_type;
- typedef BucketTraits bucket_traits;
- static const bool constant_time_size = ConstantTimeSize;
- static const bool power_2_buckets = Power2Buckets;
- static const bool unique_keys = UniqueKeys;
- static const bool cache_begin = CacheBegin;
- static const bool compare_hash = CompareHash;
-};
-
 struct default_bucket_traits;
 
 template <class T>
 struct uset_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < detail::internal_default_uset_hook<T>::value
- , get_default_uset_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_uset_hook>
       , constant_time_size<true>
       , size_type<std::size_t>
       , equal<std::equal_to<T> >
@@ -356,6 +524,7 @@
       , power_2_buckets<false>
       , cache_begin<false>
       , compare_hash<false>
+ , incremental<false>
>::type
 {};
 
@@ -380,7 +549,7 @@
 //! The container supports the following options:
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
-//! \c bucket_traits<>, power_2_buckets<> and cache_begin<>.
+//! \c bucket_traits<>, power_2_buckets<>, cache_begin<> and incremental<>.
 //!
 //! hashtable only provides forward iterators but it provides 4 iterator types:
 //! iterator and const_iterator to navigate through the whole container and
@@ -397,13 +566,12 @@
 //!
 //! Since no automatic rehashing is done, iterators are never invalidated when
 //! inserting or erasing elements. Iterators are only invalidated when rehashing.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 class hashtable_impl
- : private detail::hashtable_data_t<Config>
 {
    public:
    typedef typename Config::value_traits value_traits;
@@ -455,18 +623,22 @@
       <node_ptr, const node>::type const_node_ptr;
    typedef typename slist_impl::node_algorithms node_algorithms;
 
- static const bool constant_time_size = Config::constant_time_size;
    static const bool stateful_value_traits = detail::store_cont_ptr_on_it<hashtable_impl>::value;
    static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
- static const bool unique_keys = Config::unique_keys;
+
+ static const bool unique_keys = 0 != (Config::bool_flags & detail::hash_bool_flags::unique_keys_pos);
+ static const bool constant_time_size = 0 != (Config::bool_flags & detail::hash_bool_flags::constant_time_size_pos);
+ static const bool cache_begin = 0 != (Config::bool_flags & detail::hash_bool_flags::cache_begin_pos);
+ static const bool compare_hash = 0 != (Config::bool_flags & detail::hash_bool_flags::compare_hash_pos);
+ static const bool incremental = 0 != (Config::bool_flags & detail::hash_bool_flags::incremental_pos);
+ static const bool power_2_buckets = incremental || (0 != (Config::bool_flags & detail::hash_bool_flags::power_2_buckets_pos));
+
    static const bool optimize_multikey
       = detail::optimize_multikey_is_true<node_traits>::value && !unique_keys;
- static const bool power_2_buckets = Config::power_2_buckets;
- static const bool cache_begin = Config::cache_begin;
- static const bool compare_hash = Config::compare_hash;
 
    /// @cond
    private:
+
    //Configuration error: compare_hash<> can't be specified without store_hash<>
    //See documentation for more explanations
    BOOST_STATIC_ASSERT((!compare_hash || store_hash));
@@ -483,7 +655,17 @@
    typedef detail::bool_<cache_begin> cache_begin_t;
    typedef detail::bool_<power_2_buckets> power_2_buckets_t;
    typedef detail::size_holder<constant_time_size, size_type> size_traits;
- typedef detail::hashtable_data_t<Config> base_type;
+ typedef detail::size_holder<incremental, size_type> split_traits;
+ typedef detail::group_functions<node_traits> group_functions_t;
+
+ static const std::size_t hashtable_data_bool_flags_mask =
+ ( detail::hash_bool_flags::cache_begin_pos
+ | detail::hash_bool_flags::constant_time_size_pos
+ | detail::hash_bool_flags::incremental_pos
+ );
+ typedef typename detail::usetopt_mask
+ <Config, hashtable_data_bool_flags_mask>::type masked_config_t;
+ detail::hashtable_data_t<masked_config_t> data_;
 
    template<bool IsConst>
    struct downcast_node_to_value
@@ -555,16 +737,16 @@
    /// @cond
 
    const real_value_traits &get_real_value_traits(detail::bool_<false>) const
- { return *this; }
+ { return this->data_; }
 
    const real_value_traits &get_real_value_traits(detail::bool_<true>) const
- { return base_type::get_value_traits(*this); }
+ { return data_.get_value_traits(*this); }
 
    real_value_traits &get_real_value_traits(detail::bool_<false>)
- { return *this; }
+ { return this->data_; }
 
    real_value_traits &get_real_value_traits(detail::bool_<true>)
- { return base_type::get_value_traits(*this); }
+ { return data_.get_value_traits(*this); }
 
    /// @endcond
 
@@ -593,14 +775,16 @@
                   , const hasher & hash_func = hasher()
                   , const key_equal &equal_func = key_equal()
                   , const value_traits &v_traits = value_traits())
- : base_type(b_traits, hash_func, equal_func, v_traits)
+ : data_(b_traits, hash_func, equal_func, v_traits)
    {
       priv_initialize_buckets();
       this->priv_size_traits().set_size(size_type(0));
- BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_buckets_len() != 0);
+ size_type bucket_size = this->priv_buckets_len();
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_size != 0);
       //Check power of two bucket array if the option is activated
       BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (this->priv_buckets_len() & (this->priv_buckets_len()-1))));
+ (!power_2_buckets || (0 == (bucket_size & (bucket_size-1))));
+ priv_split_traits().set_size(bucket_size>>1);
    }
 
    //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set
@@ -620,10 +804,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    iterator begin()
- {
- size_type bucket_num;
- return iterator(this->priv_begin(bucket_num), this);
- }
+ { return iterator(this->priv_begin(), this); }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
    //! of the unordered_set.
@@ -643,10 +824,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    const_iterator cbegin() const
- {
- size_type bucket_num;
- return const_iterator(this->priv_begin(bucket_num), this);
- }
+ { return const_iterator(this->priv_begin(), this); }
 
    //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
    //!
@@ -760,21 +938,32 @@
          this->priv_size_traits().set_size(other.priv_size_traits().get_size());
          other.priv_size_traits().set_size(backup);
       }
+ else if(incremental){
+ size_type backup = this->priv_split_traits().get_size();
+ this->priv_split_traits().set_size(other.priv_split_traits().get_size());
+ other.priv_split_traits().set_size(backup);
+ }
    }
 
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw
+ //! Cloner should yield to nodes that compare equal and produce the same
+ //! hash than the original node.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. The hash function and the equality
+ //! predicate are copied from the source.
    //!
- //! If cloner throws, all cloned elements are unlinked and disposed
+ //! If store_hash option is true, this method does not use the hash function.
+ //!
+ //! If any operation throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
- //!
+ //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
+ //! throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const hashtable_impl &src, Cloner cloner, Disposer disposer)
    {
@@ -789,7 +978,7 @@
          (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1))));
 
          //If src bucket count is bigger or equal, structural copy is possible
- if(src_bucket_count >= dst_bucket_count){
+ if(!incremental && (src_bucket_count >= dst_bucket_count)){
             //First clone the first ones
             const bucket_ptr src_buckets = src.priv_buckets();
             const bucket_ptr dst_buckets = this->priv_buckets();
@@ -813,7 +1002,7 @@
                   ; constructed < src_bucket_count
                   ; ++constructed){
                   bucket_type &dst_b =
- dst_buckets[priv_hash_to_bucket(constructed, dst_bucket_count)];
+ dst_buckets[priv_hash_to_bucket(constructed, dst_bucket_count, dst_bucket_count)];
                   bucket_type &src_b = src_buckets[constructed];
                   for( siterator b(src_b.begin()), e(src_b.end())
                      ; b != e
@@ -822,14 +1011,29 @@
                   }
                }
             }
+ this->priv_hasher() = src.priv_hasher();
+ this->priv_equal() = src.priv_equal();
             rollback.release();
             this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_split_traits().set_size(dst_bucket_count);
             priv_insertion_update_cache(0u);
             priv_erasure_update_cache();
          }
+ else if(store_hash){
+ //Unlike previous cloning algorithm, this can throw
+ //if cloner, hasher or comparison functor throw
+ const_iterator b(src.begin()), e(src.end());
+ detail::exception_disposer<hashtable_impl, Disposer>
+ rollback(*this, disposer);
+ for(; b != e; ++b){
+ std::size_t hash_value = this->priv_stored_or_compute_hash(*b, store_hash_t());;
+ this->priv_insert_equal_with_hash(*cloner(*b), hash_value);
+ }
+ rollback.release();
+ }
          else{
             //Unlike previous cloning algorithm, this can throw
- //if cloner, the hasher or comparison functor throw
+ //if cloner, hasher or comparison functor throw
             const_iterator b(src.begin()), e(src.end());
             detail::exception_disposer<hashtable_impl, Disposer>
                rollback(*this, disposer);
@@ -848,23 +1052,7 @@
       siterator prev;
       siterator it = this->priv_find
          (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
- bucket_type &b = this->priv_buckets()[bucket_num];
- bool found_equal = it != priv_invalid_local_it();
- node_ptr n = node_ptr(&priv_value_to_node(value));
- this->priv_store_hash(n, hash_value, store_hash_t());
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- if(!found_equal){
- it = b.before_begin();
- }
- if(optimize_multikey){
- node_ptr first_in_group = found_equal ?
- dcast_bucket_ptr(it.pointed_node()) : node_ptr(0);
- this->priv_insert_in_group(first_in_group, n, optimize_multikey_t());
- }
- priv_insertion_update_cache(bucket_num);
- this->priv_size_traits().increment();
- return iterator(b.insert_after(it, *n), this);
+ return priv_insert_equal_find(value, bucket_num, hash_value, it);
    }
 
    template<class Iterator>
@@ -968,7 +1156,7 @@
          this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
       bool success = prev_pos == priv_invalid_local_it();
       if(success){
- prev_pos = this->priv_buckets()[bucket_num].before_begin();
+ prev_pos = prev;
       }
       return std::pair<iterator, bool>(iterator(prev_pos, this),success);
    }
@@ -1177,8 +1365,8 @@
       }
       else if(optimize_multikey){
          siterator last = bucket_type::s_iterator_to
- (*node_traits::get_next(priv_get_last_in_group
- (dcast_bucket_ptr(it.pointed_node()))));
+ (*node_traits::get_next(group_functions_t::priv_get_last_in_group
+ (dcast_bucket_ptr(it.pointed_node()), optimize_multikey_t())));
          this->priv_erase_range_impl(bucket_num, prev, last, disposer, count);
       }
       else{
@@ -1188,7 +1376,7 @@
             slist_node_ptr n(it.pointed_node());
             const value_type &v = priv_value_from_slist_node(n);
             if(compare_hash){
- std::size_t vh = this->priv_stored_hash(v, store_hash_t());
+ std::size_t vh = this->priv_stored_or_compute_hash(v, store_hash_t());
                if(h != vh || !equal_func(key, v)){
                   break;
                }
@@ -1676,9 +1864,15 @@
    //! or the same as the old bucket array. new_size is the length of the
    //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
    //! n can be bigger or smaller than this->bucket_count().
+ //! 'new_bucket_traits' copy constructor should not throw.
    //!
    //! <b>Effects</b>: Updates the internal reference with the new bucket erases
- //! the values from the old bucket and inserts then in the new one.
+ //! the values from the old bucket and inserts then in the new one.
+ //! Bucket traits hold by *this is assigned from new_bucket_traits.
+ //! If the container is configured as incremental<>, the split bucket is set
+ //! to the new bucket_len().
+ //!
+ //! If store_hash option is true, this method does not use the hash function.
    //!
    //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
    //!
@@ -1698,7 +1892,7 @@
       const bool same_buffer = old_buckets == new_buckets;
       //If the new bucket length is a common factor
       //of the old one we can avoid hash calculations.
- const bool fast_shrink = (old_buckets_len > new_buckets_len) &&
+ const bool fast_shrink = (!incremental) && (old_buckets_len > new_buckets_len) &&
          (power_2_buckets ||(old_buckets_len % new_buckets_len) == 0);
       //If we are shrinking the same bucket array and it's
       //is a fast shrink, just rehash the last nodes
@@ -1708,7 +1902,9 @@
          new_first_bucket_num = priv_get_cache_bucket_num();
       }
 
- //Anti-exception stuff: they destroy the elements if something goes wrong
+ //Anti-exception stuff: they destroy the elements if something goes wrong.
+ //If the source and destination buckets are the same, the second rollback function
+ //is harmless, because all elements have been already unlinked and destroyed
       typedef detail::init_disposer<node_algorithms> NodeDisposer;
       NodeDisposer node_disp;
       detail::exception_array_disposer<bucket_type, NodeDisposer>
@@ -1733,12 +1929,13 @@
             siterator i(old_bucket.begin());
             for(;i != end; ++i){
                const value_type &v = priv_value_from_slist_node(i.pointed_node());
- const std::size_t hash_value = this->priv_stored_hash(v, store_hash_t());
- const size_type new_n = priv_hash_to_bucket(hash_value, new_buckets_len);
+ const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
+ const size_type new_n = priv_hash_to_bucket(hash_value, new_buckets_len, new_buckets_len);
                if(cache_begin && new_n < new_first_bucket_num)
                   new_first_bucket_num = new_n;
                siterator last = bucket_type::s_iterator_to
- (*priv_get_last_in_group(dcast_bucket_ptr(i.pointed_node())));
+ (*group_functions_t::priv_get_last_in_group
+ (dcast_bucket_ptr(i.pointed_node()), optimize_multikey_t()));
                if(same_buffer && new_n == n){
                   before_i = last;
                }
@@ -1750,7 +1947,7 @@
             }
          }
          else{
- const size_type new_n = priv_hash_to_bucket(n, new_buckets_len);
+ const size_type new_n = priv_hash_to_bucket(n, new_buckets_len, new_buckets_len);
             if(cache_begin && new_n < new_first_bucket_num)
                new_first_bucket_num = new_n;
             bucket_type &new_b = new_buckets[new_n];
@@ -1764,14 +1961,148 @@
       }
 
       this->priv_size_traits().set_size(size_backup);
+ this->priv_split_traits().set_size(new_buckets_len);
       this->priv_real_bucket_traits() = new_bucket_traits;
       priv_initialize_cache();
       priv_insertion_update_cache(new_first_bucket_num);
- //priv_erasure_update_cache();
       rollback1.release();
       rollback2.release();
    }
 
+ //! <b>Requires</b>:
+ //!
+ //! <b>Effects</b>:
+ //!
+ //! <b>Complexity</b>:
+ //!
+ //! <b>Throws</b>:
+ //!
+ //! <b>Note</b>: this method is only available if incremental<true> option is activated.
+ bool incremental_rehash(bool grow = true)
+ {
+ //This function is only available for containers with incremental hashing
+ BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
+ size_type split_idx = priv_split_traits().get_size();
+ size_type bucket_len = priv_buckets_len();
+
+ if(grow){
+ //Test if the split variable can be changed
+ if(split_idx >= bucket_len)
+ return false;
+
+ size_type bucket_len = priv_buckets_len();
+ size_type bucket_to_rehash = split_idx - bucket_len/2;
+ bucket_type &old_bucket = this->priv_buckets()[bucket_to_rehash];
+ siterator before_i(old_bucket.before_begin());
+ siterator end(old_bucket.end());
+ siterator i(old_bucket.begin());
+ priv_split_traits().increment();
+
+ //Anti-exception stuff: if an exception is thrown while
+ //moving elements from old_bucket to the target bucket, all moved
+ //elements are moved back to the original one.
+ detail::incremental_rehash_rollback<bucket_type, split_traits> rollback
+ ( this->priv_buckets()[split_idx], old_bucket, priv_split_traits());
+ for(;i != end; ++i){
+ const value_type &v = priv_value_from_slist_node(i.pointed_node());
+ const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
+ const size_type new_n = priv_hash_to_bucket(hash_value);
+ siterator last = bucket_type::s_iterator_to
+ (*group_functions_t::priv_get_last_in_group
+ (dcast_bucket_ptr(i.pointed_node()), optimize_multikey_t()));
+ if(new_n == bucket_to_rehash){
+ before_i = last;
+ }
+ else{
+ bucket_type &new_b = this->priv_buckets()[new_n];
+ new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
+ }
+ i = before_i;
+ }
+ rollback.release();
+ priv_erasure_update_cache();
+ return true;
+ }
+ else{
+ //Test if the split variable can be changed
+ if(split_idx <= bucket_len/2)
+ return false;
+ const size_type target_bucket_num = split_idx - 1 - bucket_len/2;
+ bucket_type &target_bucket = this->priv_buckets()[target_bucket_num];
+ bucket_type &source_bucket = this->priv_buckets()[split_idx-1];
+ target_bucket.splice_after(target_bucket.cbefore_begin(), source_bucket);
+ priv_split_traits().decrement();
+ priv_insertion_update_cache(target_bucket_num);
+ return true;
+ }
+ }
+
+ //! <b>Effects</b>: If new_bucket_traits.bucket_count() is not
+ //! this->bucket_count()/2 or this->bucket_count()*2, or
+ //! this->split_bucket() != new_bucket_traits.bucket_count() returns false
+ //! and does nothing.
+ //!
+ //! Otherwise, copy assigns new_bucket_traits to the internal bucket_traits
+ //! and transfers all the objects from old buckets to the new ones.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Note</b>: this method is only available if incremental<true> option is activated.
+ bool incremental_rehash(const bucket_traits &new_bucket_traits)
+ {
+ //This function is only available for containers with incremental hashing
+ BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
+ size_type new_bucket_traits_size = new_bucket_traits.bucket_count();
+ size_type cur_bucket_traits = this->priv_buckets_len();
+ if(new_bucket_traits_size/2 != cur_bucket_traits && new_bucket_traits_size != cur_bucket_traits/2){
+ return false;
+ }
+
+ const size_type split_idx = this->split_count();
+
+ if(new_bucket_traits_size/2 == cur_bucket_traits){
+ //Test if the split variable can be changed
+ if(!(split_idx >= cur_bucket_traits))
+ return false;
+ }
+ else{
+ //Test if the split variable can be changed
+ if(!(split_idx <= cur_bucket_traits/2))
+ return false;
+ }
+
+ const size_type ini_n = priv_get_cache_bucket_num();
+ const bucket_ptr old_buckets = this->priv_buckets();
+ this->priv_real_bucket_traits() = new_bucket_traits;
+ if(new_bucket_traits.bucket_begin() != old_buckets){
+ for(size_type n = ini_n; n < split_idx; ++n){
+ bucket_type &new_bucket = new_bucket_traits.bucket_begin()[n];
+ bucket_type &old_bucket = old_buckets[n];
+ new_bucket.splice_after(new_bucket.cbefore_begin(), old_bucket);
+ }
+ //Put cache to safe position
+ priv_initialize_cache();
+ priv_insertion_update_cache(ini_n);
+ }
+ return true;
+ }
+
+ //! <b>Requires</b>:
+ //!
+ //! <b>Effects</b>:
+ //!
+ //! <b>Complexity</b>:
+ //!
+ //! <b>Throws</b>:
+ size_type split_count() const
+ {
+ //This function is only available if incremental hashing is activated
+ BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
+ return this->priv_split_traits().get_size();
+ }
+
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
    //! the container that is bigger than n. This suggestion can be used
    //! to create bucket arrays with a size that will usually improve
@@ -1812,29 +2143,30 @@
 
    /// @cond
    private:
- std::size_t priv_hash_to_bucket(std::size_t hash_value) const
- { return priv_hash_to_bucket(hash_value, power_2_buckets_t()); }
-
- std::size_t priv_hash_to_bucket(std::size_t hash_value, detail::bool_<false>) const
- { return hash_value % this->priv_real_bucket_traits().bucket_count(); }
 
- std::size_t priv_hash_to_bucket(std::size_t hash_value, detail::bool_<true>) const
- { return hash_value & (this->priv_real_bucket_traits().bucket_count() - 1); }
+ std::size_t priv_hash_to_bucket(std::size_t hash_value) const
+ { return priv_hash_to_bucket(hash_value, this->priv_real_bucket_traits().bucket_count(), priv_split_traits().get_size()); }
 
- std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len) const
- { return priv_hash_to_bucket(hash_value, bucket_len, power_2_buckets_t()); }
+ std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len, std::size_t split) const
+ {
+ std::size_t bucket_number = priv_hash_to_bucket_impl(hash_value, bucket_len, power_2_buckets_t());
+ if(incremental)
+ if(bucket_number >= split)
+ bucket_number -= bucket_len/2;
+ return bucket_number;
+ }
 
- std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len, detail::bool_<false>) const
+ std::size_t priv_hash_to_bucket_impl(std::size_t hash_value, std::size_t bucket_len, detail::bool_<false>) const
    { return hash_value % bucket_len; }
 
- std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len, detail::bool_<true>) const
+ std::size_t priv_hash_to_bucket_impl(std::size_t hash_value, std::size_t bucket_len, detail::bool_<true>) const
    { return hash_value & (bucket_len - 1); }
 
    const key_equal &priv_equal() const
- { return static_cast<const key_equal&>(this->bucket_hash_equal_.get()); }
+ { return static_cast<const key_equal&>(this->data_.internal_.bucket_hash_equal_.get()); }
 
    key_equal &priv_equal()
- { return static_cast<key_equal&>(this->bucket_hash_equal_.get()); }
+ { return static_cast<key_equal&>(this->data_.internal_.bucket_hash_equal_.get()); }
 
    value_type &priv_value_from_slist_node(slist_node_ptr n)
    { return *this->get_real_value_traits().to_value_ptr(dcast_bucket_ptr(n)); }
@@ -1843,16 +2175,16 @@
    { return *this->get_real_value_traits().to_value_ptr(dcast_bucket_ptr(n)); }
 
    const real_bucket_traits &priv_real_bucket_traits(detail::bool_<false>) const
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
+ { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
 
    const real_bucket_traits &priv_real_bucket_traits(detail::bool_<true>) const
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
+ { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
 
    real_bucket_traits &priv_real_bucket_traits(detail::bool_<false>)
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
+ { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
 
    real_bucket_traits &priv_real_bucket_traits(detail::bool_<true>)
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
+ { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
 
    const real_bucket_traits &priv_real_bucket_traits() const
    { return this->priv_real_bucket_traits(detail::bool_<external_bucket_traits>()); }
@@ -1861,10 +2193,10 @@
    { return this->priv_real_bucket_traits(detail::bool_<external_bucket_traits>()); }
 
    const hasher &priv_hasher() const
- { return static_cast<const hasher&>(this->bucket_hash_equal_.bucket_hash.get()); }
+ { return static_cast<const hasher&>(this->data_.internal_.bucket_hash_equal_.bucket_hash.get()); }
 
    hasher &priv_hasher()
- { return static_cast<hasher&>(this->bucket_hash_equal_.bucket_hash.get()); }
+ { return static_cast<hasher&>(this->data_.internal_.bucket_hash_equal_.bucket_hash.get()); }
 
    bucket_ptr priv_buckets() const
    { return this->priv_real_bucket_traits().bucket_begin(); }
@@ -1882,10 +2214,16 @@
    { return *this->get_real_value_traits().to_node_ptr(v); }
 
    size_traits &priv_size_traits()
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
+ { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
 
    const size_traits &priv_size_traits() const
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
+ { return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
+
+ split_traits &priv_split_traits()
+ { return this->data_.internal_; }
+
+ const split_traits &priv_split_traits() const
+ { return this->data_.internal_; }
 
    template<class Disposer>
    void priv_erase_range_impl
@@ -1903,7 +2241,7 @@
          ++to_erase;
          slist_node_ptr end_ptr = end.pointed_node();
          while(to_erase != end){
- priv_erase_from_group(end_ptr, dcast_bucket_ptr(to_erase.pointed_node()), optimize_multikey_t());
+ group_functions_t::priv_erase_from_group(end_ptr, dcast_bucket_ptr(to_erase.pointed_node()), optimize_multikey_t());
             to_erase = b.erase_after_and_dispose(before_first_it, make_node_disposer(disposer));
             ++num_erased;
          }
@@ -1955,10 +2293,10 @@
    static node_ptr dcast_bucket_ptr(typename slist_impl::node_ptr p)
    { return node_ptr(&static_cast<node&>(*p)); }
 
- std::size_t priv_stored_hash(const value_type &v, detail::true_) const
+ std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const
    { return node_traits::get_hash(this->get_real_value_traits().to_node_ptr(v)); }
 
- std::size_t priv_stored_hash(const value_type &v, detail::false_) const
+ std::size_t priv_stored_or_compute_hash(const value_type &v, detail::false_) const
    { return priv_hasher()(v); }
 
    std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) const
@@ -2002,10 +2340,10 @@
    std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_)
    { return priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
 
- std::size_t priv_get_bucket_num_no_hash_store( siterator it, detail::true_)
+ std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::true_)
    {
       bucket_ptr f(priv_buckets()), l(f + priv_buckets_len() - 1);
- slist_node_ptr bb = priv_get_bucket_before_begin
+ slist_node_ptr bb = group_functions_t::priv_get_bucket_before_begin
          ( f->end().pointed_node()
          , l->end().pointed_node()
          , dcast_bucket_ptr(it.pointed_node()));
@@ -2016,7 +2354,7 @@
       return static_cast<size_type>(&b - &*f);
    }
 
- std::size_t priv_get_bucket_num_no_hash_store( siterator it, detail::false_)
+ std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::false_)
    {
       bucket_ptr f(priv_buckets()), l(f + priv_buckets_len() - 1);
       slist_node_ptr first_ptr(f->cend().pointed_node())
@@ -2035,34 +2373,6 @@
       return static_cast<std::size_t>(&b - &*f);
    }
 
- void priv_erase_from_group(slist_node_ptr end_ptr, node_ptr to_erase_ptr, detail::true_)
- {
- node_ptr nxt_ptr(node_traits::get_next(to_erase_ptr));
- node_ptr prev_in_group_ptr(group_traits::get_next(to_erase_ptr));
- bool last_in_group = (end_ptr == nxt_ptr) ||
- (group_traits::get_next(nxt_ptr) != to_erase_ptr);
- bool first_in_group = node_traits::get_next(prev_in_group_ptr) != to_erase_ptr;
-
- if(first_in_group && last_in_group){
- group_algorithms::init(to_erase_ptr);
- }
- else if(first_in_group){
- group_algorithms::unlink_after(nxt_ptr);
- }
- else if(last_in_group){
- node_ptr first_in_group = //possible_first_in_group ? possible_first_in_group :
- priv_get_first_in_group_of_last_in_group(to_erase_ptr);
- group_algorithms::unlink_after(first_in_group);
- //possible_first_in_group = 0;
- }
- else{
- group_algorithms::unlink_after(nxt_ptr);
- }
- }
-
- void priv_erase_from_group(slist_node_ptr, node_ptr, detail::false_)
- {}
-
    void priv_init_group(slist_node_ptr n, detail::true_)
    { group_algorithms::init(dcast_bucket_ptr(n)); }
 
@@ -2083,79 +2393,9 @@
       }
    }
 
- static slist_node_ptr priv_get_bucket_before_begin
- (slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p)
- {
- //First find the last node of p's group.
- //This requires checking the first node of the next group or
- //the bucket node.
- node_ptr prev_node = p;
- node_ptr nxt(node_traits::get_next(p));
- while(!(bucket_beg <= nxt && nxt <= bucket_end) &&
- (group_traits::get_next(nxt) == prev_node)){
- prev_node = nxt;
- nxt = node_traits::get_next(nxt);
- }
-
- //If we've reached the bucket node just return it.
- if(bucket_beg <= nxt && nxt <= bucket_end){
- return nxt;
- }
-
- //Otherwise, iterate using group links until the bucket node
- node_ptr first_node_of_group = nxt;
- node_ptr last_node_group = group_traits::get_next(first_node_of_group);
- slist_node_ptr possible_end = node_traits::get_next(last_node_group);
-
- while(!(bucket_beg <= possible_end && possible_end <= bucket_end)){
- first_node_of_group = dcast_bucket_ptr(possible_end);
- last_node_group = group_traits::get_next(first_node_of_group);
- possible_end = node_traits::get_next(last_node_group);
- }
- return possible_end;
- }
-
- static node_ptr priv_get_prev_to_first_in_group(slist_node_ptr bucket_node, node_ptr first_in_group)
- {
- //Just iterate using group links and obtain the node
- //before "first_in_group)"
- node_ptr prev_node = dcast_bucket_ptr(bucket_node);
- node_ptr nxt(node_traits::get_next(prev_node));
- while(nxt != first_in_group){
- prev_node = group_traits::get_next(nxt);
- nxt = node_traits::get_next(prev_node);
- }
- return prev_node;
- }
-
- static node_ptr priv_get_first_in_group_of_last_in_group(node_ptr last_in_group)
- {
- //Just iterate using group links and obtain the node
- //before "last_in_group"
- node_ptr possible_first = group_traits::get_next(last_in_group);
- node_ptr possible_first_prev = group_traits::get_next(possible_first);
- // The deleted node is at the end of the group, so the
- // node in the group pointing to it is at the beginning
- // of the group. Find that to change its pointer.
- while(possible_first_prev != last_in_group){
- possible_first = possible_first_prev;
- possible_first_prev = group_traits::get_next(possible_first);
- }
- return possible_first;
- }
-
    void priv_insert_in_group(node_ptr, node_ptr, detail::false_)
    {}
 
- static node_ptr priv_get_last_in_group(node_ptr first_in_group)
- { return priv_get_last_in_group(first_in_group, optimize_multikey_t()); }
-
- static node_ptr priv_get_last_in_group(node_ptr first_in_group, detail::true_)
- { return group_traits::get_next(first_in_group); }
-
- static node_ptr priv_get_last_in_group(node_ptr n, detail::false_)
- { return n; }
-
    siterator priv_get_previous
       (bucket_type &b, siterator i)
    { return priv_get_previous(b, i, optimize_multikey_t()); }
@@ -2166,9 +2406,8 @@
       node_ptr elem(dcast_bucket_ptr(i.pointed_node()));
       node_ptr prev_in_group(group_traits::get_next(elem));
       bool first_in_group = node_traits::get_next(prev_in_group) != elem;
-
       typename bucket_type::node &n = first_in_group
- ? *priv_get_prev_to_first_in_group(b.end().pointed_node(), elem)
+ ? *group_functions_t::priv_get_prev_to_first_in_group(b.end().pointed_node(), elem)
          : *group_traits::get_next(elem)
          ;
       return bucket_type::s_iterator_to(n);
@@ -2234,15 +2473,15 @@
                ].before_begin().pointed_node();
          }
          else{
- bucket_node = priv_get_bucket_before_begin
+ bucket_node = group_functions_t::priv_get_bucket_before_begin
                   (first_end_ptr, last_end_ptr, start_pos);
          }
          prev = bucket_type::s_iterator_to
- (*priv_get_prev_to_first_in_group(bucket_node, elem));
+ (*group_functions_t::priv_get_prev_to_first_in_group(bucket_node, elem));
       }
       else{
          if(last_in_group){
- nxt_in_group = priv_get_first_in_group_of_last_in_group(elem);
+ nxt_in_group = group_functions_t::priv_get_first_in_group_of_last_in_group(elem);
          }
          else{
             nxt_in_group = node_traits::get_next(elem);
@@ -2283,32 +2522,29 @@
    siterator priv_invalid_local_it() const
    { return priv_invalid_bucket()->end(); }
 
- siterator priv_begin(size_type &bucket_num) const
- { return priv_begin(bucket_num, cache_begin_t()); }
+ siterator priv_begin() const
+ { return priv_begin(cache_begin_t()); }
 
- siterator priv_begin(size_type &bucket_num, detail::bool_<false>) const
+ siterator priv_begin(detail::bool_<false>) const
    {
       size_type n = 0;
       size_type buckets_len = this->priv_buckets_len();
       for (n = 0; n < buckets_len; ++n){
          bucket_type &b = this->priv_buckets()[n];
          if(!b.empty()){
- bucket_num = n;
             return b.begin();
          }
       }
- bucket_num = n;
       return priv_invalid_local_it();
    }
 
- siterator priv_begin(size_type &bucket_num, detail::bool_<true>) const
+ siterator priv_begin(detail::bool_<true>) const
    {
- bucket_num = this->bucket_hash_equal_.cached_begin_ - this->priv_buckets();
- if(this->bucket_hash_equal_.cached_begin_ == priv_invalid_bucket()){
+ if(this->data_.internal_.bucket_hash_equal_.cached_begin_ == priv_invalid_bucket()){
          return priv_invalid_local_it();
       }
       else{
- return this->bucket_hash_equal_.cached_begin_->begin();
+ return this->data_.internal_.bucket_hash_equal_.cached_begin_->begin();
       }
    }
 
@@ -2316,7 +2552,7 @@
    { priv_initialize_cache(cache_begin_t()); }
 
    void priv_initialize_cache(detail::bool_<true>)
- { this->bucket_hash_equal_.cached_begin_ = priv_invalid_bucket(); }
+ { this->data_.internal_.bucket_hash_equal_.cached_begin_ = priv_invalid_bucket(); }
 
    void priv_initialize_cache(detail::bool_<false>)
    {}
@@ -2327,8 +2563,8 @@
    void priv_insertion_update_cache(size_type insertion_bucket, detail::bool_<true>)
    {
       bucket_ptr p = priv_buckets() + insertion_bucket;
- if(p < this->bucket_hash_equal_.cached_begin_){
- this->bucket_hash_equal_.cached_begin_ = p;
+ if(p < this->data_.internal_.bucket_hash_equal_.cached_begin_){
+ this->data_.internal_.bucket_hash_equal_.cached_begin_ = p;
       }
    }
 
@@ -2361,11 +2597,11 @@
          priv_initialize_cache();
       }
       else{
- size_type current_n = this->bucket_hash_equal_.cached_begin_ - priv_buckets();
+ size_type current_n = this->data_.internal_.bucket_hash_equal_.cached_begin_ - priv_buckets();
          for( const size_type num_buckets = this->priv_buckets_len()
             ; current_n < num_buckets
- ; ++current_n, ++this->bucket_hash_equal_.cached_begin_){
- if(!this->bucket_hash_equal_.cached_begin_->empty()){
+ ; ++current_n, ++this->data_.internal_.bucket_hash_equal_.cached_begin_){
+ if(!this->data_.internal_.bucket_hash_equal_.cached_begin_->empty()){
                return;
             }
          }
@@ -2378,8 +2614,8 @@
 
    void priv_swap_cache(detail::bool_<true>, hashtable_impl &other)
    {
- std::swap( this->bucket_hash_equal_.cached_begin_
- , other.bucket_hash_equal_.cached_begin_);
+ std::swap( this->data_.internal_.bucket_hash_equal_.cached_begin_
+ , other.data_.internal_.bucket_hash_equal_.cached_begin_);
    }
 
    void priv_swap_cache(detail::bool_<false>, hashtable_impl &)
@@ -2389,7 +2625,7 @@
    { return priv_get_cache(cache_begin_t()); }
 
    bucket_ptr priv_get_cache(detail::bool_<true>)
- { return this->bucket_hash_equal_.cached_begin_; }
+ { return this->data_.internal_.bucket_hash_equal_.cached_begin_; }
 
    bucket_ptr priv_get_cache(detail::bool_<false>)
    { return this->priv_buckets(); }
@@ -2398,7 +2634,7 @@
    { priv_set_cache(p, cache_begin_t()); }
 
    void priv_set_cache(bucket_ptr p, detail::bool_<true>)
- { this->bucket_hash_equal_.cached_begin_ = p; }
+ { this->data_.internal_.bucket_hash_equal_.cached_begin_ = p; }
 
    void priv_set_cache(bucket_ptr, detail::bool_<false>)
    {}
@@ -2407,7 +2643,7 @@
    { return priv_get_cache_bucket_num(cache_begin_t()); }
 
    size_type priv_get_cache_bucket_num(detail::bool_<true>)
- { return this->bucket_hash_equal_.cached_begin_ - this->priv_buckets(); }
+ { return this->data_.internal_.bucket_hash_equal_.cached_begin_ - this->priv_buckets(); }
 
    size_type priv_get_cache_bucket_num(detail::bool_<false>)
    { return 0u; }
@@ -2420,10 +2656,7 @@
    }
 
    void priv_initialize_buckets()
- {
- this->priv_clear_buckets
- ( priv_buckets(), this->priv_buckets_len());
- }
+ { this->priv_clear_buckets(priv_buckets(), this->priv_buckets_len()); }
 
    void priv_clear_buckets(bucket_ptr buckets_ptr, size_type buckets_len)
    {
@@ -2444,21 +2677,28 @@
       ( const KeyType &key, KeyHasher hash_func
       , KeyValueEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
    {
- bucket_number = priv_hash_to_bucket((h = hash_func(key)));
+ h = hash_func(key);
+ return priv_find_with_hash(key, equal_func, bucket_number, h, previt);
+ }
 
+ template<class KeyType, class KeyValueEqual>
+ siterator priv_find_with_hash
+ ( const KeyType &key, KeyValueEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const
+ {
+ bucket_number = priv_hash_to_bucket(h);
+ bucket_type &b = this->priv_buckets()[bucket_number];
+ previt = b.before_begin();
       if(constant_time_size && this->empty()){
          return priv_invalid_local_it();
       }
       
- bucket_type &b = this->priv_buckets()[bucket_number];
- previt = b.before_begin();
       siterator it = previt;
       ++it;
 
       while(it != b.end()){
          const value_type &v = priv_value_from_slist_node(it.pointed_node());
          if(compare_hash){
- std::size_t vh = this->priv_stored_hash(v, store_hash_t());
+ std::size_t vh = this->priv_stored_or_compute_hash(v, store_hash_t());
             if(h == vh && equal_func(key, v)){
                return it;
             }
@@ -2468,7 +2708,8 @@
          }
          if(optimize_multikey){
             previt = bucket_type::s_iterator_to
- (*priv_get_last_in_group(dcast_bucket_ptr(it.pointed_node())));
+ (*group_functions_t::priv_get_last_in_group
+ (dcast_bucket_ptr(it.pointed_node()), optimize_multikey_t()));
             it = previt;
          }
          else{
@@ -2476,10 +2717,45 @@
          }
          ++it;
       }
-
+ previt = b.before_begin();
       return priv_invalid_local_it();
    }
 
+ iterator priv_insert_equal_with_hash(reference value, std::size_t hash_value)
+ {
+ size_type bucket_num;
+ siterator prev;
+ siterator it = this->priv_find_with_hash
+ (value, this->priv_equal(), bucket_num, hash_value, prev);
+ return priv_insert_equal_find(value, bucket_num, hash_value, it);
+ }
+
+ iterator priv_insert_equal_find(reference value, size_type bucket_num, std::size_t hash_value, siterator it)
+ {
+ bucket_type &b = this->priv_buckets()[bucket_num];
+ bool found_equal = it != priv_invalid_local_it();
+ if(!found_equal){
+ it = b.before_begin();
+ }
+ //Now store hash if needed
+ node_ptr n = node_ptr(&priv_value_to_node(value));
+ this->priv_store_hash(n, hash_value, store_hash_t());
+ //Checks for some modes
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+ //Shorcut for optimize_multikey cases
+ if(optimize_multikey){
+ node_ptr first_in_group = found_equal ?
+ dcast_bucket_ptr(it.pointed_node()) : node_ptr(0);
+ this->priv_insert_in_group(first_in_group, n, optimize_multikey_t());
+ }
+ //Update cache and increment size if needed
+ priv_insertion_update_cache(bucket_num);
+ this->priv_size_traits().increment();
+ //Insert the element in the bucket after it
+ return iterator(b.insert_after(it, *n), this);
+ }
+
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    std::pair<siterator, siterator> priv_equal_range
       ( const KeyType &key
@@ -2506,8 +2782,8 @@
       siterator it = to_return.first;
       if(optimize_multikey){
          to_return.second = bucket_type::s_iterator_to
- (*node_traits::get_next(priv_get_last_in_group
- (dcast_bucket_ptr(it.pointed_node()))));
+ (*node_traits::get_next(group_functions_t::priv_get_last_in_group
+ (dcast_bucket_ptr(it.pointed_node()), optimize_multikey_t())));
          count = std::distance(it, to_return.second);
          if(to_return.second != b.end()){
             bucket_number_second = bucket_number_first;
@@ -2520,7 +2796,7 @@
          while(it != b.end()){
             const value_type &v = priv_value_from_slist_node(it.pointed_node());
             if(compare_hash){
- std::size_t hv = this->priv_stored_hash(v, store_hash_t());
+ std::size_t hv = this->priv_stored_or_compute_hash(v, store_hash_t());
                if(hv != h || !equal_func(key, v)){
                   to_return.second = it;
                   bucket_number_second = bucket_number_first;
@@ -2556,18 +2832,28 @@
 };
 
 /// @cond
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template < class T
          , bool UniqueKeys
          , class O1 = none, class O2 = none
          , class O3 = none, class O4 = none
          , class O5 = none, class O6 = none
          , class O7 = none, class O8 = none
- , class O9 = none
+ , class O9 = none, class O10= none
>
+#else
+template <class T, bool UniqueKeys, class ...Options>
+#endif
 struct make_hashtable_opt
 {
    typedef typename pack_options
- < uset_defaults<T>, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type packed_options;
+ < uset_defaults<T>,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    //Real value traits must be calculated from options
    typedef typename detail::get_value_traits
@@ -2598,31 +2884,32 @@
                   , specified_bucket_traits
>::type real_bucket_traits;
 
- typedef usetopt
+ typedef detail::usetopt
       < value_traits
- , UniqueKeys
       , typename packed_options::hash
       , typename packed_options::equal
       , typename packed_options::size_type
- , packed_options::constant_time_size
       , real_bucket_traits
- , packed_options::power_2_buckets
- , packed_options::cache_begin
- , packed_options::compare_hash
+ , (std::size_t(UniqueKeys)*detail::hash_bool_flags::unique_keys_pos)
+ | (std::size_t(packed_options::constant_time_size)*detail::hash_bool_flags::constant_time_size_pos)
+ | (std::size_t(packed_options::power_2_buckets)*detail::hash_bool_flags::power_2_buckets_pos)
+ | (std::size_t(packed_options::cache_begin)*detail::hash_bool_flags::cache_begin_pos)
+ | (std::size_t(packed_options::compare_hash)*detail::hash_bool_flags::compare_hash_pos)
+ | (std::size_t(packed_options::incremental)*detail::hash_bool_flags::incremental_pos)
> type;
 };
 /// @endcond
 
 //! Helper metafunction to define a \c hashtable that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
                 , class O7 = none, class O8 = none
- , class O9 = none
+ , class O9 = none, class O10= none
>
 #endif
 struct make_hashtable
@@ -2630,20 +2917,42 @@
    /// @cond
    typedef hashtable_impl
       < typename make_hashtable_opt
- <T, false, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
+ <T, false,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
 
    /// @endcond
    typedef implementation_defined type;
 };
 
-#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9>
+#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
+#if defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class ...Options>
+#else
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
+#endif
 class hashtable
- : public make_hashtable<T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
-{
- typedef typename make_hashtable
- <T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type Base;
+ : public make_hashtable<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type
+{
+ typedef typename make_hashtable<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_traits value_traits;
@@ -2669,7 +2978,6 @@
 
 #endif
 
-
 } //namespace intrusive
 } //namespace boost
 

Modified: branches/release/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- branches/release/boost/intrusive/intrusive_fwd.hpp (original)
+++ branches/release/boost/intrusive/intrusive_fwd.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -15,26 +15,12 @@
 
 #include <cstddef>
 #include <boost/intrusive/link_mode.hpp>
+#include <boost/intrusive/detail/workaround.hpp>
 
 /// @cond
 
-//std predeclarations
-namespace std{
-
-template<class T>
-struct equal_to;
-
-template<class T>
-struct less;
-
-} //namespace std{
-
 namespace boost {
 
-//Hash predeclaration
-template<class T>
-struct hash;
-
 namespace intrusive {
 
 struct none;
@@ -64,6 +50,7 @@
 ////////////////////////////
 
 //slist
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -72,46 +59,70 @@
    , class O4 = none
    , class O5 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class slist;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class slist_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class slist_member_hook;
 
 //list
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class list;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class list_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class list_member_hook;
 
 //rbtree/set/multiset
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -119,8 +130,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class rbtree;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -128,8 +143,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class set;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -137,25 +156,37 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class multiset;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
    , class O4 = none
>
+#else
+template<class ...Options>
+#endif
 class set_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
    , class O4 = none
>
+#else
+template<class ...Options>
+#endif
 class set_member_hook;
 
 //splaytree/splay_set/splay_multiset
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -163,8 +194,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class splaytree;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -172,8 +207,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class splay_set;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -181,23 +220,35 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class splay_multiset;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class splay_set_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class splay_set_member_hook;
 
 //avltree/avl_set/avl_multiset
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -205,8 +256,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class avltree;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -214,8 +269,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class avl_set;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -223,25 +282,37 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class avl_multiset;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
    , class O4 = none
>
+#else
+template<class ...Options>
+#endif
 class avl_set_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
    , class O4 = none
>
+#else
+template<class ...Options>
+#endif
 class avl_set_member_hook;
 
 //sgtree/sg_set/sg_multiset
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -249,8 +320,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class sgtree;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -258,8 +333,12 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class sg_set;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -267,23 +346,36 @@
    , class O3 = none
    , class O4 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class sg_multiset;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class bs_set_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class bs_set_member_hook;
 
 //hashtable/unordered_set/unordered_multiset
+
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -295,9 +387,14 @@
    , class O7 = none
    , class O8 = none
    , class O9 = none
+ , class O10 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class hashtable;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -309,9 +406,14 @@
    , class O7 = none
    , class O8 = none
    , class O9 = none
+ , class O10 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class unordered_set;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class T
    , class O1 = none
@@ -323,37 +425,57 @@
    , class O7 = none
    , class O8 = none
    , class O9 = none
+ , class O10 = none
>
+#else
+template<class T, class ...Options>
+#endif
 class unordered_multiset;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
    , class O4 = none
>
+#else
+template<class ...Options>
+#endif
 class unordered_set_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
    , class O4 = none
>
+#else
+template<class ...Options>
+#endif
 class unordered_set_member_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class any_base_hook;
 
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template
    < class O1 = none
    , class O2 = none
    , class O3 = none
>
+#else
+template<class ...Options>
+#endif
 class any_member_hook;
 
 } //namespace intrusive {

Modified: branches/release/boost/intrusive/linear_slist_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/linear_slist_algorithms.hpp (original)
+++ branches/release/boost/intrusive/linear_slist_algorithms.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -58,7 +58,7 @@
    typedef typename NodeTraits::const_node_ptr const_node_ptr;
    typedef NodeTraits node_traits;
 
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Constructs an non-used list element, putting the next
    //! pointer to null:
@@ -127,7 +127,7 @@
    //! <b>Throws</b>: Nothing.
    static void transfer_after(node_ptr p, node_ptr b, node_ptr e);
 
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 
    //! <b>Effects</b>: Constructs an empty list, making this_node the only
    //! node of the circular list:

Modified: branches/release/boost/intrusive/list.hpp
==============================================================================
--- branches/release/boost/intrusive/list.hpp (original)
+++ branches/release/boost/intrusive/list.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -35,20 +35,6 @@
 
 /// @cond
 
-template <class T>
-struct internal_default_list_hook
-{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_list_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
-};
-
-template <class T>
-struct get_default_list_hook
-{
- typedef typename T::default_list_hook type;
-};
-
 template <class ValueTraits, class SizeType, bool ConstantTimeSize>
 struct listopt
 {
@@ -57,17 +43,12 @@
    static const bool constant_time_size = ConstantTimeSize;
 };
 
+
 template <class T>
 struct list_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < internal_default_list_hook<T>::value
- , get_default_list_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_list_hook>
       , constant_time_size<true>
       , size_type<std::size_t>
>::type
@@ -85,7 +66,7 @@
 //! The container supports the following options:
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<> and \c size_type<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -225,7 +206,7 @@
    {
       this->priv_size_traits().set_size(size_type(0));
       node_algorithms::init_header(this->get_root_node());
- this->insert(this->end(), b, e);
+ this->insert(this->cend(), b, e);
    }
 
    //! <b>Effects</b>: If it's not a safe-mode or an auto-unlink value_type
@@ -583,7 +564,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return this->erase_and_dispose(i, detail::null_disposer()); }
 
    //! <b>Requires</b>: b and e must be valid iterators to elements in *this.
@@ -601,14 +582,14 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased elements.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    {
       if(safemode_or_autounlink || constant_time_size){
          return this->erase_and_dispose(b, e, detail::null_disposer());
       }
       else{
          node_algorithms::unlink(b.pointed_node(), e.pointed_node());
- return e;
+ return e.unconst();
       }
    }
 
@@ -628,7 +609,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased elements.
- iterator erase(iterator b, iterator e, difference_type n)
+ iterator erase(const_iterator b, const_iterator e, difference_type n)
    {
       BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(b, e) == difference_type(n));
       if(safemode_or_autounlink || constant_time_size){
@@ -639,7 +620,7 @@
             this->priv_size_traits().set_size(this->priv_size_traits().get_size() - n);
          }
          node_algorithms::unlink(b.pointed_node(), e.pointed_node());
- return e;
+ return e.unconst();
       }
    }
 
@@ -658,7 +639,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators to the erased element.
    template <class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    {
       node_ptr to_erase(i.pointed_node());
       ++i;
@@ -667,7 +648,7 @@
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
       disposer(this->get_real_value_traits().to_value_ptr(to_erase));
- return i;
+ return i.unconst();
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -685,7 +666,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators to the erased elements.
    template <class Disposer>
- iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
+ iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
    {
       node_ptr bp(b.pointed_node()), ep(e.pointed_node());
       node_algorithms::unlink(bp, ep);
@@ -697,7 +678,7 @@
          disposer(get_real_value_traits().to_value_ptr(to_erase));
          this->priv_size_traits().decrement();
       }
- return e;
+ return e.unconst();
    }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -734,7 +715,7 @@
    template <class Disposer>
    void clear_and_dispose(Disposer disposer)
    {
- iterator it(this->begin()), itend(this->end());
+ const_iterator it(this->begin()), itend(this->end());
       while(it != itend){
          node_ptr to_erase(it.pointed_node());
          ++it;
@@ -747,6 +728,7 @@
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
@@ -783,7 +765,7 @@
    //! <b>Complexity</b>: Constant time. No copy constructors are called.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
- iterator insert(iterator p, reference value)
+ iterator insert(const_iterator p, reference value)
    {
       node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
@@ -805,7 +787,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    template<class Iterator>
- void insert(iterator p, Iterator b, Iterator e)
+ void insert(const_iterator p, Iterator b, Iterator e)
    {
       for (; b != e; ++b)
          this->insert(p, *b);
@@ -830,7 +812,7 @@
    void assign(Iterator b, Iterator e)
    {
       this->clear();
- this->insert(this->end(), b, e);
+ this->insert(this->cend(), b, e);
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -853,7 +835,7 @@
    void dispose_and_assign(Disposer disposer, Iterator b, Iterator e)
    {
       this->clear_and_dispose(disposer);
- this->insert(this->end(), b, e);
+ this->insert(this->cend(), b, e);
    }
 
    //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -867,7 +849,7 @@
    //!
    //! <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 p, list_impl& x)
+ void splice(const_iterator p, list_impl& x)
    {
       if(!x.empty()){
          size_traits &thist = this->priv_size_traits();
@@ -892,7 +874,7 @@
    //!
    //! <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 p, list_impl&x, iterator new_ele)
+ void splice(const_iterator p, list_impl&x, const_iterator new_ele)
    {
       node_algorithms::transfer(p.pointed_node(), new_ele.pointed_node());
       x.priv_size_traits().decrement();
@@ -912,7 +894,7 @@
    //!
    //! <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 p, list_impl&x, iterator start, iterator end)
+ void splice(const_iterator p, list_impl&x, const_iterator start, const_iterator end)
    {
       if(constant_time_size)
          this->splice(p, x, start, end, std::distance(start, end));
@@ -933,7 +915,7 @@
    //!
    //! <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 p, list_impl&x, iterator start, iterator end, difference_type n)
+ void splice(const_iterator p, list_impl&x, const_iterator start, const_iterator end, difference_type n)
    {
       if(n){
          if(constant_time_size){
@@ -988,7 +970,7 @@
          list_impl counter[64];
          int fill = 0;
          while(!this->empty()){
- carry.splice(carry.begin(), *this, this->begin());
+ carry.splice(carry.cbegin(), *this, this->cbegin());
             int i = 0;
             while(i < fill && !counter[i].empty()) {
                carry.merge(counter[i++], p);
@@ -1034,13 +1016,13 @@
    template<class Predicate>
    void merge(list_impl& x, Predicate p)
    {
- iterator e(this->end());
- iterator bx(x.begin());
- iterator ex(x.end());
+ const_iterator e(this->end());
+ const_iterator bx(x.begin());
+ const_iterator ex(x.end());
 
- for (iterator b = this->begin(); b != e; ++b) {
+ for (const_iterator b = this->cbegin(); b != e; ++b) {
          size_type n(0);
- iterator ix(bx);
+ const_iterator ix(bx);
          while(ix != ex && p(*ix, *b)){
             ++ix; ++n;
          }
@@ -1116,8 +1098,8 @@
    template<class Pred, class Disposer>
    void remove_and_dispose_if(Pred pred, Disposer disposer)
    {
- iterator cur(this->begin());
- iterator last(this->end());
+ const_iterator cur(this->cbegin());
+ const_iterator last(this->cend());
       while(cur != last) {
          if(pred(*cur)){
             cur = this->erase_and_dispose(cur, disposer);
@@ -1185,11 +1167,11 @@
    template<class BinaryPredicate, class Disposer>
    void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
    {
- iterator itend(this->end());
- iterator cur(this->begin());
+ const_iterator itend(this->cend());
+ const_iterator cur(this->cbegin());
 
       if(cur != itend){
- iterator after(cur);
+ const_iterator after(cur);
          ++after;
          while(after != itend){
             if(pred(*cur, *after)){
@@ -1284,26 +1266,26 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
 (const list_impl<Config> &x, const list_impl<Config> &y)
 #endif
 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 bool operator==
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
 (const list_impl<Config> &x, const list_impl<Config> &y)
@@ -1336,65 +1318,65 @@
    }
 }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
 (const list_impl<Config> &x, const list_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
 (const list_impl<Config> &x, const list_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
 (const list_impl<Config> &x, const list_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
 #else
 (const list_impl<Config> &x, const list_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (list_impl<T, Options...> &x, list_impl<T, Options...> &y)
 #else
 (list_impl<Config> &x, list_impl<Config> &y)
@@ -1403,7 +1385,7 @@
 
 //! Helper metafunction to define a \c list that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none, class O3 = none>
@@ -1412,7 +1394,14 @@
 {
    /// @cond
    typedef typename pack_options
- < list_defaults<T>, O1, O2, O3>::type packed_options;
+ < list_defaults<T>,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
+
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
 
@@ -1430,12 +1419,29 @@
 
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3>
+#else
+template<class T, class ...Options>
+#endif
 class list
- : public make_list<T, O1, O2, O3>::type
+ : public make_list<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_list
- <T, O1, O2, O3>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::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/list_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/list_hook.hpp (original)
+++ branches/release/boost/intrusive/list_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -35,7 +35,7 @@
 
 //! Helper metafunction to define a \c \c list_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -44,7 +44,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_list_node_algo<typename packed_options::void_pointer>
@@ -72,15 +78,21 @@
 //!
 //! \c void_pointer<> is the pointer type that will be used internally in the hook
 //! and the the container configured to use this hook.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class list_base_hook
- : public make_list_base_hook<O1, O2, O3>::type
+ : public make_list_base_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -149,7 +161,7 @@
 
 //! Helper metafunction to define a \c \c list_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -158,7 +170,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_list_node_algo<typename packed_options::void_pointer>
@@ -181,15 +199,21 @@
 //!
 //! \c void_pointer<> is the pointer type that will be used internally in the hook
 //! and the the container configured to use this hook.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class list_member_hook
- : public make_list_member_hook<O1, O2, O3>::type
+ : public make_list_member_hook
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ <O1, O2, O3>
+ #else
+ <Options...>
+ #endif
+ ::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: branches/release/boost/intrusive/options.hpp
==============================================================================
--- branches/release/boost/intrusive/options.hpp (original)
+++ branches/release/boost/intrusive/options.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -31,6 +31,26 @@
 
 namespace detail{
 
+struct default_hook_tag{};
+
+#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
+struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
+{\
+ template <class T>\
+ struct apply\
+ { typedef typename T::BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER type; };\
+}\
+
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_list_hook);
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_slist_hook);
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_set_hook);
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_uset_hook);
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avl_set_hook);
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splay_set_hook);
+BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bs_set_hook);
+
+#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
+
 template <class ValueTraits>
 struct eval_value_traits
 {
@@ -116,8 +136,12 @@
 template<class T, class SupposedValueTraits>
 struct get_value_traits
 {
- typedef SupposedValueTraits supposed_value_traits;
- //...if it's a base hook
+ typedef typename detail::eval_if_c
+ <detail::is_convertible<SupposedValueTraits*, detail::default_hook_tag*>::value
+ ,detail::apply<SupposedValueTraits, T>
+ ,detail::identity<SupposedValueTraits>
+ >::type supposed_value_traits;
+ //...if it's a default hook
    typedef typename detail::eval_if_c
       < internal_base_hook_bool_is_true<supposed_value_traits>::value
       //...get it's internal value traits using
@@ -336,7 +360,7 @@
 };
 
 //!This option setter specifies the type of
-//!the tag of a base hook. A type can not have two
+//!the tag of a base hook. A type cannot have two
 //!base hooks of the same type, so a tag can be used
 //!to differentiate two base hooks with otherwise same type
 template<class Tag>
@@ -509,8 +533,29 @@
 /// @endcond
 };
 
+//!This option setter specifies if the hash container will use incremental
+//!hashing. With incremental hashing the cost of hash table expansion is spread
+//!out across each hash table insertion operation, as opposed to be incurred all at once.
+//!Therefore linear hashing is well suited for interactive applications or real-time
+//!appplications where the worst-case insertion time of non-incremental hash containers
+//!(rehashing the whole bucket array) is not admisible.
+template<bool Enabled>
+struct incremental
+{
+ /// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool incremental = Enabled;
+ };
+ /// @endcond
+};
+
 /// @cond
 
+//To-do: pass to variadic templates
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+
 template<class Prev, class Next>
 struct do_pack
 {
@@ -525,7 +570,6 @@
    typedef Prev type;
 };
 
-
 template
    < class DefaultOptions
    , class O1 = none
@@ -537,7 +581,8 @@
    , class O7 = none
    , class O8 = none
    , class O9 = none
- , class Option10 = none
+ , class O10 = none
+ , class O11 = none
>
 struct pack_options
 {
@@ -553,29 +598,164 @@
                         < typename do_pack
                            < typename do_pack
                               < typename do_pack
- < DefaultOptions
- , O1
+ < typename do_pack
+ < DefaultOptions
+ , O1
+ >::type
+ , O2
>::type
- , O2
+ , O3
>::type
- , O3
+ , O4
>::type
- , O4
+ , O5
>::type
- , O5
+ , O6
>::type
- , O6
+ , O7
>::type
- , O7
+ , O8
>::type
- , O8
+ , O9
>::type
- , O9
- >::type
- , Option10
+ , O10
+ >::type
+ , O11
>::type
    type;
 };
+#else
+
+//index_tuple
+template<int... Indexes>
+struct index_tuple{};
+
+//build_number_seq
+template<std::size_t Num, typename Tuple = index_tuple<> >
+struct build_number_seq;
+
+template<std::size_t Num, int... Indexes>
+struct build_number_seq<Num, index_tuple<Indexes...> >
+ : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
+{};
+
+template<int... Indexes>
+struct build_number_seq<0, index_tuple<Indexes...> >
+{ typedef index_tuple<Indexes...> type; };
+
+template<class ...Types>
+struct typelist
+{};
+
+//invert_typelist
+template<class T>
+struct invert_typelist;
+
+template<int I, typename Tuple>
+struct typelist_element;
+
+template<int I, typename Head, typename... Tail>
+struct typelist_element<I, typelist<Head, Tail...> >
+{
+ typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct typelist_element<0, typelist<Head, Tail...> >
+{
+ typedef Head type;
+};
+
+template<int ...Ints, class ...Types>
+typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
+ inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
+{
+ return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
+}
+
+//sizeof_typelist
+template<class Typelist>
+struct sizeof_typelist;
+
+template<class ...Types>
+struct sizeof_typelist< typelist<Types...> >
+{
+ static const std::size_t value = sizeof...(Types);
+};
+
+//invert_typelist_impl
+template<class Typelist, class Indexes>
+struct invert_typelist_impl;
+
+
+template<class Typelist, int ...Ints>
+struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
+{
+ static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
+ typedef typelist
+ <typename typelist_element<last_idx - Ints, Typelist>::type...> type;
+};
+
+template<class Typelist, int Int>
+struct invert_typelist_impl< Typelist, index_tuple<Int> >
+{
+ typedef Typelist type;
+};
+
+template<class Typelist>
+struct invert_typelist_impl< Typelist, index_tuple<> >
+{
+ typedef Typelist type;
+};
+
+//invert_typelist
+template<class Typelist>
+struct invert_typelist;
+
+template<class ...Types>
+struct invert_typelist< typelist<Types...> >
+{
+ typedef typelist<Types...> typelist_t;
+ typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
+ typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
+};
+
+//Do pack
+template<class Typelist>
+struct do_pack;
+
+template<>
+struct do_pack<typelist<> >;
+
+template<class Prev>
+struct do_pack<typelist<Prev> >
+{
+ typedef Prev type;
+};
+
+template<class Prev, class Last>
+struct do_pack<typelist<Prev, Last> >
+{
+ typedef typename Prev::template pack<Last> type;
+};
+
+template<class Prev, class ...Others>
+struct do_pack<typelist<Prev, Others...> >
+{
+ typedef typename Prev::template pack
+ <typename do_pack<typelist<Others...>>::type> type;
+};
+
+
+template<class ...Options>
+struct pack_options
+{
+ typedef typelist<Options...> typelist_t;
+ typedef typename invert_typelist<typelist_t>::type inverted_typelist;
+ typedef typename do_pack<inverted_typelist>::type type;
+};
+
+#endif
 
 struct hook_defaults
    : public pack_options

Modified: branches/release/boost/intrusive/pointer_plus_bits.hpp
==============================================================================
--- branches/release/boost/intrusive/pointer_plus_bits.hpp (original)
+++ branches/release/boost/intrusive/pointer_plus_bits.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -14,6 +14,7 @@
 #define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
 
 #include <boost/intrusive/detail/mpl.hpp> //ls_zeros
+#include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
 
 namespace boost {
 namespace intrusive {
@@ -28,7 +29,7 @@
    static const std::size_t value = 0;
 };
 
-//!This is an specialization for raw pointers.
+//!This is a specialization for raw pointers.
 //!Raw pointers can embed extra bits in the lower bits
 //!if the alignment is multiple of 2pow(NumBits).
 template<std::size_t Alignment>
@@ -61,7 +62,7 @@
 
    static void set_pointer(pointer &n, pointer p)
    {
- assert(0 == (std::size_t(p) & Mask));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(0 == (std::size_t(p) & Mask));
       n = pointer(std::size_t(p) | (std::size_t(n) & Mask));
    }
 
@@ -70,7 +71,7 @@
 
    static void set_bits(pointer &n, std::size_t c)
    {
- assert(c <= Mask);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(c <= Mask);
       n = pointer(std::size_t(get_pointer(n)) | c);
    }
 };

Modified: branches/release/boost/intrusive/rbtree.hpp
==============================================================================
--- branches/release/boost/intrusive/rbtree.hpp (original)
+++ branches/release/boost/intrusive/rbtree.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -36,20 +36,6 @@
 
 /// @cond
 
-template <class T>
-struct internal_default_set_hook
-{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_set_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
-};
-
-template <class T>
-struct get_default_set_hook
-{
- typedef typename T::default_set_hook type;
-};
-
 template <class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
 struct setopt
 {
@@ -63,13 +49,7 @@
 struct set_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < internal_default_set_hook<T>::value
- , get_default_set_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_set_hook>
       , constant_time_size<true>
       , size_type<std::size_t>
       , compare<std::less<T> >
@@ -91,7 +71,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1055,29 +1035,34 @@
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
       if(!src.empty()){
+ detail::exception_disposer<rbtree_impl, Disposer>
+ rollback(*this, disposer);
          node_algorithms::clone
             (const_node_ptr(&src.priv_header())
             ,node_ptr(&this->priv_header())
             ,detail::node_cloner<Cloner, rbtree_impl>(cloner, this)
             ,detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
          this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_comp() = src.priv_comp();
+ rollback.release();
       }
    }
 
@@ -1253,26 +1238,26 @@
    { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
 #else
 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
 #endif
 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 bool operator==
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
 #else
 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
@@ -1304,65 +1289,65 @@
    }
 }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
 #else
 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
 #else
 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
 #else
 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y)
 #else
 (const rbtree_impl<Config> &x, const rbtree_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (rbtree_impl<T, Options...> &x, rbtree_impl<T, Options...> &y)
 #else
 (rbtree_impl<Config> &x, rbtree_impl<Config> &y)
@@ -1370,15 +1355,23 @@
 { x.swap(y); }
 
 /// @cond
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
- , class O5 = none, class O6 = none
- , class O7 = none
>
+#else
+template<class T, class ...Options>
+#endif
 struct make_rbtree_opt
 {
    typedef typename pack_options
- < set_defaults<T>, O1, O2, O3, O4>::type packed_options;
+ < set_defaults<T>,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
 
@@ -1393,7 +1386,7 @@
 
 //! Helper metafunction to define a \c rbtree that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1403,19 +1396,42 @@
 {
    /// @cond
    typedef rbtree_impl
- < typename make_rbtree_opt<T, O1, O2, O3, O4>::type
+ < typename make_rbtree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class rbtree
- : public make_rbtree<T, O1, O2, O3, O4>::type
+ : public make_rbtree<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_rbtree
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/set.hpp
==============================================================================
--- branches/release/boost/intrusive/set.hpp (original)
+++ branches/release/boost/intrusive/set.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -32,7 +32,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -324,18 +324,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const set_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -997,65 +998,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
 #else
 (const set_impl<Config> &x, const set_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
 #else
 (const set_impl<Config> &x, const set_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
 #else
 (const set_impl<Config> &x, const set_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const set_impl<T, Options...> &x, const set_impl<T, Options...> &y)
 #else
 (const set_impl<Config> &x, const set_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (set_impl<T, Options...> &x, set_impl<T, Options...> &y)
 #else
 (set_impl<Config> &x, set_impl<Config> &y)
@@ -1064,7 +1065,7 @@
 
 //! Helper metafunction to define a \c set that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1074,19 +1075,41 @@
 {
    /// @cond
    typedef set_impl
- < typename make_rbtree_opt<T, O1, O2, O3, O4>::type
+ < typename make_rbtree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class set
- : public make_set<T, O1, O2, O3, O4>::type
+ : public make_set<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_set
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;
@@ -1135,7 +1158,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1423,18 +1446,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -2018,65 +2042,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
 #else
 (const multiset_impl<Config> &x, const multiset_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
 #else
 (const multiset_impl<Config> &x, const multiset_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
 #else
 (const multiset_impl<Config> &x, const multiset_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const multiset_impl<T, Options...> &x, const multiset_impl<T, Options...> &y)
 #else
 (const multiset_impl<Config> &x, const multiset_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (multiset_impl<T, Options...> &x, multiset_impl<T, Options...> &y)
 #else
 (multiset_impl<Config> &x, multiset_impl<Config> &y)
@@ -2085,7 +2109,7 @@
 
 //! Helper metafunction to define a \c multiset that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -2095,19 +2119,41 @@
 {
    /// @cond
    typedef multiset_impl
- < typename make_rbtree_opt<T, O1, O2, O3, O4>::type
+ < typename make_rbtree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class multiset
- : public make_multiset<T, O1, O2, O3, O4>::type
+ : public make_multiset<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
- typedef typename make_multiset
- <T, O1, O2, O3, O4>::type Base;
+ typedef typename make_multiset<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/set_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/set_hook.hpp (original)
+++ branches/release/boost/intrusive/set_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -35,7 +35,7 @@
 
 //! Helper metafunction to define a \c set_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
@@ -44,7 +44,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3, O4>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_set_node_algo<typename packed_options::void_pointer
@@ -77,15 +83,21 @@
 //!
 //! \c optimize_size<> will tell the hook to optimize the hook for size instead
 //! of speed.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3, class O4>
 #endif
 class set_base_hook
- : public make_set_base_hook<O1, O2, O3, O4>::type
+ : public make_set_base_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -154,7 +166,7 @@
 
 //! Helper metafunction to define a \c set_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
@@ -163,7 +175,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3, O4>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_set_node_algo<typename packed_options::void_pointer
@@ -191,15 +209,21 @@
 //!
 //! \c optimize_size<> will tell the hook to optimize the hook for size instead
 //! of speed.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3, class O4>
 #endif
 class set_member_hook
- : public make_set_member_hook<O1, O2, O3, O4>::type
+ : public make_set_member_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: branches/release/boost/intrusive/sg_set.hpp
==============================================================================
--- branches/release/boost/intrusive/sg_set.hpp (original)
+++ branches/release/boost/intrusive/sg_set.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -31,7 +31,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -323,18 +323,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const sg_set_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -1035,65 +1036,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_set_impl<T, Options...> &x, const sg_set_impl<T, Options...> &y)
 #else
 (const sg_set_impl<Config> &x, const sg_set_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_set_impl<T, Options...> &x, const sg_set_impl<T, Options...> &y)
 #else
 (const sg_set_impl<Config> &x, const sg_set_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_set_impl<T, Options...> &x, const sg_set_impl<T, Options...> &y)
 #else
 (const sg_set_impl<Config> &x, const sg_set_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_set_impl<T, Options...> &x, const sg_set_impl<T, Options...> &y)
 #else
 (const sg_set_impl<Config> &x, const sg_set_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (sg_set_impl<T, Options...> &x, sg_set_impl<T, Options...> &y)
 #else
 (sg_set_impl<Config> &x, sg_set_impl<Config> &y)
@@ -1102,7 +1103,7 @@
 
 //! Helper metafunction to define a \c sg_set that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1112,19 +1113,42 @@
 {
    /// @cond
    typedef sg_set_impl
- < typename make_sgtree_opt<T, O1, O2, O3, O4>::type
+ < typename make_sgtree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class sg_set
- : public make_sg_set<T, O1, O2, O3, O4>::type
+ : public make_sg_set<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_sg_set
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;
@@ -1173,7 +1197,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1461,18 +1485,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const sg_multiset_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -2080,65 +2105,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_multiset_impl<T, Options...> &x, const sg_multiset_impl<T, Options...> &y)
 #else
 (const sg_multiset_impl<Config> &x, const sg_multiset_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_multiset_impl<T, Options...> &x, const sg_multiset_impl<T, Options...> &y)
 #else
 (const sg_multiset_impl<Config> &x, const sg_multiset_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_multiset_impl<T, Options...> &x, const sg_multiset_impl<T, Options...> &y)
 #else
 (const sg_multiset_impl<Config> &x, const sg_multiset_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sg_multiset_impl<T, Options...> &x, const sg_multiset_impl<T, Options...> &y)
 #else
 (const sg_multiset_impl<Config> &x, const sg_multiset_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (sg_multiset_impl<T, Options...> &x, sg_multiset_impl<T, Options...> &y)
 #else
 (sg_multiset_impl<Config> &x, sg_multiset_impl<Config> &y)
@@ -2147,7 +2172,7 @@
 
 //! Helper metafunction to define a \c sg_multiset that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -2157,19 +2182,42 @@
 {
    /// @cond
    typedef sg_multiset_impl
- < typename make_sgtree_opt<T, O1, O2, O3, O4>::type
+ < typename make_sgtree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class sg_multiset
- : public make_sg_multiset<T, O1, O2, O3, O4>::type
+ : public make_sg_multiset<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_sg_multiset
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/sgtree.hpp
==============================================================================
--- branches/release/boost/intrusive/sgtree.hpp (original)
+++ branches/release/boost/intrusive/sgtree.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -151,7 +151,7 @@
 
    void set_alpha(float)
    { //alpha CAN't be changed.
- assert(0);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
    }
 
    h_alpha_t get_h_alpha_t() const
@@ -176,13 +176,7 @@
 struct sg_set_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < internal_default_bs_set_hook<T>::value
- , get_default_bs_set_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_bs_set_hook>
       , floating_point<true>
       , size_type<std::size_t>
       , compare<std::less<T> >
@@ -204,7 +198,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c floating_point<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1212,29 +1206,34 @@
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const sgtree_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
       if(!src.empty()){
+ detail::exception_disposer<sgtree_impl, Disposer>
+ rollback(*this, disposer);
          node_algorithms::clone
             (const_node_ptr(&src.priv_header())
             ,node_ptr(&this->priv_header())
             ,detail::node_cloner<Cloner, sgtree_impl>(cloner, this)
             ,detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
          this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_comp() = src.priv_comp();
+ rollback.release();
       }
    }
 
@@ -1469,26 +1468,26 @@
    { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
 #else
 (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
 #endif
 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 bool operator==
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
 #else
 (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
@@ -1520,65 +1519,65 @@
    }
 }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
 #else
 (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
 #else
 (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
 #else
 (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y)
 #else
 (const sgtree_impl<Config> &x, const sgtree_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (sgtree_impl<T, Options...> &x, sgtree_impl<T, Options...> &y)
 #else
 (sgtree_impl<Config> &x, sgtree_impl<Config> &y)
@@ -1586,15 +1585,22 @@
 { x.swap(y); }
 
 /// @cond
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1 = none, class O2 = none
- , class O3 = none, class O4 = none
- , class O5 = none, class O6 = none
- , class O7 = none
- >
+ , class O3 = none, class O4 = none>
+#else
+template<class T, class ...Options>
+#endif
 struct make_sgtree_opt
 {
    typedef typename pack_options
- < sg_set_defaults<T>, O1, O2, O3, O4>::type packed_options;
+ < sg_set_defaults<T>,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
 
@@ -1609,7 +1615,7 @@
 
 //! Helper metafunction to define a \c sgtree that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1619,19 +1625,41 @@
 {
    /// @cond
    typedef sgtree_impl
- < typename make_sgtree_opt<T, O1, O2, O3, O4>::type
+ < typename make_sgtree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class sgtree
- : public make_sgtree<T, O1, O2, O3, O4>::type
+ : public make_sgtree<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_sgtree
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/sgtree_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/sgtree_algorithms.hpp (original)
+++ branches/release/boost/intrusive/sgtree_algorithms.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -683,7 +683,7 @@
          for(std::size_t i = 1; true; ++i){
             bool rebalance = false;
             if(i == depth){
- assert(tree_size == count(s));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(tree_size == count(s));
                rebalance = true;
             }
             else if(i > h_alpha(size)){

Modified: branches/release/boost/intrusive/slist.hpp
==============================================================================
--- branches/release/boost/intrusive/slist.hpp (original)
+++ branches/release/boost/intrusive/slist.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -36,18 +36,6 @@
 
 /// @cond
 
-template <class T>
-struct internal_default_slist_hook
-{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_slist_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
-};
-
-template <class T>
-struct get_default_slist_hook
-{ typedef typename T::default_slist_hook type; };
-
 template <class ValueTraits, class SizeType, bool ConstantTimeSize, bool Linear, bool CacheLast>
 struct slistopt
 {
@@ -75,13 +63,7 @@
 struct slist_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < internal_default_slist_hook<T>::value
- , get_default_slist_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_slist_hook>
       , constant_time_size<true>
       , linear<false>
       , size_type<std::size_t>
@@ -114,7 +96,7 @@
 //! the '*_after' functions, ++end() == begin() and previous(begin()) == end()
 //! 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
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -300,7 +282,7 @@
       : data_(v_traits)
    {
       this->set_default_constructed_state();
- this->insert_after(this->before_begin(), b, e);
+ this->insert_after(this->cbefore_begin(), b, e);
    }
 
    //! <b>Effects</b>: If it's a safe-mode
@@ -346,7 +328,7 @@
    template <class Disposer>
    void clear_and_dispose(Disposer disposer)
    {
- iterator it(this->begin()), itend(this->end());
+ const_iterator it(this->begin()), itend(this->end());
       while(it != itend){
          node_ptr to_erase(it.pointed_node());
          ++it;
@@ -395,7 +377,7 @@
    void push_back(reference value)
    {
       BOOST_STATIC_ASSERT((cache_last != 0));
- this->insert_after(iterator(this->get_last_node(), this), value);
+ this->insert_after(const_iterator(this->get_last_node(), this), value);
    }
 
    //! <b>Effects</b>: Erases the first element of the list.
@@ -650,6 +632,7 @@
    { this->priv_shift_forward(n, detail::bool_<linear>()); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
@@ -668,7 +651,7 @@
       this->clear_and_dispose(disposer);
       detail::exception_disposer<slist_impl, Disposer>
          rollback(*this, disposer);
- iterator prev(this->before_begin());
+ const_iterator prev(this->cbefore_begin());
       const_iterator b(src.begin()), e(src.end());
       for(; b != e; ++b){
          prev = this->insert_after(prev, *cloner(*b));
@@ -689,7 +672,7 @@
    //! <b>Complexity</b>: Constant.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
- iterator insert_after(iterator prev_p, reference value)
+ iterator insert_after(const_iterator prev_p, reference value)
    {
       node_ptr n = get_real_value_traits().to_node_ptr(value);
       if(safemode_or_autounlink)
@@ -716,7 +699,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    template<class Iterator>
- void insert_after(iterator prev_p, Iterator first, Iterator last)
+ void insert_after(const_iterator prev_p, Iterator first, Iterator last)
    {
       for (; first != last; ++first)
          prev_p = this->insert_after(prev_p, *first);
@@ -734,7 +717,7 @@
    //! 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)
+ iterator insert(const_iterator p, reference value)
    { return this->insert_after(this->previous(p), value); }
 
    //! <b>Requires</b>: Dereferencing iterator must yield
@@ -752,7 +735,7 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    template<class Iterator>
- void insert(iterator p, Iterator b, Iterator e)
+ void insert(const_iterator p, Iterator b, Iterator e)
    { return this->insert_after(this->previous(p), b, e); }
 
    //! <b>Effects</b>: Erases the element after the element pointed by prev of
@@ -767,7 +750,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
- iterator erase_after(iterator prev)
+ iterator erase_after(const_iterator prev)
    { return this->erase_after_and_dispose(prev, detail::null_disposer()); }
 
    //! <b>Effects</b>: Erases the range (before_first, last) from
@@ -783,7 +766,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
- iterator erase_after(iterator before_first, iterator last)
+ iterator erase_after(const_iterator before_first, const_iterator last)
    {
       if(safemode_or_autounlink || constant_time_size){
          return this->erase_after_and_dispose(before_first, last, detail::null_disposer());
@@ -797,7 +780,7 @@
             }
          }
          node_algorithms::unlink_after(bfp, lp);
- return last;
+ return last.unconst();
       }
    }
 
@@ -815,9 +798,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
- iterator erase_after(iterator before_first, iterator last, difference_type n)
+ iterator erase_after(const_iterator before_first, const_iterator last, difference_type n)
    {
- BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(++iterator(before_first), last) == difference_type(n));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(++const_iterator(before_first), last) == difference_type(n));
       if(safemode_or_autounlink){
          return this->erase_after(before_first, last);
       }
@@ -833,7 +816,7 @@
          if(constant_time_size){
             this->priv_size_traits().set_size(this->priv_size_traits().get_size() - n);
          }
- return last;
+ return last.unconst();
       }
    }
 
@@ -849,7 +832,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return this->erase_after(this->previous(i)); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -866,7 +849,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased elements.
- iterator erase(iterator first, iterator last)
+ iterator erase(const_iterator first, const_iterator last)
    { return this->erase_after(this->previous(first), last); }
 
    //! <b>Effects</b>: Erases the range [first, last) from
@@ -883,7 +866,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
- iterator erase(iterator first, iterator last, difference_type n)
+ iterator erase(const_iterator first, const_iterator last, difference_type n)
    { return this->erase_after(this->previous(first), last, n); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -901,9 +884,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators to the erased element.
    template<class Disposer>
- iterator erase_after_and_dispose(iterator prev, Disposer disposer)
+ iterator erase_after_and_dispose(const_iterator prev, Disposer disposer)
    {
- iterator it(prev);
+ const_iterator it(prev);
       ++it;
       node_ptr to_erase(it.pointed_node());
       ++it;
@@ -916,16 +899,16 @@
          node_algorithms::init(to_erase);
       disposer(get_real_value_traits().to_value_ptr(to_erase));
       this->priv_size_traits().decrement();
- return it;
+ return it.unconst();
    }
 
    /// @cond
 
    template<class Disposer>
- static iterator s_erase_after_and_dispose(iterator prev, Disposer disposer)
+ static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer)
    {
       BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
- iterator it(prev);
+ const_iterator it(prev);
       ++it;
       node_ptr to_erase(it.pointed_node());
       ++it;
@@ -934,10 +917,10 @@
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
       disposer(real_value_traits::to_value_ptr(to_erase));
- return it;
+ return it.unconst();
    }
 
- static iterator s_erase_after(iterator prev)
+ static iterator s_erase_after(const_iterator prev)
    { return s_erase_after_and_dispose(prev, detail::null_disposer()); }
 
    /// @endcond
@@ -957,7 +940,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators to the erased element.
    template<class Disposer>
- iterator erase_after_and_dispose(iterator before_first, iterator last, Disposer disposer)
+ iterator erase_after_and_dispose(const_iterator before_first, const_iterator last, Disposer disposer)
    {
       node_ptr bfp(before_first.pointed_node()), lp(last.pointed_node());
       node_ptr fp(node_traits::get_next(bfp));
@@ -973,7 +956,7 @@
       if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){
          this->set_last_node(bfp);
       }
- return last;
+ return last.unconst();
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -992,7 +975,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased element.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return this->erase_after_and_dispose(this->previous(i), disposer); }
 
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -1013,7 +996,7 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references) to the
    //! erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator first, iterator last, Disposer disposer)
+ iterator erase_and_dispose(const_iterator first, const_iterator last, Disposer disposer)
    { return this->erase_after_and_dispose(this->previous(first), last, disposer); }
 
    //! <b>Requires</b>: Dereferencing iterator must yield
@@ -1035,7 +1018,7 @@
    void assign(Iterator b, Iterator e)
    {
       this->clear();
- this->insert_after(this->before_begin(), b, e);
+ this->insert_after(this->cbefore_begin(), b, e);
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1058,7 +1041,7 @@
    void dispose_and_assign(Disposer disposer, Iterator b, Iterator e)
    {
       this->clear_and_dispose(disposer);
- this->insert_after(this->before_begin(), b, e, disposer);
+ this->insert_after(this->cbefore_begin(), b, e, disposer);
    }
 
    //! <b>Requires</b>: prev is an iterator to an element or x.end()/x.before_begin() in x.
@@ -1077,10 +1060,10 @@
    //!
    //! <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)
+ iterator splice_after(const_iterator prev, slist_impl &x)
    {
       if (!x.empty()){
- iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active
+ const_iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active
          node_ptr prev_n(prev.pointed_node());
          node_ptr last_x_n(last_x.pointed_node());
          if(cache_last){
@@ -1092,10 +1075,10 @@
          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;
+ return last_x.unconst();
       }
       else{
- return prev;
+ return prev.unconst();
       }
    }
 
@@ -1112,9 +1095,9 @@
    //!
    //! <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_pos, slist_impl &x, iterator prev_ele)
+ void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator prev_ele)
    {
- iterator elem = prev_ele;
+ const_iterator elem = prev_ele;
       this->splice_after(prev_pos, x, prev_ele, ++elem, 1);
    }
 
@@ -1133,7 +1116,7 @@
    //!
    //! <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_pos, slist_impl &x, iterator before_first, iterator before_last)
+ void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_first, const_iterator before_last)
    {
       if(constant_time_size)
          this->splice_after(prev_pos, x, before_first, before_last, std::distance(before_first, before_last));
@@ -1156,7 +1139,7 @@
    //!
    //! <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_pos, slist_impl &x, iterator before_first, iterator before_last, difference_type n)
+ void splice_after(const_iterator prev_pos, slist_impl &x, const_iterator before_first, const_iterator before_last, difference_type n)
    {
       if(n){
          BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_first, before_last) == n);
@@ -1188,7 +1171,7 @@
    //!
    //! <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)
+ iterator splice(const_iterator it, slist_impl &x)
    { return this->splice_after(this->previous(it), x); }
 
    //! <b>Requires</b>: it p must be a valid iterator of *this.
@@ -1205,7 +1188,7 @@
    //!
    //! <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)
+ void splice(const_iterator pos, slist_impl &x, const_iterator elem)
    { return this->splice_after(this->previous(pos), x, x.previous(elem)); }
 
    //! <b>Requires</b>: pos must be a dereferenceable iterator in *this
@@ -1225,7 +1208,7 @@
    //!
    //! <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)
+ void splice(const_iterator pos, slist_impl &x, const_iterator first, const_iterator 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
@@ -1244,7 +1227,7 @@
    //!
    //! <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)
+ void splice(const_iterator pos, slist_impl &x, const_iterator first, const_iterator last, difference_type 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>.
@@ -1266,10 +1249,10 @@
          slist_impl carry;
          slist_impl counter[64];
          int fill = 0;
- iterator last_inserted;
+ const_iterator last_inserted;
          while(!this->empty()){
- last_inserted = this->begin();
- carry.splice_after(carry.before_begin(), *this, this->before_begin());
+ last_inserted = this->cbegin();
+ carry.splice_after(carry.cbefore_begin(), *this, this->cbefore_begin());
             int i = 0;
             while(i < fill && !counter[i].empty()) {
                last_inserted = carry.merge(counter[i++], p);
@@ -1277,16 +1260,16 @@
             BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
 
             node_ptr p = node_algorithms::get_previous_node
- (last_inserted.pointed_node(), carry.end().pointed_node());
- iterator last_element(p, this);
+ (last_inserted.pointed_node(), carry.cend().pointed_node());
+ const_iterator last_element(p, this);
             if(constant_time_size){
- counter[i].splice_after( counter[i].before_begin(), carry
- , carry.before_begin(), last_element
+ counter[i].splice_after( counter[i].cbefore_begin(), carry
+ , carry.cbefore_begin(), last_element
                                       , carry.size());
             }
             else{
- counter[i].splice_after( counter[i].before_begin(), carry
- , carry.before_begin(), last_element);
+ counter[i].splice_after( counter[i].cbefore_begin(), carry
+ , carry.cbefore_begin(), last_element);
             }
             if(i == fill)
                ++fill;
@@ -1298,13 +1281,13 @@
 
          node_ptr p = node_algorithms::get_previous_node
             (last_inserted.pointed_node(), counter[--fill].end().pointed_node());
- iterator last_element(p, this);
+ const_iterator last_element(p, this);
          if(constant_time_size){
- this->splice_after( before_begin(), counter[fill], counter[fill].before_begin()
+ this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
                               , last_element, counter[fill].size());
          }
          else{
- this->splice_after( before_begin(), counter[fill], counter[fill].before_begin()
+ this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
                               , last_element);
          }
       }
@@ -1348,12 +1331,12 @@
    template<class Predicate>
    iterator merge(slist_impl& x, Predicate p)
    {
- iterator a(before_begin()), e(end()), ax(x.before_begin()), ex(x.end());
- iterator last_inserted(e);
- iterator a_next;
+ const_iterator a(cbefore_begin()), e(cend()), ax(x.cbefore_begin()), ex(x.cend());
+ const_iterator last_inserted(e);
+ const_iterator a_next;
       while(++(a_next = a) != e && !x.empty()) {
- iterator ix(ax);
- iterator cx;
+ const_iterator ix(ax);
+ const_iterator cx;
          size_type n(0);
          while(++(cx = ix) != ex && p(*cx, *a_next)){
             ++ix; ++n;
@@ -1367,7 +1350,7 @@
       if (!x.empty()){
          last_inserted = this->splice_after(a, x);
       }
- return last_inserted;
+ return last_inserted.unconst();
    }
 
    //! <b>Effects</b>: This function removes all of x's elements and inserts them
@@ -1455,7 +1438,7 @@
    template<class Pred, class Disposer>
    void remove_and_dispose_if(Pred pred, Disposer disposer)
    {
- iterator bcur(this->before_begin()), cur(this->begin()), e(this->end());
+ const_iterator bcur(this->before_begin()), cur(this->begin()), e(this->end());
       
       while(cur != e){
          if (pred(*cur)){
@@ -1528,10 +1511,10 @@
    template<class BinaryPredicate, class Disposer>
    void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
    {
- iterator end_n(this->end());
- iterator bcur(this->begin());
+ const_iterator end_n(this->cend());
+ const_iterator bcur(this->cbegin());
       if(bcur != end_n){
- iterator cur(bcur);
+ const_iterator cur(bcur);
          ++cur;
          while(cur != end_n) {
             if (pred(*bcur, *cur)){
@@ -1643,7 +1626,7 @@
    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(uncast(this->get_last_node()), this);
       }
       return const_iterator
          (node_algorithms::get_previous_node
@@ -1760,26 +1743,26 @@
    }
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
 #else
 (const slist_impl<Config> &x, const slist_impl<Config> &y)
 #endif
 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 bool operator==
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
 #else
 (const slist_impl<Config> &x, const slist_impl<Config> &y)
@@ -1812,65 +1795,65 @@
    }
 }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
 #else
 (const slist_impl<Config> &x, const slist_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
 #else
 (const slist_impl<Config> &x, const slist_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
 #else
 (const slist_impl<Config> &x, const slist_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
 #else
 (const slist_impl<Config> &x, const slist_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
 #else
 (slist_impl<Config> &x, slist_impl<Config> &y)
@@ -1879,7 +1862,7 @@
 
 //! Helper metafunction to define a \c slist that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none, class O3 = none, class O4 = none, class O5 = none>
@@ -1888,7 +1871,13 @@
 {
    /// @cond
    typedef typename pack_options
- < slist_defaults<T>, O1, O2, O3, O4, O5>::type packed_options;
+ < slist_defaults<T>,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5
+ #else
+ Options...
+ #endif
+ >::type packed_options;
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
    typedef slist_impl
@@ -1907,12 +1896,29 @@
 
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4, class O5>
+#else
+template<class T, class ...Options>
+#endif
 class slist
- : public make_slist<T, O1, O2, O3, O4, O5>::type
+ : public make_slist<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_slist
- <T, O1, O2, O3, O4, O5>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5
+ #else
+ Options...
+ #endif
+ >::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-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -37,7 +37,7 @@
 
 //! Helper metafunction to define a \c slist_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -46,7 +46,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_slist_node_algo<typename packed_options::void_pointer>
@@ -75,15 +81,21 @@
 //!
 //! \c void_pointer<> is the pointer type that will be used internally in the hook
 //! and the the container configured to use this hook.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class slist_base_hook
- : public make_slist_base_hook<O1, O2, O3>::type
+ : public make_slist_base_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -152,7 +164,7 @@
 
 //! Helper metafunction to define a \c slist_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -161,7 +173,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_slist_node_algo<typename packed_options::void_pointer>
@@ -185,15 +203,21 @@
 //!
 //! \c void_pointer<> is the pointer type that will be used internally in the hook
 //! and the the container configured to use this hook.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class slist_member_hook
- : public make_slist_member_hook<O1, O2, O3>::type
+ : public make_slist_member_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: branches/release/boost/intrusive/splay_set.hpp
==============================================================================
--- branches/release/boost/intrusive/splay_set.hpp (original)
+++ branches/release/boost/intrusive/splay_set.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -31,7 +31,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -323,18 +323,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const splay_set_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -1072,65 +1073,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_set_impl<T, Options...> &x, const splay_set_impl<T, Options...> &y)
 #else
 (const splay_set_impl<Config> &x, const splay_set_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_set_impl<T, Options...> &x, const splay_set_impl<T, Options...> &y)
 #else
 (const splay_set_impl<Config> &x, const splay_set_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_set_impl<T, Options...> &x, const splay_set_impl<T, Options...> &y)
 #else
 (const splay_set_impl<Config> &x, const splay_set_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_set_impl<T, Options...> &x, const splay_set_impl<T, Options...> &y)
 #else
 (const splay_set_impl<Config> &x, const splay_set_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (splay_set_impl<T, Options...> &x, splay_set_impl<T, Options...> &y)
 #else
 (splay_set_impl<Config> &x, splay_set_impl<Config> &y)
@@ -1139,7 +1140,7 @@
 
 //! Helper metafunction to define a \c splay_set that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1149,19 +1150,41 @@
 {
    /// @cond
    typedef splay_set_impl
- < typename make_splaytree_opt<T, O1, O2, O3, O4>::type
+ < typename make_splaytree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class splay_set
- : public make_splay_set<T, O1, O2, O3, O4>::type
+ : public make_splay_set<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_splay_set
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;
@@ -1210,7 +1233,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1498,18 +1521,19 @@
    { tree_.swap(other.tree_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const splay_multiset_impl &src, Cloner cloner, Disposer disposer)
    { tree_.clone_from(src.tree_, cloner, disposer); }
@@ -2154,65 +2178,65 @@
    /// @endcond
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_multiset_impl<T, Options...> &x, const splay_multiset_impl<T, Options...> &y)
 #else
 (const splay_multiset_impl<Config> &x, const splay_multiset_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_multiset_impl<T, Options...> &x, const splay_multiset_impl<T, Options...> &y)
 #else
 (const splay_multiset_impl<Config> &x, const splay_multiset_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_multiset_impl<T, Options...> &x, const splay_multiset_impl<T, Options...> &y)
 #else
 (const splay_multiset_impl<Config> &x, const splay_multiset_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splay_multiset_impl<T, Options...> &x, const splay_multiset_impl<T, Options...> &y)
 #else
 (const splay_multiset_impl<Config> &x, const splay_multiset_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (splay_multiset_impl<T, Options...> &x, splay_multiset_impl<T, Options...> &y)
 #else
 (splay_multiset_impl<Config> &x, splay_multiset_impl<Config> &y)
@@ -2221,7 +2245,7 @@
 
 //! Helper metafunction to define a \c splay_multiset that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -2231,19 +2255,42 @@
 {
    /// @cond
    typedef splay_multiset_impl
- < typename make_splaytree_opt<T, O1, O2, O3, O4>::type
+ < typename make_splaytree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class splay_multiset
- : public make_splay_multiset<T, O1, O2, O3, O4>::type
+ : public make_splay_multiset<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_splay_multiset
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/splay_set_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/splay_set_hook.hpp (original)
+++ branches/release/boost/intrusive/splay_set_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -34,7 +34,7 @@
 
 //! Helper metafunction to define a \c splay_set_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -43,7 +43,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_splay_set_node_algo<typename packed_options::void_pointer>
@@ -72,15 +78,21 @@
 //!
 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
 //! \c auto_unlink or \c safe_link).
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class splay_set_base_hook
- : public make_splay_set_base_hook<O1, O2, O3>::type
+ : public make_splay_set_base_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -149,7 +161,7 @@
 
 //! Helper metafunction to define a \c splay_set_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none>
@@ -158,7 +170,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_splay_set_node_algo<typename packed_options::void_pointer>
@@ -183,15 +201,21 @@
 //!
 //! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
 //! \c auto_unlink or \c safe_link).
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3>
 #endif
 class splay_set_member_hook
- : public make_splay_set_member_hook<O1, O2, O3>::type
+ : public make_splay_set_member_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!

Modified: branches/release/boost/intrusive/splaytree.hpp
==============================================================================
--- branches/release/boost/intrusive/splaytree.hpp (original)
+++ branches/release/boost/intrusive/splaytree.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -35,20 +35,6 @@
 
 /// @cond
 
-template <class T>
-struct internal_default_splay_set_hook
-{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::default_splay_set_hook* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(detail::two);
-};
-
-template <class T>
-struct get_default_splay_set_hook
-{
- typedef typename T::default_splay_set_hook type;
-};
-
 template <class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
 struct splaysetopt
 {
@@ -62,13 +48,7 @@
 struct splay_set_defaults
    : pack_options
       < none
- , base_hook
- < typename detail::eval_if_c
- < internal_default_splay_set_hook<T>::value
- , get_default_splay_set_hook<T>
- , detail::identity<none>
- >::type
- >
+ , base_hook<detail::default_splay_set_hook>
       , constant_time_size<true>
       , size_type<std::size_t>
       , compare<std::less<T> >
@@ -90,7 +70,7 @@
 //! \c base_hook<>/member_hook<>/value_traits<>,
 //! \c constant_time_size<>, \c size_type<> and
 //! \c compare<>.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1072,29 +1052,34 @@
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. Copies the predicate from the source container.
    //!
    //! If cloner throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const splaytree_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
       if(!src.empty()){
+ detail::exception_disposer<splaytree_impl, Disposer>
+ rollback(*this, disposer);
          node_algorithms::clone
             (const_node_ptr(&src.priv_header())
             ,node_ptr(&this->priv_header())
             ,detail::node_cloner<Cloner, splaytree_impl>(cloner, this)
             ,detail::node_disposer<Disposer, splaytree_impl>(disposer, this));
          this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_comp() = src.priv_comp();
+ rollback.release();
       }
    }
 
@@ -1339,26 +1324,26 @@
    { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y)
 #else
 (const splaytree_impl<Config> &x, const splaytree_impl<Config> &y)
 #endif
 { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 bool operator==
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y)
 #else
 (const splaytree_impl<Config> &x, const splaytree_impl<Config> &y)
@@ -1390,65 +1375,65 @@
    }
 }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator!=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y)
 #else
 (const splaytree_impl<Config> &x, const splaytree_impl<Config> &y)
 #endif
 { return !(x == y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y)
 #else
 (const splaytree_impl<Config> &x, const splaytree_impl<Config> &y)
 #endif
 { return y < x; }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator<=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y)
 #else
 (const splaytree_impl<Config> &x, const splaytree_impl<Config> &y)
 #endif
 { return !(y < x); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline bool operator>=
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y)
 #else
 (const splaytree_impl<Config> &x, const splaytree_impl<Config> &y)
 #endif
 { return !(x < y); }
 
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
 #endif
 inline void swap
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 (splaytree_impl<T, Options...> &x, splaytree_impl<T, Options...> &y)
 #else
 (splaytree_impl<Config> &x, splaytree_impl<Config> &y)
@@ -1456,15 +1441,23 @@
 { x.swap(y); }
 
 /// @cond
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1 = none, class O2 = none
- , class O3 = none, class O4 = none
- , class O5 = none, class O6 = none
- , class O7 = none
- >
+ , class O3 = none, class O4 = none>
+#else
+template<class T, class ...Options>
+#endif
 struct make_splaytree_opt
 {
    typedef typename pack_options
- < splay_set_defaults<T>, O1, O2, O3, O4>::type packed_options;
+ < splay_set_defaults<T>,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
    typedef typename detail::get_value_traits
       <T, typename packed_options::value_traits>::type value_traits;
 
@@ -1479,7 +1472,7 @@
 
 //! Helper metafunction to define a \c splaytree that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
@@ -1489,19 +1482,41 @@
 {
    /// @cond
    typedef splaytree_impl
- < typename make_splaytree_opt<T, O1, O2, O3, O4>::type
+ < typename make_splaytree_opt<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class O1, class O2, class O3, class O4>
+#else
+template<class T, class ...Options>
+#endif
 class splaytree
- : public make_splaytree<T, O1, O2, O3, O4>::type
+ : public make_splaytree<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_splaytree
- <T, O1, O2, O3, O4>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    public:
    typedef typename Base::value_compare value_compare;

Modified: branches/release/boost/intrusive/splaytree_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/splaytree_algorithms.hpp (original)
+++ branches/release/boost/intrusive/splaytree_algorithms.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -870,7 +870,7 @@
          if(NodeTraits::get_parent(g) == p)
             NodeTraits::set_parent(g, n);
          else{//must be ( g->right == p )
- assert(0);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
             NodeTraits::set_right(g, n);
          }
       }

Modified: branches/release/boost/intrusive/unordered_set.hpp
==============================================================================
--- branches/release/boost/intrusive/unordered_set.hpp (original)
+++ branches/release/boost/intrusive/unordered_set.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -56,7 +56,7 @@
 //!
 //! Since no automatic rehashing is done, iterators are never invalidated when
 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -268,18 +268,24 @@
    { table_.swap(other.table_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes that compare equal and produce the same
+ //! hash than the original node.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. The hash function and the equality
+ //! predicate are copied from the source.
    //!
- //! If cloner throws, all cloned elements are unlinked and disposed
+ //! If store_hash option is true, this method does not use the hash function.
+ //!
+ //! If any operation throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
+ //! throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer)
    { table_.clone_from(src.table_, cloner, disposer); }
@@ -920,6 +926,8 @@
    //!
    //! <b>Effects</b>: Updates the internal reference with the new bucket erases
    //! the values from the old bucket and inserts then in the new one.
+ //!
+ //! If store_hash option is true, this method does not use the hash function.
    //!
    //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
    //!
@@ -927,6 +935,32 @@
    void rehash(const bucket_traits &new_bucket_traits)
    { table_.rehash(new_bucket_traits); }
 
+ //! <b>Requires</b>:
+ //!
+ //! <b>Effects</b>:
+ //!
+ //! <b>Complexity</b>:
+ //!
+ //! <b>Throws</b>:
+ //!
+ //! <b>Note</b>: this method is only available if incremental<true> option is activated.
+ bool incremental_rehash(bool grow = true)
+ { return table_.incremental_rehash(grow); }
+
+ //! <b>Note</b>: this method is only available if incremental<true> option is activated.
+ bool incremental_rehash(const bucket_traits &new_bucket_traits)
+ { return table_.incremental_rehash(new_bucket_traits); }
+
+ //! <b>Requires</b>:
+ //!
+ //! <b>Effects</b>:
+ //!
+ //! <b>Complexity</b>:
+ //!
+ //! <b>Throws</b>:
+ size_type split_count() const
+ { return table_.split_count(); }
+
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
    //! the container that is bigger than n. This suggestion can be used
    //! to create bucket arrays with a size that will usually improve
@@ -954,14 +988,14 @@
 
 //! Helper metafunction to define an \c unordered_set that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
                 , class O7 = none, class O8 = none
- , class O9 = none
+ , class O9 = none, class O10= none
>
 #endif
 struct make_unordered_set
@@ -969,19 +1003,42 @@
    /// @cond
    typedef unordered_set_impl
       < typename make_hashtable_opt
- <T, true, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
+ <T, true,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9>
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
+#else
+template<class T, class ...Options>
+#endif
 class unordered_set
- : public make_unordered_set<T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
+ : public make_unordered_set<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_unordered_set
- <T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type Base;
 
    //Assert if passed value traits are compatible with the type
    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
@@ -1052,7 +1109,7 @@
 //!
 //! Since no automatic rehashing is done, iterators are never invalidated when
 //! inserting or erasing elements. Iterators are only invalidated when rehasing.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
 template<class T, class ...Options>
 #else
 template<class Config>
@@ -1265,18 +1322,24 @@
    { table_.swap(other.table_); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes that compare equal and produce the same
+ //! hash than the original node.
    //!
    //! <b>Effects</b>: Erases all the elements from *this
    //! calling Disposer::operator()(pointer), clones all the
    //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this.
+ //! and inserts them on *this. The hash function and the equality
+ //! predicate are copied from the source.
    //!
- //! If cloner throws, all cloned elements are unlinked and disposed
+ //! If store_hash option is true, this method does not use the hash function.
+ //!
+ //! If any operation throws, all cloned elements are unlinked and disposed
    //! calling Disposer::operator()(pointer).
    //!
    //! <b>Complexity</b>: Linear to erased plus inserted elements.
    //!
- //! <b>Throws</b>: If cloner throws.
+ //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
+ //! throws. Basic guarantee.
    template <class Cloner, class Disposer>
    void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer)
    { table_.clone_from(src.table_, cloner, disposer); }
@@ -1854,6 +1917,8 @@
    //!
    //! <b>Effects</b>: Updates the internal reference with the new bucket erases
    //! the values from the old bucket and inserts then in the new one.
+ //!
+ //! If store_hash option is true, this method does not use the hash function.
    //!
    //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
    //!
@@ -1861,6 +1926,32 @@
    void rehash(const bucket_traits &new_bucket_traits)
    { table_.rehash(new_bucket_traits); }
 
+ //! <b>Requires</b>:
+ //!
+ //! <b>Effects</b>:
+ //!
+ //! <b>Complexity</b>:
+ //!
+ //! <b>Throws</b>:
+ //!
+ //! <b>Note</b>: this method is only available if incremental<true> option is activated.
+ bool incremental_rehash(bool grow = true)
+ { return table_.incremental_rehash(grow); }
+
+ //! <b>Note</b>: this method is only available if incremental<true> option is activated.
+ bool incremental_rehash(const bucket_traits &new_bucket_traits)
+ { return table_.incremental_rehash(new_bucket_traits); }
+
+ //! <b>Requires</b>:
+ //!
+ //! <b>Effects</b>:
+ //!
+ //! <b>Complexity</b>:
+ //!
+ //! <b>Throws</b>:
+ size_type split_count() const
+ { return table_.split_count(); }
+
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
    //! the container that is bigger than n. This suggestion can be used
    //! to create bucket arrays with a size that will usually improve
@@ -1888,14 +1979,14 @@
 
 //! Helper metafunction to define an \c unordered_multiset that yields to the same type when the
 //! same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class T, class ...Options>
 #else
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
                 , class O7 = none, class O8 = none
- , class O9 = none
+ , class O9 = none, class O10= none
>
 #endif
 struct make_unordered_multiset
@@ -1903,19 +1994,42 @@
    /// @cond
    typedef unordered_multiset_impl
       < typename make_hashtable_opt
- <T, false, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
+ <T, false,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9>
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8, class O9, class O10>
+#else
+template<class T, class ...Options>
+#endif
 class unordered_multiset
- : public make_unordered_multiset<T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type
+ : public make_unordered_multiset<T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type
 {
    typedef typename make_unordered_multiset
- <T, O1, O2, O3, O4, O5, O6, O7, O8, O9>::type Base;
+ <T,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
+ #else
+ Options...
+ #endif
+ >::type Base;
    //Assert if passed value traits are compatible with the type
    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
 

Modified: branches/release/boost/intrusive/unordered_set_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/unordered_set_hook.hpp (original)
+++ branches/release/boost/intrusive/unordered_set_hook.hpp 2008-10-13 15:36:50 EDT (Mon, 13 Oct 2008)
@@ -153,7 +153,7 @@
 
 //! Helper metafunction to define a \c unordered_set_base_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
@@ -162,7 +162,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3, O4>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_uset_node_algo<typename packed_options::void_pointer
@@ -201,15 +207,21 @@
 //! \c optimize_multikey<> will tell the hook to store a link to form a group
 //! with other value with the same value to speed up searches and insertions
 //! in unordered_multisets with a great number of with equivalent keys.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3, class O4>
 #endif
 class unordered_set_base_hook
- : public make_unordered_set_base_hook<O1, O2, O3, O4>::type
+ : public make_unordered_set_base_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!
@@ -279,7 +291,7 @@
 
 //! Helper metafunction to define a \c unordered_set_member_hook that yields to the same
 //! type when the same options (either explicitly or implicitly) are used.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
@@ -288,7 +300,13 @@
 {
    /// @cond
    typedef typename pack_options
- < hook_defaults, O1, O2, O3, O4>::type packed_options;
+ < hook_defaults,
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type packed_options;
 
    typedef detail::generic_hook
    < get_uset_node_algo< typename packed_options::void_pointer
@@ -318,15 +336,21 @@
 //!
 //! \c store_hash<> will tell the hook to store the hash of the value
 //! to speed up rehashings.
-#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
 template<class ...Options>
 #else
 template<class O1, class O2, class O3, class O4>
 #endif
 class unordered_set_member_hook
- : public make_unordered_set_member_hook<O1, O2, O3, O4>::type
+ : public make_unordered_set_member_hook<
+ #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+ O1, O2, O3, O4
+ #else
+ Options...
+ #endif
+ >::type
 {
- #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    //! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
    //! initializes the node to an unlinked state.
    //!


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk