Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r50332 - in branches/release/boost: interprocess interprocess/containers interprocess/containers/detail interprocess/detail interprocess/ipc interprocess/smart_ptr interprocess/sync interprocess/sync/emulation intrusive intrusive/detail
From: igaztanaga_at_[hidden]
Date: 2008-12-20 14:50:21


Author: igaztanaga
Date: 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
New Revision: 50332
URL: http://svn.boost.org/trac/boost/changeset/50332

Log:
Merge from trunk for 1.38
Added:
   branches/release/boost/intrusive/detail/clear_on_destructor_base.hpp
      - copied unchanged from r50331, /trunk/boost/intrusive/detail/clear_on_destructor_base.hpp
   branches/release/boost/intrusive/priority_compare.hpp
      - copied unchanged from r50331, /trunk/boost/intrusive/priority_compare.hpp
   branches/release/boost/intrusive/treap.hpp
      - copied unchanged from r50331, /trunk/boost/intrusive/treap.hpp
   branches/release/boost/intrusive/treap_algorithms.hpp
      - copied unchanged from r50331, /trunk/boost/intrusive/treap_algorithms.hpp
   branches/release/boost/intrusive/treap_set.hpp
      - copied unchanged from r50331, /trunk/boost/intrusive/treap_set.hpp
Text files modified:
   branches/release/boost/interprocess/containers/deque.hpp | 71 ++++++++++----
   branches/release/boost/interprocess/containers/detail/flat_tree.hpp | 14 +-
   branches/release/boost/interprocess/containers/detail/node_alloc_holder.hpp | 55 ++++++-----
   branches/release/boost/interprocess/containers/detail/tree.hpp | 36 +++---
   branches/release/boost/interprocess/containers/flat_map.hpp | 136 ++++++++++++++--------------
   branches/release/boost/interprocess/containers/flat_set.hpp | 100 ++++++++-------------
   branches/release/boost/interprocess/containers/list.hpp | 140 ++++++++++++++---------------
   branches/release/boost/interprocess/containers/map.hpp | 160 +++++++++++++--------------------
   branches/release/boost/interprocess/containers/set.hpp | 100 ++++++++-------------
   branches/release/boost/interprocess/containers/slist.hpp | 149 +++++++++++++++++++------------
   branches/release/boost/interprocess/containers/string.hpp | 79 ++++++++--------
   branches/release/boost/interprocess/containers/vector.hpp | 74 ++++++---------
   branches/release/boost/interprocess/detail/os_thread_functions.hpp | 60 +++++++++++-
   branches/release/boost/interprocess/detail/segment_manager_helper.hpp | 2
   branches/release/boost/interprocess/detail/utilities.hpp | 18 +-
   branches/release/boost/interprocess/file_mapping.hpp | 64 +++++++-----
   branches/release/boost/interprocess/ipc/message_queue.hpp | 14 ++
   branches/release/boost/interprocess/managed_external_buffer.hpp | 39 ++++---
   branches/release/boost/interprocess/managed_heap_memory.hpp | 34 ++++--
   branches/release/boost/interprocess/managed_mapped_file.hpp | 32 ++++--
   branches/release/boost/interprocess/managed_shared_memory.hpp | 34 ++++--
   branches/release/boost/interprocess/managed_windows_shared_memory.hpp | 25 +++-
   branches/release/boost/interprocess/mapped_region.hpp | 33 +++++-
   branches/release/boost/interprocess/shared_memory_object.hpp | 17 ++
   branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp | 4
   branches/release/boost/interprocess/smart_ptr/unique_ptr.hpp | 10 +-
   branches/release/boost/interprocess/sync/emulation/interprocess_recursive_mutex.hpp | 18 +-
   branches/release/boost/interprocess/sync/file_lock.hpp | 69 ++++++++++++++
   branches/release/boost/interprocess/sync/interprocess_recursive_mutex.hpp | 6
   branches/release/boost/interprocess/sync/lock_options.hpp | 20 +--
   branches/release/boost/interprocess/sync/scoped_lock.hpp | 29 +++---
   branches/release/boost/interprocess/sync/sharable_lock.hpp | 16 +-
   branches/release/boost/interprocess/sync/upgradable_lock.hpp | 20 ++--
   branches/release/boost/interprocess/windows_shared_memory.hpp | 11 -
   branches/release/boost/intrusive/any_hook.hpp | 4
   branches/release/boost/intrusive/avl_set.hpp | 63 +++++++++---
   branches/release/boost/intrusive/avl_set_hook.hpp | 2
   branches/release/boost/intrusive/avltree.hpp | 169 ++++++++++++++++++++++++++++-------
   branches/release/boost/intrusive/bs_set_hook.hpp | 2
   branches/release/boost/intrusive/circular_list_algorithms.hpp | 2
   branches/release/boost/intrusive/circular_slist_algorithms.hpp | 2
   branches/release/boost/intrusive/derivation_value_traits.hpp | 2
   branches/release/boost/intrusive/detail/assert.hpp | 2
   branches/release/boost/intrusive/detail/config_begin.hpp | 4
   branches/release/boost/intrusive/detail/config_end.hpp | 2
   branches/release/boost/intrusive/detail/ebo_functor_holder.hpp | 2
   branches/release/boost/intrusive/detail/generic_hook.hpp | 2
   branches/release/boost/intrusive/detail/hashtable_node.hpp | 2
   branches/release/boost/intrusive/detail/list_node.hpp | 2
   branches/release/boost/intrusive/detail/mpl.hpp | 4
   branches/release/boost/intrusive/detail/parent_from_member.hpp | 2
   branches/release/boost/intrusive/detail/rbtree_node.hpp | 2
   branches/release/boost/intrusive/detail/slist_node.hpp | 2
   branches/release/boost/intrusive/detail/transform_iterator.hpp | 2
   branches/release/boost/intrusive/detail/tree_algorithms.hpp | 162 +++++++++++++++++----------------
   branches/release/boost/intrusive/detail/tree_node.hpp | 3
   branches/release/boost/intrusive/detail/utilities.hpp | 13 +
   branches/release/boost/intrusive/hashtable.hpp | 41 +++++++
   branches/release/boost/intrusive/intrusive_fwd.hpp | 47 +++++++++
   branches/release/boost/intrusive/linear_slist_algorithms.hpp | 2
   branches/release/boost/intrusive/link_mode.hpp | 2
   branches/release/boost/intrusive/list.hpp | 17 ++-
   branches/release/boost/intrusive/list_hook.hpp | 2
   branches/release/boost/intrusive/member_value_traits.hpp | 2
   branches/release/boost/intrusive/options.hpp | 16 +++
   branches/release/boost/intrusive/pointer_plus_bits.hpp | 2
   branches/release/boost/intrusive/rbtree.hpp | 186 ++++++++++++++++++++++++++++++---------
   branches/release/boost/intrusive/rbtree_algorithms.hpp | 2
   branches/release/boost/intrusive/set.hpp | 59 +++++++++---
   branches/release/boost/intrusive/set_hook.hpp | 2
   branches/release/boost/intrusive/sg_set.hpp | 59 +++++++++---
   branches/release/boost/intrusive/sgtree.hpp | 160 +++++++++++++++++++++++++++-------
   branches/release/boost/intrusive/slist.hpp | 13 ++
   branches/release/boost/intrusive/slist_hook.hpp | 2
   branches/release/boost/intrusive/splay_set.hpp | 59 +++++++++---
   branches/release/boost/intrusive/splay_set_hook.hpp | 2
   branches/release/boost/intrusive/splaytree.hpp | 172 ++++++++++++++++++++++++++++--------
   branches/release/boost/intrusive/trivial_value_traits.hpp | 2
   branches/release/boost/intrusive/unordered_set.hpp | 18 +++
   branches/release/boost/intrusive/unordered_set_hook.hpp | 2
   80 files changed, 1893 insertions(+), 1117 deletions(-)

Modified: branches/release/boost/interprocess/containers/deque.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/deque.hpp (original)
+++ branches/release/boost/interprocess/containers/deque.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -215,6 +215,9 @@
 
       difference_type operator-(const self_t& x) const
       {
+ if(!this->m_cur && !x.m_cur){
+ return 0;
+ }
          return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
             (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
       }
@@ -459,7 +462,7 @@
       members_holder(const allocator_type &a)
          : map_allocator_type(a), allocator_type(a)
          , m_map(0), m_map_size(0)
- , m_start(), m_finish()
+ , m_start(), m_finish(m_start)
       {}
 
       ptr_alloc_ptr m_map;
@@ -610,11 +613,16 @@
    {}
 
    deque(const deque& x)
- : Base(x.alloc(), x.size())
- { std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start); }
+ : Base(x.alloc())
+ {
+ if(x.size()){
+ this->priv_initialize_map(x.size());
+ std::uninitialized_copy(x.begin(), x.end(), this->members_.m_start);
+ }
+ }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- deque(const detail::moved_object<deque> &mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ deque(detail::moved_object<deque> mx)
       : Base(mx.get().alloc())
    { this->swap(mx.get()); }
    #else
@@ -661,8 +669,8 @@
       return *this;
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- deque& operator= (const detail::moved_object<deque> &mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ deque& operator= (detail::moved_object<deque> mx)
    {
       deque &x = mx.get();
    #else
@@ -674,7 +682,9 @@
       return *this;
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<deque> x)
+ { this->swap(x.get()); }
    void swap(deque& x)
    #else
    void swap(deque &&x)
@@ -686,11 +696,6 @@
       std::swap(this->members_.m_map_size, x.members_.m_map_size);
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<deque> &mx)
- { this->swap(mx.get()); }
- #endif
-
    void assign(size_type n, const T& val)
    { this->priv_fill_assign(n, val); }
 
@@ -714,8 +719,8 @@
       }
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void push_back(const detail::moved_object<value_type> &mt)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void push_back(detail::moved_object<value_type> mt)
    {
       value_type &t = mt.get();
    #else
@@ -742,8 +747,8 @@
       }
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void push_front(const detail::moved_object<value_type> &mt)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void push_front(detail::moved_object<value_type> mt)
    {
       value_type &t = mt.get();
    #else
@@ -796,8 +801,8 @@
       }
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator position, const detail::moved_object<value_type> &m)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, detail::moved_object<value_type> m)
    {
       value_type &mx = m.get();
    #else
@@ -1487,12 +1492,34 @@
                        const deque<T, Alloc>& y)
    { return !(x < y); }
 
-template <class T, class Alloc>
-inline void swap(deque<T,Alloc>& x, deque<T,Alloc>& y)
- { x.swap(y); }
+
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+template <class T, class A>
+inline void swap(deque<T, A>& x, deque<T, A>& y)
+{ x.swap(y); }
+
+template <class T, class A>
+inline void swap(detail::moved_object<deque<T, A> > x, deque<T, A>& y)
+{ x.get().swap(y); }
+
+template <class T, class A>
+inline void swap(deque<T, A> &x, detail::moved_object<deque<T, A> > y)
+{ x.swap(y.get()); }
+#else
+template <class T, class A>
+inline void swap(deque<T, A>&&x, deque<T, A>&&y)
+{ x.swap(y); }
+#endif
 
 /// @cond
 
+//!This class is movable
+template <class T, class A>
+struct is_movable<deque<T, A> >
+{
+ enum { value = true };
+};
+
 //!has_trivial_destructor_after_move<> == true_type
 //!specialization for optimizations
 template <class T, class A>

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -134,7 +134,7 @@
    { }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_tree(const detail::moved_object<flat_tree> &x)
+ flat_tree(detail::moved_object<flat_tree> x)
       : m_data(detail::move_impl(x.get().m_data))
    { }
    #else
@@ -150,7 +150,7 @@
    { m_data = x.m_data; return *this; }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_tree& operator=(const detail::moved_object<flat_tree>& mx)
+ flat_tree& operator=(detail::moved_object<flat_tree> mx)
    { m_data = detail::move_impl(mx.get().m_data); return *this; }
    #else
    flat_tree& operator=(flat_tree &&mx)
@@ -227,7 +227,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<flat_tree>& other)
+ void swap(detail::moved_object<flat_tree> other)
    { this->swap(other.get()); }
    #else
    void swap(flat_tree &&other)
@@ -247,7 +247,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert_unique(const detail::moved_object<value_type>& mval)
+ std::pair<iterator,bool> insert_unique(detail::moved_object<value_type> mval)
    {
       value_type &val = mval.get();
    #else
@@ -271,7 +271,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_equal(const detail::moved_object<value_type>& mval)
+ iterator insert_equal(detail::moved_object<value_type> mval)
    {
       iterator i = this->upper_bound(KeyOfValue()(mval.get()));
       i = this->m_data.m_vect.insert(i, mval);
@@ -297,7 +297,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_unique(const_iterator pos, const detail::moved_object<value_type>& mval)
+ iterator insert_unique(const_iterator pos, detail::moved_object<value_type> mval)
    {
       insert_commit_data data;
       std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval.get(), data);
@@ -326,7 +326,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_equal(const_iterator pos, const detail::moved_object<value_type>& mval)
+ iterator insert_equal(const_iterator pos, detail::moved_object<value_type> mval)
    {
       insert_commit_data data;
       priv_insert_equal_prepare(pos, mval.get(), data);

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -87,7 +87,7 @@
    {}
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- node_alloc_holder(const detail::moved_object<node_alloc_holder> &other)
+ node_alloc_holder(detail::moved_object<node_alloc_holder> other)
       : members_(detail::move_impl(other.get().node_alloc()))
    { this->swap(other.get()); }
    #else
@@ -103,7 +103,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Pred>
- node_alloc_holder(const detail::moved_object<ValAlloc> &a, const Pred &c)
+ node_alloc_holder(detail::moved_object<ValAlloc> a, const Pred &c)
       : members_(a.get(), typename ICont::value_compare(c))
    {}
    #else
@@ -119,7 +119,7 @@
    {}
 
    ~node_alloc_holder()
- {}
+ { this->clear(alloc_version()); }
 
    size_type max_size() const
    { return this->node_alloc().max_size(); }
@@ -144,7 +144,7 @@
 
    #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, detail::moved_object<std::pair<Convertible1, Convertible2> > value)
    {
       typedef typename Node::hook_type hook_type;
       typedef typename Node::value_type::first_type first_type;
@@ -297,33 +297,36 @@
    FwdIterator allocate_many_and_construct
       (FwdIterator beg, difference_type n, Inserter inserter)
    {
- typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
+ if(n){
+ typedef typename NodeAlloc::multiallocation_iterator multiallocation_iterator;
 
- //Try to allocate memory in a single block
- multiallocation_iterator itbeg =
- this->node_alloc().allocate_individual(n), itend, itold;
- int constructed = 0;
- Node *p = 0;
- BOOST_TRY{
- for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
- p = &*itbeg;
- ++itbeg;
- //This can throw
- boost::interprocess::construct_in_place(p, beg);
- ++constructed;
- //This can throw in some containers (predicate might throw)
- inserter(*p);
+ //Try to allocate memory in a single block
+ multiallocation_iterator itbeg =
+ this->node_alloc().allocate_individual(n), itend, itold;
+ int constructed = 0;
+ Node *p = 0;
+ BOOST_TRY{
+ for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
+ p = &*itbeg;
+ ++itbeg;
+ //This can throw
+ boost::interprocess::construct_in_place(p, beg);
+ ++constructed;
+ //This can throw in some containers (predicate might throw)
+ inserter(*p);
+ }
          }
- }
- BOOST_CATCH(...){
- if(constructed){
- this->destroy(p);
+ BOOST_CATCH(...){
+ if(constructed){
+ this->destroy(p);
+ }
+ this->node_alloc().deallocate_many(itbeg);
+ BOOST_RETHROW
          }
- this->node_alloc().deallocate_many(itbeg);
- BOOST_RETHROW
+ BOOST_CATCH_END
       }
- BOOST_CATCH_END
       return beg;
+
    }
 
    void clear(allocator_v1)

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -451,7 +451,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- rbtree(const detail::moved_object<rbtree>& x)
+ rbtree(detail::moved_object<rbtree> x)
       : AllocHolder(x.get(), x.get().key_comp())
    { this->swap(x.get()); }
    #else
@@ -461,7 +461,7 @@
    #endif
 
    ~rbtree()
- { this->clear(); }
+ {} //AllocHolder clears the tree
 
    rbtree& operator=(const rbtree& x)
    {
@@ -489,7 +489,7 @@
    }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- rbtree& operator=(const detail::moved_object<rbtree>& mx)
+ rbtree& operator=(detail::moved_object<rbtree> mx)
    { this->clear(); this->swap(mx.get()); return *this; }
    #else
    rbtree& operator=(rbtree &&mx)
@@ -584,7 +584,7 @@
    { AllocHolder::swap(x); }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<rbtree>& mt)
+ void swap(detail::moved_object<rbtree> mt)
    { this->swap(mt.get()); }
    #else
    void swap(rbtree &&mt)
@@ -622,7 +622,7 @@
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class MovableConvertible>
    iterator insert_unique_commit
- (const detail::moved_object<MovableConvertible>& mv, insert_commit_data &data)
+ (detail::moved_object<MovableConvertible> mv, insert_commit_data &data)
    {
       NodePtr tmp = AllocHolder::create_node(mv);
       iiterator it(this->icont().insert_unique_commit(*tmp, data));
@@ -652,8 +652,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class MovableConvertible>
- std::pair<iterator,bool> insert_unique
- (const detail::moved_object<MovableConvertible>& mv)
+ std::pair<iterator,bool> insert_unique(detail::moved_object<MovableConvertible> mv)
    {
       insert_commit_data data;
       std::pair<iterator,bool> ret =
@@ -796,8 +795,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class MovableConvertible>
- iterator insert_unique
- (const_iterator hint, const detail::moved_object<MovableConvertible> &mv)
+ iterator insert_unique(const_iterator hint, detail::moved_object<MovableConvertible> mv)
    {
       insert_commit_data data;
       std::pair<iterator,bool> ret =
@@ -844,7 +842,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class MovableConvertible>
- iterator insert_equal(const detail::moved_object<MovableConvertible> &mv)
+ iterator insert_equal(detail::moved_object<MovableConvertible> mv)
    {
       NodePtr p(AllocHolder::create_node(mv));
       return iterator(this->icont().insert_equal(this->icont().end(), *p));
@@ -866,7 +864,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class MovableConvertible>
- iterator insert_equal(const_iterator hint, const detail::moved_object<MovableConvertible> &mv)
+ iterator insert_equal(const_iterator hint, detail::moved_object<MovableConvertible> mv)
    {
       NodePtr p(AllocHolder::create_node(mv));
       return iterator(this->icont().insert_equal(hint.get(), *p));
@@ -993,13 +991,15 @@
    void priv_create_and_insert_nodes
       (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
    {
- if(unique){
- priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
- }
- else{
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont()));
+ if(beg != end){
+ if(unique){
+ priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
+ }
+ else{
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont()));
+ }
       }
    }
 };

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -22,6 +22,7 @@
 #include <utility>
 #include <functional>
 #include <memory>
+#include <stdexcept>
 #include <boost/interprocess/containers/detail/flat_tree.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
@@ -171,8 +172,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_map(const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_map(detail::moved_object<flat_map<Key,T,Pred,Alloc> > x)
       : m_flat_tree(detail::move_impl(x.get().m_flat_tree)) {}
 
    #else
@@ -192,8 +193,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_map<Key,T,Pred,Alloc>& operator=(const detail::moved_object<flat_map<Key, T, Pred, Alloc> >& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_map<Key,T,Pred,Alloc>& operator=(detail::moved_object<flat_map<Key, T, Pred, Alloc> > mx)
       { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
    #else
    flat_map<Key,T,Pred,Alloc>& operator=(flat_map<Key, T, Pred, Alloc> && mx)
@@ -354,13 +355,6 @@
       { return m_flat_tree.max_size(); }
 
    //! Effects: If there is no key equivalent to x in the flat_map, inserts
- //! value_type(detail::move_impl(x), T()) into the flat_map (the key is move-constructed)
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- //! Effects: If there is no key equivalent to x in the flat_map, inserts
    //! value_type(x, T()) into the flat_map.
    //!
    //! Returns: A reference to the mapped_type corresponding to x in *this.
@@ -375,7 +369,14 @@
       return (*i).second;
    }
 
- T &operator[](const detail::moved_object<key_type>& mk)
+ //! Effects: If there is no key equivalent to x in the flat_map, inserts
+ //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
+ //!
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
+ //!
+ //! Complexity: Logarithmic.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ T &operator[](detail::moved_object<key_type> mk)
    {
       key_type &k = mk.get();
       iterator i = lower_bound(k);
@@ -385,12 +386,6 @@
       return (*i).second;
    }
    #else
- //! Effects: If there is no key equivalent to x in the flat_map, inserts
- //! value_type(x, T()) into the flat_map.
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
    T &operator[](key_type &&mk)
    {
       key_type &k = mk;
@@ -402,14 +397,29 @@
    }
    #endif
 
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- void swap(flat_map<Key,T,Pred,Alloc>& x)
- { m_flat_tree.swap(x.m_flat_tree); }
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ T& at(const key_type& k)
+ {
+ iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ const T& at(const key_type& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
 
    //! <b>Effects</b>: Swaps the contents of *this and x.
    //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
@@ -417,13 +427,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& x)
- { m_flat_tree.swap(x.get().m_flat_tree); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<flat_map> x)
+ { this->swap(x.get()); }
+ void swap(flat_map& x)
    #else
- void swap(flat_map<Key,T,Pred,Alloc> && x)
- { m_flat_tree.swap(x.m_flat_tree); }
+ void swap(flat_map &&x)
    #endif
+ { m_flat_tree.swap(x.m_flat_tree); }
 
    //! <b>Effects</b>: Inserts x if and only if there is no element in the container
    //! with key equivalent to the key of x.
@@ -451,8 +462,8 @@
    //! to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
       { return force<std::pair<iterator,bool> >(
          m_flat_tree.insert_unique(force<impl_moved_value_type>(x))); }
    #else
@@ -485,8 +496,8 @@
    //! 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.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, 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
@@ -742,20 +753,20 @@
                        const flat_map<Key,T,Pred,Alloc>& y)
    { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class Key, class T, class Pred, class Alloc>
 inline void swap(flat_map<Key,T,Pred,Alloc>& x,
                  flat_map<Key,T,Pred,Alloc>& y)
    { x.swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& x,
+inline void swap(detail::moved_object<flat_map<Key,T,Pred,Alloc> > x,
                  flat_map<Key,T,Pred,Alloc>& y)
    { x.get().swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
 inline void swap(flat_map<Key,T,Pred,Alloc>& x,
- const detail::moved_object<flat_map<Key,T,Pred,Alloc> >& y)
+ detail::moved_object<flat_map<Key,T,Pred,Alloc> > y)
    { x.swap(y.get()); }
 #else
 template <class Key, class T, class Pred, class Alloc>
@@ -916,8 +927,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_multimap(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_multimap(detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > x)
       : m_flat_tree(detail::move_impl(x.get().m_flat_tree)) { }
    #else
    flat_multimap(flat_multimap<Key,T,Pred,Alloc> && x)
@@ -927,20 +938,17 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- flat_multimap<Key,T,Pred,Alloc>&
- operator=(const flat_multimap<Key,T,Pred,Alloc>& x)
+ flat_multimap<Key,T,Pred,Alloc>& operator=(const flat_multimap<Key,T,Pred,Alloc>& x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
    //! <b>Effects</b>: this->swap(x.get()).
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_multimap<Key,T,Pred,Alloc>&
- operator=(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_multimap<Key,T,Pred,Alloc>& operator=(detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > mx)
       { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
    #else
- flat_multimap<Key,T,Pred,Alloc>&
- operator=(flat_multimap<Key,T,Pred,Alloc> && mx)
+ flat_multimap<Key,T,Pred,Alloc>& operator=(flat_multimap<Key,T,Pred,Alloc> && mx)
       { m_flat_tree = detail::move_impl(mx.m_flat_tree); return *this; }
    #endif
 
@@ -1069,22 +1077,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- void swap(flat_multimap<Key,T,Pred,Alloc>& x)
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& x)
- { m_flat_tree.swap(x.get().m_flat_tree); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<flat_multimap> x)
+ { this->swap(x.get()); }
+ void swap(flat_multimap& x)
    #else
- void swap(flat_multimap<Key,T,Pred,Alloc> && x)
- { m_flat_tree.swap(x.m_flat_tree); }
+ void swap(flat_multimap &&x)
    #endif
+ { m_flat_tree.swap(x.m_flat_tree); }
 
    //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
    //! newly inserted element.
@@ -1103,8 +1103,8 @@
    //! to the elements with bigger keys than x.
    //!
    //! <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)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(detail::moved_object<value_type> x)
       { return force_copy<iterator>(m_flat_tree.insert_equal(force<impl_moved_value_type>(x))); }
    #else
    iterator insert(value_type &&x)
@@ -1136,8 +1136,8 @@
    //! to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, 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(const_iterator position, value_type &&x)
@@ -1391,21 +1391,21 @@
                        const flat_multimap<Key,T,Pred,Alloc>& y)
    { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class Key, class T, class Pred, class Alloc>
 inline void swap(flat_multimap<Key,T,Pred,Alloc>& x,
                  flat_multimap<Key,T,Pred,Alloc>& y)
    { x.swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> >& x,
+inline void swap(detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > x,
                  flat_multimap<Key,T,Pred,Alloc>& y)
    { x.get().swap(y); }
 
 
 template <class Key, class T, class Pred, class Alloc>
 inline void swap(flat_multimap<Key,T,Pred,Alloc>& x,
- const detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > & y)
+ detail::moved_object<flat_multimap<Key,T,Pred,Alloc> > y)
    { x.swap(y.get()); }
 #else
 template <class Key, class T, class Pred, class Alloc>

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -115,8 +115,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_set(const detail::moved_object<flat_set<T,Pred,Alloc> >& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_set(detail::moved_object<flat_set<T,Pred,Alloc> > mx)
       : m_flat_tree(detail::move_impl(mx.get().m_flat_tree)) {}
    #else
    flat_set(flat_set<T,Pred,Alloc> && mx)
@@ -132,8 +132,8 @@
    //! <b>Effects</b>: Makes *this a copy of x.
    //!
    //! <b>Complexity</b>: Linear in x.size().
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_set<T,Pred,Alloc>& operator=(const detail::moved_object<flat_set<T, Pred, Alloc> > &mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_set<T,Pred,Alloc>& operator=(detail::moved_object<flat_set<T, Pred, Alloc> > mx)
       { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
 
    #else
@@ -301,22 +301,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- void swap(flat_set<T,Pred,Alloc>& x)
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object <flat_set<T,Pred,Alloc> >& mx)
- { this->swap(mx.get()); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<flat_set> x)
+ { this->swap(x.get()); }
+ void swap(flat_set& x)
    #else
- void swap(flat_set<T,Pred,Alloc> && mx)
- { this->swap(mx); }
+ void swap(flat_set &&x)
    #endif
+ { m_flat_tree.swap(x.m_flat_tree); }
 
    //! <b>Effects</b>: Inserts x if and only if there is no element in the container
    //! with key equivalent to the key of x.
@@ -343,8 +335,8 @@
    //! to the elements with bigger keys than x.
    //!
    //! <b>Note</b>: If an element it's inserted it might invalidate elements.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
       { return m_flat_tree.insert_unique(x); }
    #else
    std::pair<iterator,bool> insert(value_type && x)
@@ -374,8 +366,8 @@
    //! 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.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, detail::moved_object<value_type> x)
       { return m_flat_tree.insert_unique(position, x); }
    #else
    iterator insert(const_iterator position, value_type && x)
@@ -623,25 +615,21 @@
                        const flat_set<T,Pred,Alloc>& y)
    { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class Pred, class Alloc>
-inline void swap(flat_set<T,Pred,Alloc>& x,
- flat_set<T,Pred,Alloc>& y)
+inline void swap(flat_set<T,Pred,Alloc>& x, flat_set<T,Pred,Alloc>& y)
    { x.swap(y); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(const detail::moved_object<flat_set<T,Pred,Alloc> >& x,
- flat_set<T,Pred,Alloc>& y)
+inline void swap(detail::moved_object<flat_set<T,Pred,Alloc> > x, flat_set<T,Pred,Alloc>& y)
    { x.get().swap(y); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(flat_set<T,Pred,Alloc>& x,
- const detail::moved_object<flat_set<T,Pred,Alloc> >& y)
+inline void swap(flat_set<T,Pred,Alloc>& x, detail::moved_object<flat_set<T,Pred,Alloc> > y)
    { x.swap(y.get()); }
 #else
 template <class T, class Pred, class Alloc>
-inline void swap(flat_set<T,Pred,Alloc>&&x,
- flat_set<T,Pred,Alloc>&&y)
+inline void swap(flat_set<T,Pred,Alloc>&&x, flat_set<T,Pred,Alloc>&&y)
    { x.swap(y); }
 #endif
 
@@ -732,8 +720,8 @@
    flat_multiset(const flat_multiset<T,Pred,Alloc>& x)
       : m_flat_tree(x.m_flat_tree) {}
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_multiset(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_multiset(detail::moved_object<flat_multiset<T,Pred,Alloc> > x)
       : m_flat_tree(detail::move_impl(x.get().m_flat_tree)) {}
    #else
    flat_multiset(flat_multiset<T,Pred,Alloc> && x)
@@ -743,8 +731,8 @@
    flat_multiset<T,Pred,Alloc>& operator=(const flat_multiset<T,Pred,Alloc>& x)
       { m_flat_tree = x.m_flat_tree; return *this; }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- flat_multiset<T,Pred,Alloc>& operator=(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ flat_multiset<T,Pred,Alloc>& operator=(detail::moved_object<flat_multiset<T,Pred,Alloc> > mx)
       { m_flat_tree = detail::move_impl(mx.get().m_flat_tree); return *this; }
    #else
    flat_multiset<T,Pred,Alloc>& operator=(flat_multiset<T,Pred,Alloc> && mx)
@@ -910,22 +898,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- void swap(flat_multiset<T,Pred,Alloc>& x)
- { m_flat_tree.swap(x.m_flat_tree); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& mx)
- { this->swap(mx.get()); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<flat_multiset> x)
+ { this->swap(x.get()); }
+ void swap(flat_multiset& x)
    #else
- void swap(flat_multiset<T,Pred,Alloc> && mx)
- { this->swap(mx); }
+ void swap(flat_multiset &&x)
    #endif
+ { m_flat_tree.swap(x.m_flat_tree); }
 
    //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
    //! newly inserted element.
@@ -944,8 +924,8 @@
    //! to the elements with bigger keys than x.
    //!
    //! <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)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(detail::moved_object<value_type> x)
       { return m_flat_tree.insert_equal(x); }
    #else
    iterator insert(value_type && x)
@@ -975,8 +955,8 @@
    //! 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.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator position, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, detail::moved_object<value_type> x)
       { return m_flat_tree.insert_equal(position, x); }
    #else
    iterator insert(const_iterator position, value_type && x)
@@ -1219,25 +1199,21 @@
                        const flat_multiset<T,Pred,Alloc>& y)
 { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class Pred, class Alloc>
-inline void swap(flat_multiset<T,Pred,Alloc>& x,
- flat_multiset<T,Pred,Alloc>& y)
+inline void swap(flat_multiset<T,Pred,Alloc>& x, flat_multiset<T,Pred,Alloc>& y)
    { x.swap(y); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(const detail::moved_object<flat_multiset<T,Pred,Alloc> >& x,
- flat_multiset<T,Pred,Alloc>& y)
+inline void swap(detail::moved_object<flat_multiset<T,Pred,Alloc> > x, flat_multiset<T,Pred,Alloc>& y)
    { x.get().swap(y); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(flat_multiset<T,Pred,Alloc>& x,
- const detail::moved_object<flat_multiset<T,Pred,Alloc> >& y)
+inline void swap(flat_multiset<T,Pred,Alloc>& x, detail::moved_object<flat_multiset<T,Pred,Alloc> > y)
    { x.swap(y.get()); }
 #else
 template <class T, class Pred, class Alloc>
-inline void swap(flat_multiset<T,Pred,Alloc>&&x,
- flat_multiset<T,Pred,Alloc>&&y)
+inline void swap(flat_multiset<T,Pred,Alloc>&&x, flat_multiset<T,Pred,Alloc>&&y)
    { x.swap(y); }
 #endif
 

Modified: branches/release/boost/interprocess/containers/list.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/list.hpp (original)
+++ branches/release/boost/interprocess/containers/list.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -153,9 +153,9 @@
    /// @cond
    typedef typename
       detail::intrusive_list_type<A>::type Icont;
+ typedef list <T, A> ThisType;
    typedef detail::node_alloc_holder<A, Icont> AllocHolder;
    typedef typename AllocHolder::NodePtr NodePtr;
- typedef list <T, A> ThisType;
    typedef typename AllocHolder::NodeAlloc NodeAlloc;
    typedef typename AllocHolder::ValAlloc ValAlloc;
    typedef typename AllocHolder::Node Node;
@@ -365,11 +365,11 @@
 
    //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
    //!
- //! <b>Throws</b>: If allocator_type's default constructor throws.
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- list(const detail::moved_object<list> &x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ list(detail::moved_object<list> x)
       : AllocHolder(detail::move_impl((AllocHolder&)x.get()))
    {}
    #else
@@ -396,8 +396,8 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements.
- ~list()
- { this->clear(); }
+ ~list()
+ {} //AllocHolder clears the list
 
    //! <b>Effects</b>: Returns a copy of the internal allocator.
    //!
@@ -562,8 +562,8 @@
    //! <b>Throws</b>: If memory allocation throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void push_front(const detail::moved_object<T>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void push_front(detail::moved_object<T> x)
    { this->insert(this->cbegin(), x); }
    #else
    void push_front(T &&x)
@@ -583,8 +583,8 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void push_back (const detail::moved_object<T>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void push_back (detail::moved_object<T> x)
    { this->insert(this->cend(), x); }
    #else
    void push_back (T &&x)
@@ -715,19 +715,15 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<ThisType> x)
+ { this->swap(x.get()); }
    void swap(ThisType& x)
+ #else
+ void swap(ThisType &&x)
+ #endif
    { AllocHolder::swap(x); }
 
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type()
- //! allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- //void swap(const detail::moved_object<ThisType>& x)
- //{ this->swap(x.get()); }
-
    //! <b>Effects</b>: Makes *this contain the same elements as x.
    //!
    //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
@@ -752,8 +748,8 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- ThisType& operator=(const detail::moved_object<ThisType>& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ ThisType& operator=(detail::moved_object<ThisType> mx)
    {
       this->clear();
       this->swap(mx.get());
@@ -814,8 +810,8 @@
    //! <b>Throws</b>: If memory allocation throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator p, const detail::moved_object<T>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator p, detail::moved_object<T> x)
    {
       NodePtr tmp = AllocHolder::create_node(x);
       return iterator(this->icont().insert(p.get(), *tmp));
@@ -973,7 +969,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //! this list. Iterators of this list and all the references are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(iterator p, detail::moved_object<ThisType> x)
+ { this->splice(p, x.get()); }
    void splice(iterator p, ThisType& x)
+ #else
+ void splice(iterator p, ThisType&& x)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont());
@@ -983,9 +985,6 @@
       }
    }
 
-// void splice(iterator p, const detail::moved_object<ThisType>& x)
-// { this->splice(p, x.get()); }
-
    //! <b>Requires</b>: p must point to an element contained
    //! by this list. i must point to an element contained in list x.
    //!
@@ -1000,7 +999,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator i)
+ { this->splice(p, x.get(), i); }
    void splice(const_iterator p, ThisType &x, const_iterator i)
+ #else
+ void splice(const_iterator p, ThisType &&x, const_iterator i)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont(), i.get());
@@ -1010,9 +1015,6 @@
       }
    }
 
-// 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
    //! by this list. first and last must point to elements contained in list x.
    //!
@@ -1026,7 +1028,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator first, const_iterator last)
+ { this->splice(p, x.get(), first, last); }
    void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last)
+ #else
+ void splice(const_iterator p, ThisType &&x, const_iterator first, const_iterator last)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont(), first.get(), last.get());
@@ -1036,9 +1044,6 @@
       }
    }
 
-// 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
    //! by this list. first and last must point to elements contained in list x.
    //! n == std::distance(first, last)
@@ -1053,7 +1058,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator first, const_iterator last, size_type n)
+ { this->splice(p, x.get(), first, last, n); }
    void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n)
+ #else
+ void splice(const_iterator p, ThisType &&x, const_iterator first, const_iterator last, size_type n)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
@@ -1063,9 +1074,6 @@
       }
    }
 
-// 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.
    //!
    //! <b>Throws</b>: Nothing.
@@ -1142,23 +1150,15 @@
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void merge(detail::moved_object<list<T, A> > x)
+ { this->merge(x.get()); }
    void merge(list<T, A>& x)
+ #else
+ void merge(list<T, A>&& x)
+ #endif
    { this->merge(x, value_less()); }
 
- //! <b>Effects</b>: This function removes all of moved mx's elements and inserts them
- //! in order into *this according to std::less<value_type>. The merge is stable;
- //! that is, if an element from *this is equivalent to one from x, then the element
- //! from *this will precede the one from x.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time: it performs at most
- //! size() + x.size() - 1 comparisons.
- //!
- //! <b>Note</b>: Iterators and references to *this are not invalidated.
- //void merge(const detail::moved_object<list<T, A> >& x)
- //{ this->merge(x.get()); }
-
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
    //! ordering and both *this and x must be sorted according to that ordering
    //! The lists x and *this must be distinct.
@@ -1173,8 +1173,16 @@
    //! size() + x.size() - 1 comparisons.
    //!
    //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ template <class StrictWeakOrdering>
+ void merge(detail::moved_object<list<T, A> > x, StrictWeakOrdering comp)
+ { this->merge(x.get(), comp); }
    template <class StrictWeakOrdering>
    void merge(list<T, A>& x, StrictWeakOrdering comp)
+ #else
+ template <class StrictWeakOrdering>
+ void merge(list<T, A>&& x, StrictWeakOrdering comp)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().merge(x.icont(),
@@ -1185,24 +1193,6 @@
       }
    }
 
- //! <b>Requires</b>: p must be a comparison function that induces a strict weak
- //! ordering and both *this and x must be sorted according to that ordering
- //! The lists x and *this must be distinct.
- //!
- //! <b>Effects</b>: This function removes all of moved mx's elements and inserts them
- //! in order into *this. The merge is stable; that is, if an element from *this is
- //! equivalent to one from x, then the element from *this will precede the one from x.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time: it performs at most
- //! size() + x.size() - 1 comparisons.
- //!
- //! <b>Note</b>: Iterators and references to *this are not invalidated.
- //template <class StrictWeakOrdering>
- //void merge(const detail::moved_object<list<T, A> >& x, StrictWeakOrdering comp)
- //{ return this->merge(x.get(), comp); }
-
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
@@ -1283,9 +1273,11 @@
    void priv_create_and_insert_nodes
       (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
    {
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
+ if(beg != end){
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
+ }
    }
 
    //Default constructed version
@@ -1410,7 +1402,7 @@
   return !(x < y);
 }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class A>
 inline void swap(list<T, A>& x, list<T, A>& y)
 {
@@ -1418,13 +1410,13 @@
 }
 
 template <class T, class A>
-inline void swap(const detail::moved_object<list<T, A> >& x, list<T, A>& y)
+inline void swap(detail::moved_object<list<T, A> >& x, list<T, A> y)
 {
   x.get().swap(y);
 }
 
 template <class T, class A>
-inline void swap(list<T, A>& x, const detail::moved_object<list<T, A> >& y)
+inline void swap(list<T, A>& x, detail::moved_object<list<T, A> > y)
 {
   x.swap(y.get());
 }

Modified: branches/release/boost/interprocess/containers/map.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/map.hpp (original)
+++ branches/release/boost/interprocess/containers/map.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -54,6 +54,7 @@
 #include <utility>
 #include <functional>
 #include <memory>
+#include <stdexcept>
 #include <boost/interprocess/containers/detail/tree.hpp>
 #include <boost/type_traits/has_trivial_destructor.hpp>
 #include <boost/interprocess/detail/mpl.hpp>
@@ -164,8 +165,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- map(const detail::moved_object<map<Key,T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ map(detail::moved_object<map<Key,T,Pred,Alloc> > x)
       : m_tree(detail::move_impl(x.get().m_tree))
    {}
    #else
@@ -183,8 +184,8 @@
    //! <b>Effects</b>: this->swap(x.get()).
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- map<Key,T,Pred,Alloc>& operator=(const detail::moved_object<map<Key,T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ map<Key,T,Pred,Alloc>& operator=(detail::moved_object<map<Key,T,Pred,Alloc> > x)
    { m_tree = detail::move_impl(x.get().m_tree); return *this; }
    #else
    map<Key,T,Pred,Alloc>& operator=(map<Key,T,Pred,Alloc> &&x)
@@ -334,8 +335,8 @@
    //! Returns: A reference to the mapped_type corresponding to x in *this.
    //!
    //! Complexity: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- T& operator[](const detail::moved_object<key_type>& mk)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ T& operator[](detail::moved_object<key_type> mk)
    {
       key_type &k = mk.get();
       //we can optimize this
@@ -362,43 +363,29 @@
    }
    #endif
 
-/*
- //! Effects: If there is no key equivalent to x in the map, inserts
- //! value_type(detail::move_impl(x), T()) into the map (the key is move-constructed)
- //!
- //! Returns: A reference to the mapped_type corresponding to x in *this.
- //!
- //! Complexity: Logarithmic.
- T& at(const key_type& x)
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ T& at(const key_type& k)
    {
- if(this->find(x) == this->end()){
-
- }
- key_type &k = mk.get();
- //we can optimize this
- iterator i = lower_bound(k);
- // i->first is greater than or equivalent to k.
- if (i == end() || key_comp()(k, (*i).first)){
- value_type val(k, detail::move_impl(T()));
- i = insert(i, detail::move_impl(val));
+ iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
       }
- return (*i).second;
+ return i->second;
    }
 
-//;
-//const T& at(const key_type& x) const;
-//4 Returns: A reference to the element whose key is equivalent to x.
-//5 Throws: An exception object of type out_of_range if no such element is present.
-*/
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- void swap(map<Key,T,Pred,Alloc>& x)
- { m_tree.swap(x.m_tree); }
+ //! Returns: A reference to the element whose key is equivalent to x.
+ //! Throws: An exception object of type out_of_range if no such element is present.
+ //! Complexity: logarithmic.
+ const T& at(const key_type& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i == this->end()){
+ throw std::out_of_range("key not found");
+ }
+ return i->second;
+ }
 
    //! <b>Effects</b>: Swaps the contents of *this and x.
    //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
@@ -406,13 +393,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<map<Key,T,Pred,Alloc> >& x)
- { m_tree.swap(x.get().m_tree); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<map> x)
+ { this->swap(x.get()); }
+ void swap(map& x)
    #else
- void swap(map<Key,T,Pred,Alloc> &&x)
- { m_tree.swap(x.m_tree); }
+ void swap(map &&x)
    #endif
+ { m_tree.swap(x.m_tree); }
 
    //! <b>Effects</b>: Inserts x if and only if there is no element in the container
    //! with key equivalent to the key of x.
@@ -444,8 +432,8 @@
    //! points to the element with key equivalent to the key of x.
    //!
    //! <b>Complexity</b>: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert(const detail::moved_object<std::pair<key_type, mapped_type> > &x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(detail::moved_object<std::pair<key_type, mapped_type> > x)
    { return m_tree.insert_unique(x); }
    #else
    std::pair<iterator,bool> insert(std::pair<key_type, mapped_type> &&x)
@@ -460,8 +448,8 @@
    //! points to the element with key equivalent to the key of x.
    //!
    //! <b>Complexity</b>: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
    { return m_tree.insert_unique(x); }
    #else
    std::pair<iterator,bool> insert(value_type &&x)
@@ -489,8 +477,8 @@
    //!
    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
    //! is inserted right before p.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<std::pair<key_type, mapped_type> > &x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(iterator position, detail::moved_object<std::pair<key_type, mapped_type> > x)
    { return m_tree.insert_unique(position, x); }
    #else
    iterator insert(iterator position, std::pair<key_type, mapped_type> &&x)
@@ -512,8 +500,8 @@
    //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
    //!
    //! <b>Complexity</b>: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(iterator position, detail::moved_object<value_type> x)
    { return m_tree.insert_unique(position, x); }
    #else
    iterator insert(iterator position, value_type &&x)
@@ -716,25 +704,21 @@
                        const map<Key,T,Pred,Alloc>& y)
    { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(map<Key,T,Pred,Alloc>& x,
- map<Key,T,Pred,Alloc>& y)
+inline void swap(map<Key,T,Pred,Alloc>& x, map<Key,T,Pred,Alloc>& y)
    { x.swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(const detail::moved_object<map<Key,T,Pred,Alloc> >& x,
- map<Key,T,Pred,Alloc>& y)
+inline void swap(detail::moved_object<map<Key,T,Pred,Alloc> > x, map<Key,T,Pred,Alloc>& y)
    { x.get().swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(map<Key,T,Pred,Alloc>& x,
- const detail::moved_object<map<Key,T,Pred,Alloc> >& y)
+inline void swap(map<Key,T,Pred,Alloc>& x, detail::moved_object<map<Key,T,Pred,Alloc> > y)
    { x.swap(y.get()); }
 #else
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(map<Key,T,Pred,Alloc>&&x,
- map<Key,T,Pred,Alloc>&&y)
+inline void swap(map<Key,T,Pred,Alloc>&&x, map<Key,T,Pred,Alloc>&&y)
    { x.swap(y); }
 #endif
 
@@ -863,8 +847,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- multimap(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ multimap(detail::moved_object<multimap<Key,T,Pred,Alloc> > x)
       : m_tree(detail::move_impl(x.get().m_tree))
    {}
    #else
@@ -883,13 +867,11 @@
    //! <b>Effects</b>: this->swap(x.get()).
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- multimap<Key,T,Pred,Alloc>&
- operator=(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ multimap<Key,T,Pred,Alloc>& operator=(detail::moved_object<multimap<Key,T,Pred,Alloc> > x)
    { m_tree = detail::move_impl(x.get().m_tree); return *this; }
    #else
- multimap<Key,T,Pred,Alloc>&
- operator=(multimap<Key,T,Pred,Alloc> && x)
+ multimap<Key,T,Pred,Alloc>& operator=(multimap<Key,T,Pred,Alloc> && x)
    { m_tree = detail::move_impl(x.m_tree); return *this; }
    #endif
 
@@ -1018,22 +1000,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- void swap(multimap<Key,T,Pred,Alloc>& x)
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x)
- { m_tree.swap(x.get().m_tree); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<multimap> x)
+ { this->swap(x.get()); }
+ void swap(multimap& x)
    #else
- void swap(multimap<Key,T,Pred,Alloc> && x)
- { m_tree.swap(x.m_tree); }
+ void swap(multimap &&x)
    #endif
+ { m_tree.swap(x.m_tree); }
 
    //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
    //! newly inserted element.
@@ -1053,8 +1027,8 @@
    //! the iterator pointing to the newly inserted element.
    //!
    //! <b>Complexity</b>: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const detail::moved_object<std::pair<key_type, mapped_type> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(detail::moved_object<std::pair<key_type, mapped_type> > x)
    { return m_tree.insert_equal(x); }
    #else
    iterator insert(std::pair<key_type, mapped_type> && x)
@@ -1091,8 +1065,8 @@
    //!
    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
    //! is inserted right before p.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(iterator position, const detail::moved_object<std::pair<key_type, mapped_type> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(iterator position, detail::moved_object<std::pair<key_type, mapped_type> > x)
    { return m_tree.insert_equal(position, x); }
    #else
    iterator insert(iterator position, std::pair<key_type, mapped_type> && x)
@@ -1295,25 +1269,21 @@
 { return !(x < y); }
 
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(multimap<Key,T,Pred,Alloc>& x,
- multimap<Key,T,Pred,Alloc>& y)
+inline void swap(multimap<Key,T,Pred,Alloc>& x, multimap<Key,T,Pred,Alloc>& y)
 { x.swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(const detail::moved_object<multimap<Key,T,Pred,Alloc> >& x,
- multimap<Key,T,Pred,Alloc>& y)
+inline void swap(detail::moved_object<multimap<Key,T,Pred,Alloc> > x, multimap<Key,T,Pred,Alloc>& y)
 { x.get().swap(y); }
 
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(multimap<Key,T,Pred,Alloc>& x,
- const detail::moved_object<multimap<Key,T,Pred,Alloc> >& y)
+inline void swap(multimap<Key,T,Pred,Alloc>& x, detail::moved_object<multimap<Key,T,Pred,Alloc> > y)
 { x.swap(y.get()); }
 #else
 template <class Key, class T, class Pred, class Alloc>
-inline void swap(multimap<Key,T,Pred,Alloc>&&x,
- multimap<Key,T,Pred,Alloc>&&y)
+inline void swap(multimap<Key,T,Pred,Alloc>&&x, multimap<Key,T,Pred,Alloc>&&y)
 { x.swap(y); }
 #endif
 

Modified: branches/release/boost/interprocess/containers/set.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/set.hpp (original)
+++ branches/release/boost/interprocess/containers/set.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -144,8 +144,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- set(const detail::moved_object<set<T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ set(detail::moved_object<set<T,Pred,Alloc> > x)
       : m_tree(detail::move_impl(x.get().m_tree))
    {}
    #else
@@ -163,8 +163,8 @@
    //! <b>Effects</b>: this->swap(x.get()).
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- set<T,Pred,Alloc>& operator=(const detail::moved_object<set<T, Pred, Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ set<T,Pred,Alloc>& operator=(detail::moved_object<set<T, Pred, Alloc> > x)
    { m_tree = detail::move_impl(x.get().m_tree); return *this; }
    #else
    set<T,Pred,Alloc>& operator=(set<T, Pred, Alloc> &&x)
@@ -330,22 +330,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- void swap(set<T,Pred,Alloc>& x)
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<set<T,Pred,Alloc> >& x)
- { m_tree.swap(x.get().m_tree); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<set> x)
+ { this->swap(x.get()); }
+ void swap(set& x)
    #else
- void swap(set<T,Pred,Alloc> &&x)
- { m_tree.swap(x.m_tree); }
+ void swap(set &&x)
    #endif
+ { m_tree.swap(x.m_tree); }
 
    //! <b>Effects</b>: Inserts x if and only if there is no element in the container
    //! with key equivalent to the key of x.
@@ -366,8 +358,8 @@
    //! points to the element with key equivalent to the key of x.
    //!
    //! <b>Complexity</b>: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- std::pair<iterator,bool> insert(const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ std::pair<iterator,bool> insert(detail::moved_object<value_type> x)
    { return m_tree.insert_unique(x); }
    #else
    std::pair<iterator,bool> insert(value_type &&x)
@@ -392,8 +384,8 @@
    //! <b>Returns</b>: An iterator pointing to the element with key equivalent to the key of x.
    //!
    //! <b>Complexity</b>: Logarithmic.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator p, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator p, detail::moved_object<value_type> x)
    { return m_tree.insert_unique(p, x); }
    #else
    iterator insert(const_iterator p, value_type &&x)
@@ -596,26 +588,22 @@
                        const set<T,Pred,Alloc>& y)
 { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class Pred, class Alloc>
-inline void swap(set<T,Pred,Alloc>& x,
- set<T,Pred,Alloc>& y)
+inline void swap(set<T,Pred,Alloc>& x, set<T,Pred,Alloc>& y)
 { x.swap(y); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(set<T,Pred,Alloc>& x,
- detail::moved_object<set<T,Pred,Alloc> >& y)
+inline void swap(set<T,Pred,Alloc>& x, detail::moved_object<set<T,Pred,Alloc> >& y)
 { x.swap(y.get()); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<set<T,Pred,Alloc> >& y,
- set<T,Pred,Alloc>& x)
+inline void swap(detail::moved_object<set<T,Pred,Alloc> >& y, set<T,Pred,Alloc>& x)
 { y.swap(x.get()); }
 
 #else
 template <class T, class Pred, class Alloc>
-inline void swap(set<T,Pred,Alloc>&&x,
- set<T,Pred,Alloc>&&y)
+inline void swap(set<T,Pred,Alloc>&&x, set<T,Pred,Alloc>&&y)
 { x.swap(y); }
 #endif
 
@@ -718,8 +706,8 @@
    //! <b>Complexity</b>: Construct.
    //!
    //! <b>Postcondition</b>: x is emptied.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- multiset(const detail::moved_object<multiset<T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ multiset(detail::moved_object<multiset<T,Pred,Alloc> > x)
       : m_tree(detail::move_impl(x.get().m_tree))
    {}
    #else
@@ -737,8 +725,8 @@
    //! <b>Effects</b>: this->swap(x.get()).
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- multiset<T,Pred,Alloc>& operator=(const detail::moved_object<multiset<T,Pred,Alloc> >& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ multiset<T,Pred,Alloc>& operator=(detail::moved_object<multiset<T,Pred,Alloc> > x)
    { m_tree = detail::move_impl(x.get().m_tree); return *this; }
    #else
    multiset<T,Pred,Alloc>& operator=(multiset<T,Pred,Alloc> &&x)
@@ -904,22 +892,14 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- void swap(multiset<T,Pred,Alloc>& x)
- { m_tree.swap(x.m_tree); }
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
- //! If this->allocator_type() != x.allocator_type() allocators are also swapped.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<multiset<T,Pred,Alloc> >& x)
- { m_tree.swap(x.get().m_tree); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<multiset> x)
+ { this->swap(x.get()); }
+ void swap(multiset& x)
    #else
- void swap(multiset<T,Pred,Alloc> && x)
- { m_tree.swap(x.m_tree); }
+ void swap(multiset &&x)
    #endif
+ { m_tree.swap(x.m_tree); }
 
    //! <b>Effects</b>: Inserts x and returns the iterator pointing to the
    //! newly inserted element.
@@ -935,8 +915,8 @@
    //!
    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
    //! is inserted right before p.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(detail::moved_object<value_type> x)
    { return m_tree.insert_equal(x); }
    #else
    iterator insert(value_type && x)
@@ -962,8 +942,8 @@
    //!
    //! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
    //! is inserted right before p.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator p, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator p, detail::moved_object<value_type> x)
    { return m_tree.insert_equal(p, x); }
    #else
    iterator insert(const_iterator p, value_type && x)
@@ -1160,25 +1140,21 @@
                        const multiset<T,Pred,Alloc>& y)
 { return !(x < y); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class Pred, class Alloc>
-inline void swap(multiset<T,Pred,Alloc>& x,
- multiset<T,Pred,Alloc>& y)
+inline void swap(multiset<T,Pred,Alloc>& x, multiset<T,Pred,Alloc>& y)
 { x.swap(y); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(multiset<T,Pred,Alloc>& x,
- detail::moved_object<multiset<T,Pred,Alloc> >& y)
+inline void swap(multiset<T,Pred,Alloc>& x, detail::moved_object<multiset<T,Pred,Alloc> >& y)
 { x.swap(y.get()); }
 
 template <class T, class Pred, class Alloc>
-inline void swap(detail::moved_object<multiset<T,Pred,Alloc> >& y,
- multiset<T,Pred,Alloc>& x)
+inline void swap(detail::moved_object<multiset<T,Pred,Alloc> >& y, multiset<T,Pred,Alloc>& x)
 { y.swap(x.get()); }
 #else
 template <class T, class Pred, class Alloc>
-inline void swap(multiset<T,Pred,Alloc>&&x,
- multiset<T,Pred,Alloc>&&y)
+inline void swap(multiset<T,Pred,Alloc>&&x, multiset<T,Pred,Alloc>&&y)
 { x.swap(y); }
 #endif
 

Modified: branches/release/boost/interprocess/containers/slist.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/slist.hpp (original)
+++ branches/release/boost/interprocess/containers/slist.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -178,7 +178,7 @@
       detail::intrusive_slist_type<A>::type Icont;
    typedef detail::node_alloc_holder<A, Icont> AllocHolder;
    typedef typename AllocHolder::NodePtr NodePtr;
- typedef list <T, A> ThisType;
+ typedef slist <T, A> ThisType;
    typedef typename AllocHolder::NodeAlloc NodeAlloc;
    typedef typename AllocHolder::ValAlloc ValAlloc;
    typedef typename AllocHolder::Node Node;
@@ -384,11 +384,11 @@
 
    //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
    //!
- //! <b>Throws</b>: If allocator_type's default constructor throws.
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- slist(const detail::moved_object<slist> &x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ slist(detail::moved_object<slist> x)
       : AllocHolder(detail::move_impl((AllocHolder&)x.get()))
    {}
    #else
@@ -421,8 +421,8 @@
    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
    //!
    //! <b>Complexity</b>: Linear to the number of elements in x.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- slist& operator= (const detail::moved_object<slist>& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ slist& operator= (detail::moved_object<slist> mx)
    {
       if (&mx.get() != this){
          this->clear();
@@ -448,7 +448,7 @@
    //!
    //! <b>Complexity</b>: Linear to the number of elements.
    ~slist()
- { this->clear(); }
+ {} //AllocHolder clears the slist
 
    //! <b>Effects</b>: Returns a copy of the internal allocator.
    //!
@@ -597,7 +597,13 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Linear to the number of elements on *this and x.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<slist> x)
+ { this->swap(x.get()); }
    void swap(slist& x)
+ #else
+ void swap(slist &&x)
+ #endif
    { AllocHolder::swap(x); }
 
    //! <b>Requires</b>: !empty()
@@ -637,8 +643,8 @@
    //! <b>Throws</b>: If memory allocation throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void push_front(const detail::moved_object<T>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void push_front(detail::moved_object<T> x)
    { this->icont().push_front(*this->create_node(x)); }
    #else
    void push_front(T && x)
@@ -702,8 +708,8 @@
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references of
    //! previous values.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert_after(const_iterator prev_pos, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert_after(const_iterator prev_pos, detail::moved_object<value_type> x)
    { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
    #else
    iterator insert_after(const_iterator prev_pos, value_type && x)
@@ -760,8 +766,8 @@
    //! <b>Throws</b>: If memory allocation throws.
    //!
    //! <b>Complexity</b>: Linear to the elements before p.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator p, const detail::moved_object<value_type>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator p, detail::moved_object<value_type> x)
    { return this->insert_after(previous(p), x); }
    #else
    iterator insert(const_iterator p, value_type && x)
@@ -1000,7 +1006,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
    //! this list. Iterators of this list and all the references are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice_after(const_iterator prev_pos, detail::moved_object<slist> x)
+ { this->splice_after(prev_pos, x.get()); }
    void splice_after(const_iterator prev_pos, slist& x)
+ #else
+ void splice_after(const_iterator prev_pos, slist&& x)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after(prev_pos.get(), x.icont());
@@ -1010,12 +1022,6 @@
       }
    }
 
- //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
- // after p. This is constant time.
-
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! i must point to an element contained in list x.
    //!
@@ -1030,7 +1036,13 @@
    //!
    //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
    //! list. Iterators of this list and all the references are not invalidated.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice_after(const_iterator prev_pos, detail::moved_object<slist> x, const_iterator prev)
+ { this->splice_after(prev_pos, x.get(), prev); }
    void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
+ #else
+ void splice_after(const_iterator prev_pos, slist&& x, const_iterator prev)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
@@ -1040,13 +1052,6 @@
       }
    }
 
- //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,
- // inserting it immediately after p. This is constant time.
-
-
    //! <b>Requires</b>: prev_pos must be a valid iterator of this.
    //! before_first and before_last must be valid iterators of x.
    //! prev_pos must not be contained in [before_first, before_last) range.
@@ -1061,8 +1066,16 @@
    //!
    //! <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(const_iterator prev_pos, slist& x,
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice_after(const_iterator prev_pos, detail::moved_object<slist> x,
                      const_iterator before_first, const_iterator before_last)
+ { this->splice_after(prev_pos, x.get(), before_first, before_last); }
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last)
+ #else
+ void splice_after(const_iterator prev_pos, slist&& x,
+ const_iterator before_first, const_iterator before_last)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after
@@ -1073,10 +1086,6 @@
       }
    }
 
- //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.
    //! before_first and before_last must be valid iterators of x.
    //! prev_pos must not be contained in [before_first, before_last) range.
@@ -1092,9 +1101,19 @@
    //!
    //! <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.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice_after(const_iterator prev_pos, 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); }
    void splice_after(const_iterator prev_pos, slist& x,
                      const_iterator before_first, const_iterator before_last,
                      size_type n)
+ #else
+ void splice_after(const_iterator prev_pos, slist&& x,
+ const_iterator before_first, const_iterator before_last,
+ size_type n)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().splice_after
@@ -1105,10 +1124,6 @@
       }
    }
 
- //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
    //! by the list. x != *this
    //!
@@ -1122,12 +1137,15 @@
    //!
    //! <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(const_iterator p, slist& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(const_iterator p, detail::moved_object<ThisType> x)
+ { this->splice(p, x.get()); }
+ void splice(const_iterator p, ThisType& x)
+ #else
+ void splice(const_iterator p, ThisType&& x)
+ #endif
    { this->splice_after(this->previous(p), 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
    //! by this list. i must point to an element contained in list x.
    //!
@@ -1142,12 +1160,15 @@
    //!
    //! <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(const_iterator p, slist& x, const_iterator i)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator i)
+ { this->splice(p, x.get(), i); }
+ void splice(const_iterator p, slist& x, const_iterator i)
+ #else
+ void splice(const_iterator p, slist&& x, const_iterator i)
+ #endif
    { this->splice_after(previous(p), x, 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
    //! by this list. first and last must point to elements contained in list x.
    //!
@@ -1162,12 +1183,15 @@
    //!
    //! <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.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void splice(const_iterator p, detail::moved_object<ThisType> x, const_iterator first, const_iterator last)
+ { this->splice(p, x.get(), first, last); }
    void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+ #else
+ void splice(const_iterator p, slist&& x, const_iterator first, const_iterator last)
+ #endif
    { this->splice_after(previous(p), x, previous(first), previous(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.
    //!
    //! <b>Throws</b>: Nothing.
@@ -1244,12 +1268,15 @@
    //!
    //! <b>Complexity</b>: This function is linear time: it performs at most
    //! size() + x.size() - 1 comparisons.
- void merge(slist& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void merge(detail::moved_object<slist<T, A> > x)
+ { this->merge(x.get()); }
+ void merge(slist<T, A>& x)
+ #else
+ void merge(slist<T, A>&& x)
+ #endif
    { this->merge(x, value_less()); }
 
- //void merge(const detail::moved_object<slist>& x)
- //{ this->merge(x.get(), value_less()); }
-
    //! <b>Requires</b>: p must be a comparison function that induces a strict weak
    //! ordering and both *this and x must be sorted according to that ordering
    //! The lists x and *this must be distinct.
@@ -1264,8 +1291,16 @@
    //! size() + x.size() - 1 comparisons.
    //!
    //! <b>Note</b>: Iterators and references to *this are not invalidated.
- template <class StrictWeakOrdering>
- void merge(slist& x, StrictWeakOrdering comp)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ template <class StrictWeakOrdering>
+ void merge(detail::moved_object<slist<T, A> > x, StrictWeakOrdering comp)
+ { this->merge(x.get(), comp); }
+ template <class StrictWeakOrdering>
+ void merge(slist<T, A>& x, StrictWeakOrdering comp)
+ #else
+ template <class StrictWeakOrdering>
+ void merge(slist<T, A>&& x, StrictWeakOrdering comp)
+ #endif
    {
       if((NodeAlloc&)*this == (NodeAlloc&)x){
          this->icont().merge(x.icont(),
@@ -1276,10 +1311,6 @@
       }
    }
 
- //template <class StrictWeakOrdering>
- //void merge(const detail::moved_object<slist>& x, StrictWeakOrdering comp)
- //{ this->merge(x.get(), comp); }
-
    //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
    //! The sort is stable, that is, the relative order of equivalent elements is preserved.
    //!
@@ -1509,17 +1540,17 @@
 operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2)
    { return !(sL1 < sL2); }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class A>
 inline void swap(slist<T,A>& x, slist<T,A>& y)
    { x.swap(y); }
 
 template <class T, class A>
-inline void swap(const detail::moved_object<slist<T,A> >& x, slist<T,A>& y)
+inline void swap(detail::moved_object<slist<T,A> > x, slist<T,A>& y)
    { x.get().swap(y); }
 
 template <class T, class A>
-inline void swap(slist<T,A>& x, const detail::moved_object<slist<T,A> >& y)
+inline void swap(slist<T,A>& x, detail::moved_object<slist<T,A> > y)
    { x.swap(y.get()); }
 #else
 template <class T, class A>

Modified: branches/release/boost/interprocess/containers/string.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/string.hpp (original)
+++ branches/release/boost/interprocess/containers/string.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -98,8 +98,8 @@
       this->allocate_initial_block(n);
    }
 
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_string_base(const detail::moved_object<basic_string_base<A> >& b)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE)
+ basic_string_base(detail::moved_object<basic_string_base<A> > b)
       : members_(b.get().members_)
    {
       init();
@@ -380,7 +380,13 @@
          this->members_.m_repr.long_repr().length = static_cast<typename A::size_type>(sz);
    }
 
- void swap(basic_string_base& other)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_string_base> x)
+ { this->swap(x.get()); }
+ void swap(basic_string_base& other)
+ #else
+ void swap(basic_string_base &&other)
+ #endif
    {
       if(this->is_short()){
          if(other.is_short()){
@@ -552,8 +558,8 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_string(const detail::moved_object<basic_string>& s)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_string(detail::moved_object<basic_string> s)
       : base_t(detail::move_impl((base_t&)s.get()))
    {}
    #else
@@ -637,8 +643,8 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_string& operator=(const detail::moved_object<basic_string>& ms)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_string& operator=(detail::moved_object<basic_string> ms)
    {
       basic_string &s = ms.get();
       if (&s != this){
@@ -965,8 +971,8 @@
    { return this->operator=(s); }
 
    //! <b>Effects</b>: Moves the resources from ms *this.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_string& assign(const detail::moved_object<basic_string>& ms)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_string& assign(detail::moved_object<basic_string> ms)
    { return this->operator=(ms);}
    #else
    basic_string& assign(basic_string && ms)
@@ -1259,17 +1265,14 @@
    }
 
    //! <b>Effects</b>: Swaps the contents of two strings.
- void swap(basic_string& s)
- { base_t::swap(s); }
-
- //! <b>Effects</b>: Swaps the contents of two strings.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<basic_string>& ms)
- { this->swap(ms.get()); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_string> x)
+ { this->swap(x.get()); }
+ void swap(basic_string& x)
    #else
- void swap(basic_string && ms)
- { this->swap(ms); }
+ void swap(basic_string &&x)
    #endif
+ { base_t::swap(x); }
 
    //! <b>Returns</b>: Returns a pointer to a null-terminated array of characters
    //! representing the string's contents. For any string s it is guaranteed
@@ -1930,7 +1933,7 @@
 #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
 template <class CharT, class Traits, class A>
 inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
+operator+(detail::moved_object<basic_string<CharT,Traits,A> > mx,
           const basic_string<CharT,Traits,A>& y)
 {
    mx.get() += y;
@@ -1951,7 +1954,7 @@
 template <class CharT, class Traits, class A>
 inline detail::moved_object<basic_string<CharT,Traits,A> >
 operator+(const basic_string<CharT,Traits,A>& x,
- const detail::moved_object<basic_string<CharT,Traits,A> >& my)
+ detail::moved_object<basic_string<CharT,Traits,A> > my)
 {
    typedef typename basic_string<CharT,Traits,A>::size_type size_type;
    return my.get().replace(size_type(0), size_type(0), x);
@@ -1985,7 +1988,7 @@
 template <class CharT, class Traits, class A>
 inline detail::moved_object<basic_string<CharT,Traits,A> >
 operator+(const CharT* s,
- const detail::moved_object<basic_string<CharT,Traits,A> >& my)
+ detail::moved_object<basic_string<CharT,Traits,A> > my)
 {
    typedef typename basic_string<CharT,Traits,A>::size_type size_type;
    return my.get().replace(size_type(0), size_type(0), s);
@@ -2018,7 +2021,7 @@
 template <class CharT, class Traits, class A>
 inline detail::moved_object<basic_string<CharT,Traits,A> >
 operator+(CharT c,
- const detail::moved_object<basic_string<CharT,Traits,A> >& my)
+ detail::moved_object<basic_string<CharT,Traits,A> > my)
 {
    typedef typename basic_string<CharT,Traits,A>::size_type size_type;
    return my.get().replace(size_type(0), size_type(0), &c, &c + 1);
@@ -2051,7 +2054,7 @@
 #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
 template <class CharT, class Traits, class A>
 inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
+operator+(detail::moved_object<basic_string<CharT,Traits,A> > mx,
           const CharT* s)
 {
    mx.get() += s;
@@ -2084,7 +2087,7 @@
 #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
 template <class CharT, class Traits, class A>
 inline detail::moved_object<basic_string<CharT,Traits,A> >
-operator+(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
+operator+(detail::moved_object<basic_string<CharT,Traits,A> > mx,
           const CharT c)
 {
    mx.get() += c;
@@ -2234,23 +2237,19 @@
 // Swap.
 #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
 template <class CharT, class Traits, class A>
-inline void swap(basic_string<CharT,Traits,A>& x,
- basic_string<CharT,Traits,A>& y)
+inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>& y)
 { x.swap(y); }
 
 template <class CharT, class Traits, class A>
-inline void swap(const detail::moved_object<basic_string<CharT,Traits,A> >& mx,
- basic_string<CharT,Traits,A>& y)
+inline void swap(detail::moved_object<basic_string<CharT,Traits,A> > mx, basic_string<CharT,Traits,A>& y)
 { mx.get().swap(y); }
 
 template <class CharT, class Traits, class A>
-inline void swap(basic_string<CharT,Traits,A>& x,
- const detail::moved_object<basic_string<CharT,Traits,A> >& my)
+inline void swap(basic_string<CharT,Traits,A>& x, detail::moved_object<basic_string<CharT,Traits,A> > my)
 { x.swap(my.get()); }
 #else
 template <class CharT, class Traits, class A>
-inline void swap(basic_string<CharT,Traits,A> && x,
- basic_string<CharT,Traits,A> &&y)
+inline void swap(basic_string<CharT,Traits,A> && x, basic_string<CharT,Traits,A> &&y)
 { x.swap(y); }
 #endif
 
@@ -2319,7 +2318,7 @@
 template <class CharT, class Traits, class A>
 std::basic_ostream<CharT, Traits>&
 operator<<(std::basic_ostream<CharT, Traits>& os,
- const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
+ detail::moved_object<basic_string<CharT,Traits,A> > ms)
 { return os << ms.get(); }
 #endif
 
@@ -2327,7 +2326,7 @@
 template <class CharT, class Traits, class A>
 std::basic_istream<CharT, Traits>&
 operator>>(std::basic_istream<CharT, Traits>& is,
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
            basic_string<CharT,Traits,A>& s)
             #else
            basic_string<CharT,Traits,A>&&s)
@@ -2376,18 +2375,18 @@
    return is;
 }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class CharT, class Traits, class A>
 std::basic_istream<CharT, Traits>&
 operator>>(std::basic_istream<CharT, Traits>& is,
- const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
+ detail::moved_object<basic_string<CharT,Traits,A> > ms)
 { return is >> ms.get(); }
 #endif
 
 template <class CharT, class Traits, class A>
 std::basic_istream<CharT, Traits>&
 getline(std::istream& is,
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
         basic_string<CharT,Traits,A>& s,
          #else
         basic_string<CharT,Traits,A>&&s,
@@ -2427,12 +2426,12 @@
 template <class CharT, class Traits, class A>
 std::basic_istream<CharT, Traits>&
 getline(std::istream& is,
- const detail::moved_object<basic_string<CharT,Traits,A> >& ms,
+ detail::moved_object<basic_string<CharT,Traits,A> > ms,
         CharT delim)
 { return getline(is, ms.get(), delim); }
 #endif
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class CharT, class Traits, class A>
 inline std::basic_istream<CharT, Traits>&
 getline(std::basic_istream<CharT, Traits>& is,
@@ -2444,7 +2443,7 @@
 template <class CharT, class Traits, class A>
 std::basic_istream<CharT, Traits>&
 getline(std::istream& is,
- const detail::moved_object<basic_string<CharT,Traits,A> >& ms)
+ detail::moved_object<basic_string<CharT,Traits,A> > ms)
 { return getline(is, ms.get()); }
 #else
 template <class CharT, class Traits, class A>

Modified: branches/release/boost/interprocess/containers/vector.hpp
==============================================================================
--- branches/release/boost/interprocess/containers/vector.hpp (original)
+++ branches/release/boost/interprocess/containers/vector.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -312,7 +312,10 @@
 
    //Destructor
    ~vector_alloc_holder()
- { this->prot_deallocate(); }
+ {
+ this->prot_destroy_all();
+ this->prot_deallocate();
+ }
 
    typedef detail::integral_constant<unsigned, 1> allocator_v1;
    typedef detail::integral_constant<unsigned, 2> allocator_v2;
@@ -397,6 +400,12 @@
          for(; n--; ++p) p->~value_type();
    }
 
+ void prot_destroy_all()
+ {
+ this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
+ this->members_.m_size = 0;
+ }
+
    A &alloc()
    { return members_; }
 
@@ -502,8 +511,8 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- vector(const detail::moved_object<vector<T, A> >& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ vector(detail::moved_object<vector<T, A> > mx)
       : base_t(mx.get())
    { this->swap(mx.get()); }
    #else
@@ -531,7 +540,7 @@
    //!
    //! <b>Complexity</b>: Linear to the number of elements.
    ~vector()
- { this->priv_destroy_all(); }
+ {} //vector_alloc_holder clears the data
 
    //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
    //!
@@ -870,8 +879,8 @@
    //! <b>Throws</b>: If allocator_type's copy constructor throws.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- vector<T, A>& operator=(const detail::moved_object<vector<T, A> >& mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ vector<T, A>& operator=(detail::moved_object<vector<T, A> > mx)
    {
       vector<T, A> &x = mx.get();
    #else
@@ -932,8 +941,8 @@
    //! <b>Throws</b>: If memory allocation throws.
    //!
    //! <b>Complexity</b>: Amortized constant time.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void push_back(const detail::moved_object<T> & mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void push_back(detail::moved_object<T> mx)
    {
       value_type &x = mx.get();
    #else
@@ -1059,10 +1068,12 @@
    //! <b>Throws</b>: Nothing.
    //!
    //! <b>Complexity</b>: Constant.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(vector<T, A>& x)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<vector> x)
+ { this->swap(x.get()); }
+ void swap(vector& x)
    #else
- void swap(vector<T, A> && x)
+ void swap(vector &&x)
    #endif
    {
       allocator_type &this_al = this->alloc(), &other_al = x.alloc();
@@ -1076,21 +1087,6 @@
       }
    }
 
- #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.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- void swap(const detail::moved_object<vector<T, A> >& mx)
- {
- vector<T, A> &x = mx.get();
- this->swap(x);
- }
- #endif
-
    //! <b>Requires</b>: position must be a valid iterator of *this.
    //!
    //! <b>Effects</b>: Insert a copy of x before position.
@@ -1115,8 +1111,8 @@
    //!
    //! <b>Complexity</b>: If position is end(), amortized constant time
    //! Linear time otherwise.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- iterator insert(const_iterator position, const detail::moved_object<T> &mx)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ iterator insert(const_iterator position, detail::moved_object<T> mx)
    {
       value_type &x = mx.get();
    #else
@@ -1255,7 +1251,7 @@
    //!
    //! <b>Complexity</b>: Linear to the number of elements in the vector.
    void clear()
- { this->priv_destroy_all(); }
+ { this->prot_destroy_all(); }
 
    /// @cond
 
@@ -1303,12 +1299,6 @@
       }
    }
 
- void priv_destroy_all()
- {
- this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size);
- this->members_.m_size = 0;
- }
-
    template <class FwdIt>
    void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
    {
@@ -1319,13 +1309,7 @@
       }
    }
 
- 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
- )
+ void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
    {
       //Check if we have enough memory or try to expand current memory
       size_type remaining = this->members_.m_capacity - this->members_.m_size;
@@ -1969,17 +1953,17 @@
                                        y.begin(), y.end());
 }
 
-#ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 template <class T, class A>
 inline void swap(vector<T, A>& x, vector<T, A>& y)
 { x.swap(y); }
 
 template <class T, class A>
-inline void swap(const detail::moved_object<vector<T, A> >& x, vector<T, A>& y)
+inline void swap(detail::moved_object<vector<T, A> > x, vector<T, A>& y)
 { x.get().swap(y); }
 
 template <class T, class A>
-inline void swap(vector<T, A> &x, const detail::moved_object<vector<T, A> >& y)
+inline void swap(vector<T, A> &x, detail::moved_object<vector<T, A> > y)
 { x.swap(y.get()); }
 #else
 template <class T, class A>

Modified: branches/release/boost/interprocess/detail/os_thread_functions.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/os_thread_functions.hpp (original)
+++ branches/release/boost/interprocess/detail/os_thread_functions.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -34,10 +34,13 @@
 
 typedef unsigned long OS_process_id_t;
 typedef unsigned long OS_thread_id_t;
+typedef OS_thread_id_t OS_systemwide_thread_id_t;
 
+//process
 inline OS_process_id_t get_current_process_id()
 { return winapi::get_current_process_id(); }
 
+//thread
 inline OS_thread_id_t get_current_thread_id()
 { return winapi::get_current_thread_id(); }
 
@@ -50,28 +53,71 @@
 inline void thread_yield()
 { winapi::sched_yield(); }
 
+//systemwide thread
+inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
+{
+ return get_current_thread_id();
+}
+
+inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
+{
+ return equal_thread_id(id1, id2);
+}
+
+inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
+{
+ return get_invalid_thread_id();
+}
+
 #else //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
 
 typedef pthread_t OS_thread_id_t;
-typedef int OS_process_id_t;
+typedef pid_t OS_process_id_t;
+
+struct OS_systemwide_thread_id_t
+{
+ OS_systemwide_thread_id_t(pid_t p, pthread_t t)
+ : pid(p), tid(t)
+ {}
+ pid_t pid;
+ pthread_t tid;
+};
 
+//process
 inline OS_process_id_t get_current_process_id()
-{ return getpid(); }
+{ return ::getpid(); }
 
-inline pthread_t get_current_thread_id()
-{ return pthread_self(); }
+//thread
+inline OS_thread_id_t get_current_thread_id()
+{ return ::pthread_self(); }
 
 inline OS_thread_id_t get_invalid_thread_id()
-{
+{
    static pthread_t invalid_id;
    return invalid_id;
 }
 
 inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
-{ return 0 != pthread_equal(id1, id2); }
+{ return 0 != ::pthread_equal(id1, id2); }
 
 inline void thread_yield()
-{ sched_yield(); }
+{ ::sched_yield(); }
+
+//systemwide thread
+inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
+{
+ return OS_systemwide_thread_id_t(::getpid(), ::pthread_self());
+}
+
+inline bool equal_systemwide_thread_id(const OS_systemwide_thread_id_t &id1, const OS_systemwide_thread_id_t &id2)
+{
+ return (0 != ::pthread_equal(id1.tid, id2.tid)) && (id1.pid == id2.pid);
+}
+
+inline OS_systemwide_thread_id_t get_invalid_systemwide_thread_id()
+{
+ return OS_systemwide_thread_id_t(pid_t(0), get_invalid_thread_id());
+}
 
 #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
 

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -382,7 +382,7 @@
    index_data(void *ptr) : m_ptr(ptr){}
 
    void *value() const
- { return static_cast<void>(detail::get_pointer(m_ptr)); }
+ { return static_cast<void*>(detail::get_pointer(m_ptr)); }
 };
 
 template<class MemoryAlgorithm>

Modified: branches/release/boost/interprocess/detail/utilities.hpp
==============================================================================
--- branches/release/boost/interprocess/detail/utilities.hpp (original)
+++ branches/release/boost/interprocess/detail/utilities.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -542,7 +542,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template <class D, class S>
- pair(const detail::moved_object<std::pair<D, S> >& p)
+ pair(detail::moved_object<std::pair<D, S> > p)
       : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
    {}
    #else
@@ -567,7 +567,7 @@
    {}
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair(const detail::moved_object<pair<T1, T2> >& p)
+ pair(detail::moved_object<pair<T1, T2> > p)
       : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
    {}
    #else
@@ -578,7 +578,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template <class D, class S>
- pair(const detail::moved_object<pair<D, S> >& p)
+ pair(detail::moved_object<pair<D, S> > p)
       : first(detail::move_impl(p.get().first)), second(detail::move_impl(p.get().second))
    {}
    #else
@@ -616,7 +616,7 @@
    #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair& operator=(const detail::moved_object<pair<T1, T2> > &p)
+ pair& operator=(detail::moved_object<pair<T1, T2> > p)
    {
       first = detail::move_impl(p.get().first);
       second = detail::move_impl(p.get().second);
@@ -632,7 +632,7 @@
    #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- pair& operator=(const detail::moved_object<std::pair<T1, T2> > &p)
+ pair& operator=(detail::moved_object<std::pair<T1, T2> > p)
    {
       first = detail::move_impl(p.get().first);
       second = detail::move_impl(p.get().second);
@@ -649,7 +649,7 @@
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template <class D, class S>
- pair& operator=(const detail::moved_object<std::pair<D, S> > &p)
+ pair& operator=(detail::moved_object<std::pair<D, S> > p)
    {
       first = detail::move_impl(p.get().first);
       second = detail::move_impl(p.get().second);
@@ -666,7 +666,7 @@
    #endif
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- void swap(const detail::moved_object<pair> &p)
+ void swap(detail::moved_object<pair> p)
    { std::swap(*this, p.get()); }
 
    void swap(pair& p)
@@ -709,14 +709,14 @@
 
 #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
 template <class T1, class T2>
-inline void swap(const detail::moved_object<pair<T1, T2> > &x, pair<T1, T2>& y)
+inline void swap(detail::moved_object<pair<T1, T2> > &x, pair<T1, T2> y)
 {
    swap(x.get().first, y.first);
    swap(x.get().second, y.second);
 }
 
 template <class T1, class T2>
-inline void swap(pair<T1, T2>& x, const detail::moved_object<pair<T1, T2> > &y)
+inline void swap(pair<T1, T2>& x, detail::moved_object<pair<T1, T2> > y)
 {
    swap(x.first, y.get().first);
    swap(x.second, y.get().second);

Modified: branches/release/boost/interprocess/file_mapping.hpp
==============================================================================
--- branches/release/boost/interprocess/file_mapping.hpp (original)
+++ branches/release/boost/interprocess/file_mapping.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -8,8 +8,8 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-#ifndef BOOST_INTERPROCESS_MAPPED_FILE_HPP
-#define BOOST_INTERPROCESS_MAPPED_FILE_HPP
+#ifndef BOOST_INTERPROCESS_FILE_MAPPING_HPP
+#define BOOST_INTERPROCESS_FILE_MAPPING_HPP
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
@@ -28,9 +28,22 @@
 //!Describes file_mapping and mapped region classes
 
 namespace boost {
-
 namespace interprocess {
 
+///@cond
+
+class file_mapping;
+
+//!Trait class to detect if a type is
+//!movable
+template<>
+struct is_movable<file_mapping>
+{
+ enum { value = true };
+};
+
+///@endcond
+
 //!A class that wraps a file-mapping that can be used to
 //!create mapped regions from the mapped files
 class file_mapping
@@ -52,10 +65,10 @@
    //!modes. Throws interprocess_exception on error.
    file_mapping(const char *filename, mode_t mode);
 
- //!Moves the ownership of "moved"'s shared memory object to *this.
- //!After the call, "moved" does not represent any shared memory object.
+ //!Moves the ownership of "moved"'s file mapping object to *this.
+ //!After the call, "moved" does not represent any file mapping object.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    file_mapping(detail::moved_object<file_mapping> moved)
       : m_handle(file_handle_t(detail::invalid_file()))
    { this->swap(moved.get()); }
@@ -65,29 +78,31 @@
    { this->swap(moved); }
    #endif
 
- //!Moves the ownership of "moved"'s shared memory to *this.
- //!After the call, "moved" does not represent any shared memory.
+ //!Moves the ownership of "moved"'s file mapping to *this.
+ //!After the call, "moved" does not represent any file mapping.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- file_mapping &operator=
- (detail::moved_object<file_mapping> moved)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ file_mapping &operator=(detail::moved_object<file_mapping> m_other)
    {
- file_mapping tmp(moved);
- this->swap(tmp);
- return *this;
- }
+ file_mapping &moved = m_other.get();
    #else
    file_mapping &operator=(file_mapping &&moved)
    {
+ #endif
       file_mapping tmp(detail::move_impl(moved));
       this->swap(tmp);
       return *this;
    }
- #endif
 
    //!Swaps to file_mappings.
    //!Does not throw.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<file_mapping> mother)
+ { this->swap(mother.get()); }
    void swap(file_mapping &other);
+ #else
+ void swap(file_mapping &&other);
+ #endif
 
    //!Returns access mode
    //!used in the constructor
@@ -125,7 +140,11 @@
 inline const char *file_mapping::get_name() const
 { return m_filename.c_str(); }
 
-inline void file_mapping::swap(file_mapping &other)
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+void file_mapping::swap(file_mapping &other)
+#else
+void file_mapping::swap(file_mapping &&other)
+#endif
 {
    std::swap(m_handle, other.m_handle);
    std::swap(m_mode, other.m_mode);
@@ -170,15 +189,6 @@
    }
 }
 
-
-//!Trait class to detect if a type is
-//!movable
-template<>
-struct is_movable<file_mapping>
-{
- enum { value = true };
-};
-
 ///@endcond
 
 //!A class that stores the name of a file
@@ -202,4 +212,4 @@
 
 #include <boost/interprocess/detail/config_end.hpp>
 
-#endif //BOOST_INTERPROCESS_MAPPED_FILE_HPP
+#endif //BOOST_INTERPROCESS_FILE_MAPPING_HPP

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -465,8 +465,11 @@
 
             case timed :
                do{
- if(!p_hdr->m_cond_send.timed_wait(lock, abs_time))
- return !p_hdr->is_full();
+ if(!p_hdr->m_cond_send.timed_wait(lock, abs_time)){
+ if(p_hdr->is_full())
+ return false;
+ break;
+ }
                }
                while (p_hdr->is_full());
             break;
@@ -554,8 +557,11 @@
 
             case timed :
                do{
- if(!p_hdr->m_cond_recv.timed_wait(lock, abs_time))
- return !p_hdr->is_empty();
+ if(!p_hdr->m_cond_recv.timed_wait(lock, abs_time)){
+ if(p_hdr->is_empty())
+ return false;
+ break;
+ }
                }
                while (p_hdr->is_empty());
             break;

Modified: branches/release/boost/interprocess/managed_external_buffer.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_external_buffer.hpp (original)
+++ branches/release/boost/interprocess/managed_external_buffer.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -75,35 +75,42 @@
    }
 
    //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_external_buffer
- (detail::moved_object<basic_managed_external_buffer> moved)
- { this->swap(moved.get()); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_external_buffer(detail::moved_object<basic_managed_external_buffer> mother)
+ {
+ basic_managed_external_buffer &moved = mother.get();
    #else
- basic_managed_external_buffer
- (basic_managed_external_buffer &&moved)
- { this->swap(moved); }
- #endif
+ basic_managed_external_buffer(basic_managed_external_buffer &&moved)
+ {
+ #endif
+ this->swap(moved);
+ }
 
    //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_external_buffer &operator=
- (detail::moved_object<basic_managed_external_buffer> moved)
- { this->swap(moved.get()); return *this; }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_external_buffer &operator=(detail::moved_object<basic_managed_external_buffer> moved)
    #else
- basic_managed_external_buffer &operator=
- (basic_managed_external_buffer &&moved)
- { this->swap(moved); return *this; }
+ basic_managed_external_buffer &operator=(basic_managed_external_buffer &&moved)
    #endif
+ {
+ basic_managed_external_buffer tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+ }
 
    void grow(std::size_t extra_bytes)
    { base_t::grow(extra_bytes); }
 
    //!Swaps the ownership of the managed heap memories managed by *this and other.
    //!Never throws.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_managed_external_buffer> mother)
+ { this->swap(mother.get()); }
    void swap(basic_managed_external_buffer &other)
+ #else
+ void swap(basic_managed_external_buffer &&other)
+ #endif
    { base_t::swap(other); }
-
 };
 
 ///@cond

Modified: branches/release/boost/interprocess/managed_heap_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_heap_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_heap_memory.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -71,25 +71,29 @@
    }
 
    //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    basic_managed_heap_memory
- (detail::moved_object<basic_managed_heap_memory> moved)
- { this->swap(moved.get()); }
+ (detail::moved_object<basic_managed_heap_memory> mother)
+ {
+ basic_managed_heap_memory &moved = mother.get();
    #else
    basic_managed_heap_memory(basic_managed_heap_memory &&moved)
- { this->swap(moved); }
- #endif
+ {
+ #endif
+ this->swap(moved);
+ }
 
    //!Moves the ownership of "moved"'s managed memory to *this. Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_heap_memory &operator=
- (detail::moved_object<basic_managed_heap_memory> moved)
- { this->swap(moved.get()); return *this; }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_heap_memory &operator=(detail::moved_object<basic_managed_heap_memory> moved)
    #else
- basic_managed_heap_memory &operator=
- (basic_managed_heap_memory &&moved)
- { this->swap(moved); return *this; }
+ basic_managed_heap_memory &operator=(basic_managed_heap_memory &&moved)
    #endif
+ {
+ basic_managed_heap_memory tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+ }
 
    //!Tries to resize internal heap memory so that
    //!we have room for more objects.
@@ -121,7 +125,13 @@
 
    //!Swaps the ownership of the managed heap memories managed by *this and other.
    //!Never throws.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_managed_heap_memory> mother)
+ { this->swap(mother.get()); }
    void swap(basic_managed_heap_memory &other)
+ #else
+ void swap(basic_managed_heap_memory &&other)
+ #endif
    {
       base_t::swap(other);
       m_heapmem.swap(other.m_heapmem);

Modified: branches/release/boost/interprocess/managed_mapped_file.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_mapped_file.hpp (original)
+++ branches/release/boost/interprocess/managed_mapped_file.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -118,25 +118,30 @@
 
    //!Moves the ownership of "moved"'s managed memory to *this.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    basic_managed_mapped_file
- (detail::moved_object<basic_managed_mapped_file> moved)
- { this->swap(moved.get()); }
+ (detail::moved_object<basic_managed_mapped_file> mother)
+ {
+ basic_managed_mapped_file &moved = mother.get();
    #else
    basic_managed_mapped_file(basic_managed_mapped_file &&moved)
- { this->swap(moved); }
- #endif
+ {
+ #endif
+ this->swap(moved);
+ }
 
    //!Moves the ownership of "moved"'s managed memory to *this.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_mapped_file &operator=
- (detail::moved_object<basic_managed_mapped_file> moved)
- { this->swap(moved.get()); return *this; }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_mapped_file &operator=(detail::moved_object<basic_managed_mapped_file> moved)
    #else
    basic_managed_mapped_file &operator=(basic_managed_mapped_file &&moved)
- { this->swap(moved); return *this; }
    #endif
+ {
+ basic_managed_mapped_file tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+ }
 
    //!Destroys *this and indicates that the calling process is finished using
    //!the resource. The destructor function will deallocate
@@ -149,7 +154,14 @@
 
    //!Swaps the ownership of the managed mapped memories managed by *this and other.
    //!Never throws.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_managed_mapped_file> mother)
+ { this->swap(mother.get()); }
+
    void swap(basic_managed_mapped_file &other)
+ #else
+ void swap(basic_managed_mapped_file &&other)
+ #endif
    {
       base_t::swap(other);
       m_mfile.swap(other.m_mfile);

Modified: branches/release/boost/interprocess/managed_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_shared_memory.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -134,29 +134,41 @@
 
    //!Moves the ownership of "moved"'s managed memory to *this.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_shared_memory
- (detail::moved_object<basic_managed_shared_memory> moved)
- { this->swap(moved.get()); }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_shared_memory(detail::moved_object<basic_managed_shared_memory> mother)
+ {
+ basic_managed_shared_memory &moved = mother.get();
    #else
    basic_managed_shared_memory(basic_managed_shared_memory &&moved)
- { this->swap(moved); }
- #endif
+ {
+ #endif
+ basic_managed_shared_memory tmp;
+ this->swap(moved);
+ tmp.swap(moved);
+ }
 
    //!Moves the ownership of "moved"'s managed memory to *this.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_shared_memory &operator=
- (detail::moved_object<basic_managed_shared_memory> moved)
- { this->swap(moved.get()); return *this; }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_shared_memory &operator=(detail::moved_object<basic_managed_shared_memory> moved)
    #else
    basic_managed_shared_memory &operator=(basic_managed_shared_memory &&moved)
- { this->swap(moved); return *this; }
    #endif
+ {
+ basic_managed_shared_memory tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+ }
 
    //!Swaps the ownership of the managed shared memories managed by *this and other.
    //!Never throws.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_managed_shared_memory> mother)
+ { this->swap(mother.get()); }
    void swap(basic_managed_shared_memory &other)
+ #else
+ void swap(basic_managed_shared_memory &&other)
+ #endif
    {
       base_t::swap(other);
       base2_t::swap(other);

Modified: branches/release/boost/interprocess/managed_windows_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/managed_windows_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/managed_windows_shared_memory.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -121,7 +121,7 @@
 
    //!Moves the ownership of "moved"'s managed memory to *this.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    basic_managed_windows_shared_memory
       (detail::moved_object<basic_managed_windows_shared_memory> moved)
    { this->swap(moved.get()); }
@@ -132,15 +132,16 @@
 
    //!Moves the ownership of "moved"'s managed memory to *this.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- basic_managed_windows_shared_memory &operator=
- (detail::moved_object<basic_managed_windows_shared_memory> moved)
- { this->swap(moved.get()); return *this; }
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ basic_managed_windows_shared_memory &operator=(detail::moved_object<basic_managed_windows_shared_memory> moved)
    #else
- basic_managed_windows_shared_memory &operator=
- (basic_managed_windows_shared_memory &&moved)
- { this->swap(moved); return *this; }
+ basic_managed_windows_shared_memory &operator=(basic_managed_windows_shared_memory &&moved)
    #endif
+ {
+ basic_managed_windows_shared_memory tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+ }
 
    //!Destroys *this and indicates that the calling process is finished using
    //!the resource. All mapped regions are still valid after
@@ -152,13 +153,19 @@
 
    //!Swaps the ownership of the managed mapped memories managed by *this and other.
    //!Never throws.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<basic_managed_windows_shared_memory> mother)
+ { this->swap(mother.get()); }
    void swap(basic_managed_windows_shared_memory &other)
+ #else
+ void swap(basic_managed_windows_shared_memory &&other)
+ #endif
    {
       base_t::swap(other);
       m_wshm.swap(other.m_wshm);
    }
- /// @cond
 
+ /// @cond
    //!Tries to find a previous named allocation address. Returns a memory
    //!buffer and the object count. If not found returned pointer is 0.
    //!Never throws.

Modified: branches/release/boost/interprocess/mapped_region.hpp
==============================================================================
--- branches/release/boost/interprocess/mapped_region.hpp (original)
+++ branches/release/boost/interprocess/mapped_region.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -78,7 +78,7 @@
 
    //!Move constructor. *this will be constructed taking ownership of "other"'s
    //!region and "other" will be left in default constructor state.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    mapped_region(detail::moved_object<mapped_region> other);
    #else
    mapped_region(mapped_region &&other);
@@ -90,7 +90,7 @@
 
    //!Move assignment. If *this owns a memory mapped region, it will be
    //!destroyed and it will take ownership of "other"'s memory mapped region.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    mapped_region &operator=(detail::moved_object<mapped_region> other);
    #else
    mapped_region &operator=(mapped_region &&other);
@@ -119,7 +119,13 @@
 
    //!Swaps the mapped_region with another
    //!mapped region
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<mapped_region> mother)
+ { this->swap(mother.get()); }
    void swap(mapped_region &other);
+ #else
+ void swap(mapped_region &&other);
+ #endif
 
    //!Returns the size of the page. This size is the minimum memory that
    //!will be used by the system when mapping a memory mappable source.
@@ -158,12 +164,16 @@
 { x.swap(y); }
 
 #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
-inline mapped_region &mapped_region::operator=(detail::moved_object<mapped_region> other)
-{ this->swap(other.get()); return *this; }
+inline mapped_region &mapped_region::operator=(detail::moved_object<mapped_region> moved)
+{
 #else
-inline mapped_region &mapped_region::operator=(mapped_region &&other)
-{ this->swap(other); return *this; }
+inline mapped_region &mapped_region::operator=(mapped_region &&moved)
+{
 #endif
+ mapped_region tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+}
 
 inline mapped_region::~mapped_region()
 { this->priv_close(); }
@@ -543,9 +553,18 @@
    = mapped_region::page_size_holder<dummy>::get_page_size();
 
 inline std::size_t mapped_region::get_page_size()
-{ return page_size_holder<0>::PageSize; }
+{
+ if(!page_size_holder<0>::PageSize)
+ return page_size_holder<0>::get_page_size();
+ else
+ return page_size_holder<0>::PageSize;
+}
 
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 inline void mapped_region::swap(mapped_region &other)
+#else
+inline void mapped_region::swap(mapped_region &&other)
+#endif
 {
    detail::do_swap(this->m_base, other.m_base);
    detail::do_swap(this->m_size, other.m_size);

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -74,9 +74,8 @@
    //!Moves the ownership of "moved"'s shared memory object to *this.
    //!After the call, "moved" does not represent any shared memory object.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
- shared_memory_object
- (const detail::moved_object<shared_memory_object> moved)
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ shared_memory_object(detail::moved_object<shared_memory_object> moved)
       : m_handle(file_handle_t(detail::invalid_file()))
    { this->swap(moved.get()); }
    #else
@@ -88,7 +87,7 @@
    //!Moves the ownership of "moved"'s shared memory to *this.
    //!After the call, "moved" does not represent any shared memory.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    shared_memory_object &operator=
       (detail::moved_object<shared_memory_object> moved)
    {
@@ -106,7 +105,13 @@
    #endif
 
    //!Swaps the shared_memory_objects. Does not throw
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<shared_memory_object> mother)
+ { this->swap(mother.get()); }
    void swap(shared_memory_object &other);
+ #else
+ void swap(shared_memory_object &&other);
+ #endif
 
    //!Erases a shared memory object from the system.
    //!Returns false on error. Never throws
@@ -168,7 +173,11 @@
 inline bool shared_memory_object::get_size(offset_t &size) const
 { return detail::get_file_size((file_handle_t)m_handle, size); }
 
+#if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
 inline void shared_memory_object::swap(shared_memory_object &other)
+#else
+inline void shared_memory_object::swap(shared_memory_object &&other)
+#endif
 {
    std::swap(m_handle, other.m_handle);
    std::swap(m_mode, other.m_mode);

Modified: branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp
==============================================================================
--- branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp (original)
+++ branches/release/boost/interprocess/smart_ptr/shared_ptr.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -153,7 +153,7 @@
    //!Move-Constructs a shared_ptr that takes ownership of other resource and
    //!other is put in default-constructed state.
    //!Throws: nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    explicit shared_ptr(detail::moved_object<shared_ptr> other)
       : m_pn()
    { this->swap(other.get()); }
@@ -198,7 +198,7 @@
 
    //!Move-assignment. Equivalent to shared_ptr(other).swap(*this).
    //!Never throws
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    shared_ptr & operator=(detail::moved_object<shared_ptr> other) // never throws
    {
       this_type(other).swap(*this);

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -150,7 +150,7 @@
    //!deleter() and u.get_deleter() both reference the same lvalue deleter.
    //!
    //!Throws: nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    unique_ptr(detail::moved_object<unique_ptr> u)
       : ptr_(u.get().release(), detail::move_impl(u.get().get_deleter()))
    {}
@@ -179,7 +179,7 @@
    //!was constructed from u.get_deleter().
    //!
    //!Throws: nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    template <class U, class E>
    unique_ptr(detail::moved_object<unique_ptr<U, E> > u,
       typename detail::enable_if_c<
@@ -230,7 +230,7 @@
    //!Returns: *this.
    //!
    //!Throws: nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    unique_ptr& operator=(detail::moved_object<unique_ptr> u)
    {
       reset(u.get().release());
@@ -261,7 +261,7 @@
    //!
    //!Throws: nothing.
    template <class U, class E>
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    unique_ptr& operator=(detail::moved_object<unique_ptr<U, E> > mu)
    {
       reset(mu.get().release());
@@ -359,7 +359,7 @@
    //!Effects: The stored pointers of this and u are exchanged.
    //! The stored deleters are swapped (unqualified).
    //!Throws: nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    void swap(unique_ptr& u)
    { ptr_.swap(u.ptr_); }
 

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -33,14 +33,14 @@
 namespace interprocess {
 
 inline interprocess_recursive_mutex::interprocess_recursive_mutex()
- : m_nLockCount(0), m_nOwner(detail::get_invalid_thread_id()){}
+ : m_nLockCount(0), m_nOwner(detail::get_invalid_systemwide_thread_id()){}
 
 inline interprocess_recursive_mutex::~interprocess_recursive_mutex(){}
 
 inline void interprocess_recursive_mutex::lock()
 {
- detail::OS_thread_id_t th_id = detail::get_current_thread_id();
- if(detail::equal_thread_id(th_id, m_nOwner)){
+ detail::OS_systemwide_thread_id_t th_id = detail::get_current_systemwide_thread_id();
+ if(detail::equal_systemwide_thread_id(th_id, m_nOwner)){
       if((unsigned int)(m_nLockCount+1) == 0){
          //Overflow, throw an exception
          throw interprocess_exception();
@@ -56,8 +56,8 @@
 
 inline bool interprocess_recursive_mutex::try_lock()
 {
- detail::OS_thread_id_t th_id = detail::get_current_thread_id();
- if(detail::equal_thread_id(th_id, m_nOwner)) { // we own it
+ detail::OS_systemwide_thread_id_t th_id = detail::get_current_systemwide_thread_id();
+ if(detail::equal_systemwide_thread_id(th_id, m_nOwner)) { // we own it
       if((unsigned int)(m_nLockCount+1) == 0){
          //Overflow, throw an exception
          throw interprocess_exception();
@@ -79,8 +79,8 @@
       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
+ detail::OS_systemwide_thread_id_t th_id = detail::get_current_systemwide_thread_id();
+ if(detail::equal_systemwide_thread_id(th_id, m_nOwner)) { // we own it
       if((unsigned int)(m_nLockCount+1) == 0){
          //Overflow, throw an exception
          throw interprocess_exception();
@@ -98,10 +98,10 @@
 
 inline void interprocess_recursive_mutex::unlock()
 {
- assert(detail::equal_thread_id(detail::get_current_thread_id(), m_nOwner));
+ assert(detail::equal_systemwide_thread_id(detail::get_current_systemwide_thread_id(), m_nOwner));
    --m_nLockCount;
    if(!m_nLockCount){
- m_nOwner = detail::get_invalid_thread_id();
+ m_nOwner = detail::get_invalid_systemwide_thread_id();
       m_mutex.unlock();
    }
 }

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -18,10 +18,10 @@
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/interprocess/exceptions.hpp>
-#include <cassert>
 #include <boost/interprocess/detail/os_file_functions.hpp>
 #include <boost/interprocess/detail/os_thread_functions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
+#include <boost/interprocess/detail/move.hpp>
 
 //!\file
 //!Describes a class that wraps file locking capabilities.
@@ -29,6 +29,20 @@
 namespace boost {
 namespace interprocess {
 
+///@cond
+
+class file_lock;
+
+//!Trait class to detect if a type is
+//!movable
+template<>
+struct is_movable<file_lock>
+{
+ enum { value = true };
+};
+
+///@endcond
+
 //!A file lock, is a mutual exclusion utility similar to a mutex using a
 //!file. A file lock has sharable and exclusive locking capabilities and
 //!can be used with scoped_lock and sharable_lock classes.
@@ -38,17 +52,67 @@
 {
    /// @cond
    //Non-copyable
- file_lock();
    file_lock(const file_lock &);
    file_lock &operator=(const file_lock &);
    /// @endcond
    public:
+
+ //!Constructs an empty file mapping.
+ //!Does not throw
+ file_lock()
+ : m_file_hnd(file_handle_t(detail::invalid_file()))
+ {}
+
    //!Opens a file lock. Throws interprocess_exception if the file does not
    //!exist or there are no operating system resources.
    file_lock(const char *name);
 
+ //!Moves the ownership of "moved"'s file mapping object to *this.
+ //!After the call, "moved" does not represent any file mapping object.
+ //!Does not throw
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ file_lock(detail::moved_object<file_lock> moved)
+ : m_file_hnd(file_handle_t(detail::invalid_file()))
+ { this->swap(moved.get()); }
+ #else
+ file_lock(file_lock &&moved)
+ : m_file_hnd(file_handle_t(detail::invalid_file()))
+ { this->swap(moved); }
+ #endif
+
+ //!Moves the ownership of "moved"'s file mapping to *this.
+ //!After the call, "moved" does not represent any file mapping.
+ //!Does not throw
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ file_lock &operator=(detail::moved_object<file_lock> m_other)
+ {
+ file_lock &moved = m_other.get();
+ #else
+ file_lock &operator=(file_lock &&moved)
+ {
+ #endif
+ file_lock tmp(detail::move_impl(moved));
+ this->swap(tmp);
+ return *this;
+ }
+
    //!Closes a file lock. Does not throw.
    ~file_lock();
+
+ //!Swaps two file_locks.
+ //!Does not throw.
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
+ void swap(detail::moved_object<file_lock> mother)
+ { this->swap(mother.get()); }
+ void swap(file_lock &other)
+ #else
+ void swap(file_lock &&other)
+ #endif
+ {
+ file_handle_t tmp = m_file_hnd;
+ other.m_file_hnd = other.m_file_hnd;
+ other.m_file_hnd = tmp;
+ }
    
    //Exclusive locking
 
@@ -266,7 +330,6 @@
 }
 
 } //namespace interprocess {
-
 } //namespace boost {
 
 #include <boost/interprocess/detail/config_end.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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -104,9 +104,9 @@
    /// @cond
    private:
    #if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
- interprocess_mutex m_mutex;
- unsigned int m_nLockCount;
- detail::OS_thread_id_t m_nOwner;
+ interprocess_mutex m_mutex;
+ unsigned int m_nLockCount;
+ detail::OS_systemwide_thread_id_t m_nOwner;
    #else //#if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION)
    pthread_mutex_t m_mut;
    #endif //#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -28,26 +28,24 @@
 
 namespace interprocess {
 
-namespace detail{
- //!Type to indicate to a mutex lock constructor that must not lock the mutex.
- struct defer_lock_type{};
- //!Type to indicate to a mutex lock constructor that must try to lock the mutex.
- struct try_to_lock_type {};
- //!Type to indicate to a mutex lock constructor that the mutex is already locked.
- struct accept_ownership_type{};
-} //namespace detail{
+//!Type to indicate to a mutex lock constructor that must not lock the mutex.
+struct defer_lock_type{};
+//!Type to indicate to a mutex lock constructor that must try to lock the mutex.
+struct try_to_lock_type {};
+//!Type to indicate to a mutex lock constructor that the mutex is already locked.
+struct accept_ownership_type{};
 
 //!An object indicating that the locking
 //!must be deferred.
-static const detail::defer_lock_type defer_lock = detail::defer_lock_type();
+static const defer_lock_type defer_lock = defer_lock_type();
 
 //!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();
+static const try_to_lock_type try_to_lock = try_to_lock_type();
 
 //!An object indicating that the ownership of lockable
 //!object must be accepted by the new owner.
-static const detail::accept_ownership_type accept_ownership = detail::accept_ownership_type();
+static const accept_ownership_type accept_ownership = accept_ownership_type();
 
 } // namespace interprocess {
 } // namespace boost{

Modified: branches/release/boost/interprocess/sync/scoped_lock.hpp
==============================================================================
--- branches/release/boost/interprocess/sync/scoped_lock.hpp (original)
+++ branches/release/boost/interprocess/sync/scoped_lock.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -80,14 +80,14 @@
    //!Postconditions: owns() == false, and mutex() == &m.
    //!Notes: The constructor will not take ownership of the mutex. There is no effect
    //! required on the referenced mutex.
- scoped_lock(mutex_type& m, detail::defer_lock_type)
+ scoped_lock(mutex_type& m, defer_lock_type)
       : mp_mutex(&m), m_locked(false)
    {}
 
    //!Postconditions: owns() == true, and mutex() == &m.
    //!Notes: The constructor will suppose that the mutex is already locked. There
    //! is no effect required on the referenced mutex.
- scoped_lock(mutex_type& m, detail::accept_ownership_type)
+ scoped_lock(mutex_type& m, accept_ownership_type)
       : mp_mutex(&m), m_locked(true)
    {}
 
@@ -99,7 +99,7 @@
    //! locking depends upon the mutex. If the mutex_type does not support try_lock,
    //! this constructor will fail at compile time if instantiated, but otherwise
    //! have no effect.
- scoped_lock(mutex_type& m, detail::try_to_lock_type)
+ scoped_lock(mutex_type& m, try_to_lock_type)
       : mp_mutex(&m), m_locked(mp_mutex->try_lock())
    {}
 
@@ -125,12 +125,11 @@
    //! can be moved with the expression: "detail::move_impl(lock);". This
    //! constructor does not alter the state of the mutex, only potentially
    //! who owns it.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    scoped_lock(detail::moved_object<scoped_lock<Mutex> > scop)
       : mp_mutex(0), m_locked(scop.get().owns())
    { mp_mutex = scop.get().release(); }
    #else
-
    scoped_lock(scoped_lock &&scop)
       : mp_mutex(0), m_locked(scop.owns())
    { mp_mutex = scop.release(); }
@@ -148,7 +147,7 @@
    //! the expression: "detail::move_impl(lock);" This constructor may block if
    //! other threads hold a sharable_lock on this mutex (sharable_lock's can
    //! share ownership with an upgradable_lock).
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr)
       : mp_mutex(0), m_locked(false)
    {
@@ -187,9 +186,9 @@
    //! first place, the mutex merely changes type to an unlocked "write lock".
    //! If the "read lock" is held, then mutex transfer occurs only if it can
    //! do so in a non-blocking manner.*/
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
- ,detail::try_to_lock_type)
+ ,try_to_lock_type)
       : mp_mutex(0), m_locked(false)
    {
       upgradable_lock<mutex_type> &u_lock = upgr.get();
@@ -204,7 +203,7 @@
    }
    #else
    scoped_lock(upgradable_lock<Mutex> &&upgr
- ,detail::try_to_lock_type)
+ ,try_to_lock_type)
       : mp_mutex(0), m_locked(false)
    {
       upgradable_lock<mutex_type> &u_lock = upgr;
@@ -233,7 +232,7 @@
    //! "write lock". If the "read lock" isn't held in the first place, the mutex
    //! merely changes type to an unlocked "write lock". If the "read lock" is held,
    //! then mutex transfer occurs only if it can do so in a non-blocking manner.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr
               ,boost::posix_time::ptime &abs_time)
       : mp_mutex(0), m_locked(false)
@@ -280,9 +279,9 @@
    //! first place, the mutex merely changes type to an unlocked "write lock".
    //! If the "read lock" is held, then mutex transfer occurs only if it can
    //! do so in a non-blocking manner.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    scoped_lock(detail::moved_object<sharable_lock<Mutex> > shar
- ,detail::try_to_lock_type)
+ ,try_to_lock_type)
       : mp_mutex(0), m_locked(false)
    {
       sharable_lock<mutex_type> &s_lock = shar.get();
@@ -297,7 +296,7 @@
    }
    #else
    scoped_lock(sharable_lock<Mutex> &&shar
- ,detail::try_to_lock_type)
+ ,try_to_lock_type)
       : mp_mutex(0), m_locked(false)
    {
       sharable_lock<mutex_type> &s_lock = shar;
@@ -326,7 +325,7 @@
    //! the same mutex before the assignment. In this case, this will own the
    //! mutex after the assignment (and scop will not), but the mutex's lock
    //! count will be decremented by one.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    scoped_lock &operator=(detail::moved_object<scoped_lock> scop)
    {
       if(this->owns())
@@ -430,7 +429,7 @@
  
    //!Effects: Swaps state with moved lock.
    //!Throws: Nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    void swap(detail::moved_object<scoped_lock<mutex_type> > other)
    {
       std::swap(mp_mutex, other.get().mp_mutex);

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -86,14 +86,14 @@
    //!Postconditions: owns() == false, and mutex() == &m.
    //!Notes: The constructor will not take ownership of the mutex. There is no effect
    //! required on the referenced mutex.
- sharable_lock(mutex_type& m, detail::defer_lock_type)
+ sharable_lock(mutex_type& m, defer_lock_type)
       : mp_mutex(&m), m_locked(false)
    {}
 
    //!Postconditions: owns() == true, and mutex() == &m.
    //!Notes: The constructor will suppose that the mutex is already sharable
    //! locked. There is no effect required on the referenced mutex.
- sharable_lock(mutex_type& m, detail::accept_ownership_type)
+ sharable_lock(mutex_type& m, accept_ownership_type)
       : mp_mutex(&m), m_locked(true)
    {}
 
@@ -105,7 +105,7 @@
    //! recursive locking depends upon the mutex. If the mutex_type does not
    //! support try_lock_sharable, this constructor will fail at compile
    //! time if instantiated, but otherwise have no effect.
- sharable_lock(mutex_type& m, detail::try_to_lock_type)
+ sharable_lock(mutex_type& m, try_to_lock_type)
       : mp_mutex(&m), m_locked(false)
    { m_locked = mp_mutex->try_lock_sharable(); }
 
@@ -129,7 +129,7 @@
    //! signature. An non-moved sharable_lock can be moved with the expression:
    //! "detail::move_impl(lock);". This constructor does not alter the state of the mutex,
    //! only potentially who owns it.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    sharable_lock(detail::moved_object<sharable_lock<mutex_type> > upgr)
       : mp_mutex(0), m_locked(upgr.get().owns())
    { mp_mutex = upgr.get().release(); }
@@ -148,7 +148,7 @@
    //! unlocking upgr. Only a moved sharable_lock's will match this
    //! signature. An non-moved upgradable_lock can be moved with the expression:
    //! "detail::move_impl(lock);".*/
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    sharable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
       : mp_mutex(0), m_locked(false)
    {
@@ -182,7 +182,7 @@
    //! Only a moved scoped_lock's will match this
    //! signature. An non-moved scoped_lock can be moved with the expression:
    //! "detail::move_impl(lock);".*/
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    sharable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
       : mp_mutex(0), m_locked(false)
    {
@@ -221,7 +221,7 @@
    //!Notes: With a recursive mutex it is possible that both this and upgr own the mutex
    //! before the assignment. In this case, this will own the mutex after the assignment
    //! (and upgr will not), but the mutex's lock count will be decremented by one.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    sharable_lock &operator=(detail::moved_object<sharable_lock<mutex_type> > upgr)
    {
       if(this->owns())
@@ -328,7 +328,7 @@
 
    //!Effects: Swaps state with moved lock.
    //!Throws: Nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    void swap(detail::moved_object<sharable_lock<mutex_type> > other)
    {
       std::swap(mp_mutex, other.get().mp_mutex);

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -78,14 +78,14 @@
    //!Postconditions: owns() == false, and mutex() == &m.
    //!Notes: The constructor will not take ownership of the mutex. There is no effect
    //! required on the referenced mutex.
- upgradable_lock(mutex_type& m, detail::defer_lock_type)
+ upgradable_lock(mutex_type& m, defer_lock_type)
       : mp_mutex(&m), m_locked(false)
    {}
 
    //!Postconditions: owns() == true, and mutex() == &m.
    //!Notes: The constructor will suppose that the mutex is already upgradable
    //! locked. There is no effect required on the referenced mutex.
- upgradable_lock(mutex_type& m, detail::accept_ownership_type)
+ upgradable_lock(mutex_type& m, accept_ownership_type)
       : mp_mutex(&m), m_locked(true)
    {}
 
@@ -97,7 +97,7 @@
    //! handles recursive locking depends upon the mutex. If the mutex_type
    //! does not support try_lock_upgradable, this constructor will fail at
    //! compile time if instantiated, but otherwise have no effect.
- upgradable_lock(mutex_type& m, detail::try_to_lock_type)
+ upgradable_lock(mutex_type& m, try_to_lock_type)
       : mp_mutex(&m), m_locked(false)
    { m_locked = mp_mutex->try_lock_upgradable(); }
 
@@ -123,7 +123,7 @@
    //! signature. An non-moved upgradable_lock can be moved with the
    //! expression: "detail::move_impl(lock);". This constructor does not alter the
    //! state of the mutex, only potentially who owns it.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    upgradable_lock(detail::moved_object<upgradable_lock<mutex_type> > upgr)
       : mp_mutex(0), m_locked(upgr.get().owns())
    { mp_mutex = upgr.get().release(); }
@@ -142,7 +142,7 @@
    //! Only a moved sharable_lock's will match this
    //! signature. An non-moved sharable_lock can be moved with the
    //! expression: "detail::move_impl(lock);".
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    upgradable_lock(detail::moved_object<scoped_lock<mutex_type> > scop)
       : mp_mutex(0), m_locked(false)
    {
@@ -181,9 +181,9 @@
    //! in the first place, the mutex merely changes type to an unlocked
    //! "upgradable lock". If the "read lock" is held, then mutex transfer
    //! occurs only if it can do so in a non-blocking manner.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    upgradable_lock( detail::moved_object<sharable_lock<mutex_type> > shar
- , detail::try_to_lock_type)
+ , try_to_lock_type)
       : mp_mutex(0), m_locked(false)
    {
       sharable_lock<mutex_type> &s_lock = shar.get();
@@ -198,7 +198,7 @@
    }
    #else
    upgradable_lock( sharable_lock<mutex_type> &&shar
- , detail::try_to_lock_type)
+ , try_to_lock_type)
       : mp_mutex(0), m_locked(false)
    {
       sharable_lock<mutex_type> &s_lock = shar;
@@ -229,7 +229,7 @@
    //! mutex before the assignment. In this case, this will own the mutex
    //! after the assignment (and upgr will not), but the mutex's upgradable lock
    //! count will be decremented by one.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    upgradable_lock &operator=(detail::moved_object<upgradable_lock<mutex_type> > upgr)
    {
       if(this->owns())
@@ -336,7 +336,7 @@
 
    //!Effects: Swaps state with moved lock.
    //!Throws: Nothing.
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    void swap(detail::moved_object<upgradable_lock<mutex_type> > other)
    {
       std::swap(mp_mutex, other.get().mp_mutex);

Modified: branches/release/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- branches/release/boost/interprocess/windows_shared_memory.hpp (original)
+++ branches/release/boost/interprocess/windows_shared_memory.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -81,7 +81,7 @@
    //!Moves the ownership of "moved"'s shared memory object to *this.
    //!After the call, "moved" does not represent any shared memory object.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    windows_shared_memory
       (detail::moved_object<windows_shared_memory> moved)
    { this->swap(moved.get()); }
@@ -93,22 +93,17 @@
    //!Moves the ownership of "moved"'s shared memory to *this.
    //!After the call, "moved" does not represent any shared memory.
    //!Does not throw
- #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
+ #if !defined(BOOST_INTERPROCESS_RVALUE_REFERENCE) && !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
    windows_shared_memory &operator=
       (detail::moved_object<windows_shared_memory> moved)
- {
- windows_shared_memory tmp(moved);
- this->swap(tmp);
- return *this;
- }
    #else
    windows_shared_memory &operator=(windows_shared_memory &&moved)
+ #endif
    {
       windows_shared_memory tmp(detail::move_impl(moved));
       this->swap(tmp);
       return *this;
    }
- #endif
 
    //!Swaps to shared_memory_objects. Does not throw
    void swap(windows_shared_memory &other);

Modified: branches/release/boost/intrusive/any_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/any_hook.hpp (original)
+++ branches/release/boost/intrusive/any_hook.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -309,7 +309,7 @@
 {};
 
 //!This option setter specifies that
-//!any hook should behave as a set hook
+//!any hook should behave as an avl_set hook
 template<class BaseHook>
 struct any_to_avl_set_hook
 /// @cond
@@ -318,7 +318,7 @@
 {};
 
 //!This option setter specifies that any
-//!hook should behave as a set hook
+//!hook should behave as a bs_set hook
 template<class BaseHook>
 struct any_to_bs_set_hook
 /// @cond

Modified: branches/release/boost/intrusive/avl_set.hpp
==============================================================================
--- branches/release/boost/intrusive/avl_set.hpp (original)
+++ branches/release/boost/intrusive/avl_set.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,6 +15,7 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/avltree.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <iterator>
 
 namespace boost {
@@ -342,7 +343,7 @@
 
    //! <b>Requires</b>: value must be an lvalue
    //!
- //! <b>Effects</b>: Tries to inserts value into the avl_set.
+ //! <b>Effects</b>: Treaps to inserts value into the avl_set.
    //!
    //! <b>Returns</b>: If the value
    //! is not already present inserts it and returns a pair containing the
@@ -362,7 +363,7 @@
 
    //! <b>Requires</b>: value must be an lvalue
    //!
- //! <b>Effects</b>: Tries to to insert x into the avl_set, using "hint"
+ //! <b>Effects</b>: Treaps to to insert x into the avl_set, using "hint"
    //! as a hint to where it will be inserted.
    //!
    //! <b>Returns</b>: An iterator that points to the position where the
@@ -380,7 +381,7 @@
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
    //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an aavlitrary key with the contained values.
+ //! key_value_comp compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the avl_set, using
    //! a user provided key instead of the value itself.
@@ -415,7 +416,7 @@
 
    //! <b>Requires</b>: key_value_comp must be a comparison function that induces
    //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an aavlitrary key with the contained values.
+ //! key_value_comp compares an arbitrary key with the contained values.
    //!
    //! <b>Effects</b>: Checks if a value can be inserted in the avl_set, using
    //! a user provided key instead of the value itself, using "hint"
@@ -498,7 +499,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -512,7 +513,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -540,7 +541,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -557,9 +562,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -575,7 +586,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -610,7 +621,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -1527,7 +1542,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1541,7 +1556,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -1569,7 +1584,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1586,9 +1605,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased elements.
@@ -1604,7 +1629,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1639,7 +1664,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.

Modified: 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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/avltree.hpp
==============================================================================
--- branches/release/boost/intrusive/avltree.hpp (original)
+++ branches/release/boost/intrusive/avltree.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -26,7 +26,9 @@
 #include <boost/intrusive/detail/avltree_node.hpp>
 #include <boost/intrusive/detail/tree_node.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/avltree_algorithms.hpp>
 #include <boost/intrusive/link_mode.hpp>
@@ -77,7 +79,9 @@
 template<class Config>
 #endif
 class avltree_impl
+ : private detail::clear_on_destructor_base<avltree_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    public:
    typedef typename Config::value_traits value_traits;
    /// @cond
@@ -200,9 +204,11 @@
    //!
    //! <b>Complexity</b>: Constant.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
- avltree_impl( value_compare cmp = value_compare()
- , const value_traits &v_traits = value_traits())
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor of the value_compare object throws. Basic guarantee.
+ avltree_impl( const value_compare &cmp = value_compare()
+ , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
       node_algorithms::init_header(&priv_header());
@@ -218,10 +224,12 @@
    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
    //! comp and otherwise N * log N, where N is the distance between first and last.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
    template<class Iterator>
    avltree_impl( bool unique, Iterator b, Iterator e
- , value_compare cmp = value_compare()
+ , const value_compare &cmp = value_compare()
               , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
@@ -237,11 +245,11 @@
    //! are not deleted (i.e. no destructors are called), but the nodes according to
    //! the value_traits template parameter are reinitialized and thus can be reused.
    //!
- //! <b>Complexity</b>: Linear to elements contained in *this.
+ //! <b>Complexity</b>: Linear to elements contained in *this.
    //!
    //! <b>Throws</b>: Nothing.
    ~avltree_impl()
- { this->clear(); }
+ {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
    //!
@@ -397,7 +405,7 @@
    value_compare value_comp() const
    { return priv_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -407,7 +415,8 @@
 
    //! <b>Effects</b>: Returns the number of elements stored in the tree.
    //!
- //! <b>Complexity</b>: Linear to elements contained in *this.
+ //! <b>Complexity</b>: Linear to elements contained in *this
+ //! if constant-time size option is disabled. Constant time otherwise.
    //!
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -419,7 +428,7 @@
       }
    }
 
- //! <b>Effects</b>: Swaps the contents of two multisets.
+ //! <b>Effects</b>: Swaps the contents of two avltrees.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -445,7 +454,7 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -471,7 +480,7 @@
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -524,7 +533,7 @@
    std::pair<iterator, bool> insert_unique(reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), commit_data);
       if(!ret.second)
          return ret;
       return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
@@ -547,7 +556,7 @@
    iterator insert_unique(const_iterator hint, reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), commit_data);
       if(!ret.second)
          return ret.first;
       return insert_unique_commit(value, commit_data);
@@ -580,10 +589,36 @@
       }
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Average complexity is at most logarithmic.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! node that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that
+ //! part to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This gives a total
+ //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
@@ -596,10 +631,38 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_iterator hint, const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(hint, value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself, using "hint"
+ //! as a hint to where it will be inserted.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but it's amortized
+ //! constant time if t is inserted immediately before hint.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! constructing that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that key
+ //! to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This can give a total
+ //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const_iterator hint, const KeyType &key
@@ -613,6 +676,23 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
+ //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
+ //! must have been obtained from a previous call to "insert_check".
+ //! No objects should have been inserted or erased from the container between
+ //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
+ //!
+ //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
+ //! from the "commit_data" that a previous "insert_check" filled.
+ //!
+ //! <b>Returns</b>: An iterator to the newly inserted object.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: This function has only sense if a "insert_check" has been
+ //! previously executed to fill "commit_data". No value should be inserted or
+ //! erased between the "insert_check" and "insert_commit" calls.
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
       node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
@@ -632,9 +712,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    {
- iterator ret(i);
+ const_iterator ret(i);
       ++ret;
       node_ptr to_erase(i.pointed_node());
       if(safemode_or_autounlink)
@@ -643,7 +723,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
- return ret;
+ return ret.unconst();
    }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -655,7 +735,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { size_type n; return private_erase(b, e, n); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -683,7 +763,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -703,7 +787,7 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    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());
       iterator ret(this->erase(i));
@@ -711,6 +795,12 @@
       return ret;
    }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -724,7 +814,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)
    { size_type n; return private_erase(b, e, n, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -764,7 +854,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -1212,20 +1306,21 @@
 */
 
    /// @cond
+
    private:
    template<class Disposer>
- iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
    {
       for(n = 0; b != e; ++n)
         this->erase_and_dispose(b++, disposer);
- return b;
+ return b.unconst();
    }
 
- iterator private_erase(iterator b, iterator e, size_type &n)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n)
    {
       for(n = 0; b != e; ++n)
         this->erase(b++);
- return b;
+ return b.unconst();
    }
    /// @endcond
 
@@ -1446,8 +1541,8 @@
    //Assert if passed value traits are compatible with the type
    BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
 
- avltree( const value_compare &cmp = value_compare()
- , const value_traits &v_traits = value_traits())
+ avltree( const value_compare &cmp = value_compare()
+ , const value_traits &v_traits = value_traits())
       : Base(cmp, v_traits)
    {}
 

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/circular_list_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/circular_list_algorithms.hpp (original)
+++ branches/release/boost/intrusive/circular_list_algorithms.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/derivation_value_traits.hpp
==============================================================================
--- branches/release/boost/intrusive/derivation_value_traits.hpp (original)
+++ branches/release/boost/intrusive/derivation_value_traits.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/assert.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/assert.hpp (original)
+++ branches/release/boost/intrusive/detail/assert.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/config_begin.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/config_begin.hpp (original)
+++ branches/release/boost/intrusive/detail/config_begin.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -44,6 +44,8 @@
    #pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data
    #pragma warning (disable : 4127) //conditional expression is constant
    #pragma warning (disable : 4706) //assignment within conditional expression
+ #pragma warning (disable : 4541) //'typeid' used on polymorphic type 'boost::exception' with /GR-
+ #pragma warning (disable : 4512) //'typeid' used on polymorphic type 'boost::exception' with /GR-
 #endif
 
 //#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE

Modified: branches/release/boost/intrusive/detail/config_end.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/config_end.hpp (original)
+++ branches/release/boost/intrusive/detail/config_end.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/ebo_functor_holder.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/ebo_functor_holder.hpp (original)
+++ branches/release/boost/intrusive/detail/ebo_functor_holder.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Joaquin M Lopez Munoz 2006-2007
+// (C) Copyright Joaquin M Lopez Munoz 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/generic_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/generic_hook.hpp (original)
+++ branches/release/boost/intrusive/detail/generic_hook.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/hashtable_node.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/hashtable_node.hpp (original)
+++ branches/release/boost/intrusive/detail/hashtable_node.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/list_node.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/list_node.hpp (original)
+++ branches/release/boost/intrusive/detail/list_node.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/mpl.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/mpl.hpp (original)
+++ branches/release/boost/intrusive/detail/mpl.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -129,7 +129,7 @@
 #define BOOST_INTRUSIVE_TT_DECL
 #endif
 
-#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__)
+#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64)
 #define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
 #endif
 

Modified: branches/release/boost/intrusive/detail/parent_from_member.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/parent_from_member.hpp (original)
+++ branches/release/boost/intrusive/detail/parent_from_member.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/rbtree_node.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/rbtree_node.hpp (original)
+++ branches/release/boost/intrusive/detail/rbtree_node.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007.
+// (C) Copyright Ion Gaztanaga 2006-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/transform_iterator.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/transform_iterator.hpp (original)
+++ branches/release/boost/intrusive/detail/transform_iterator.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/detail/tree_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/tree_algorithms.hpp (original)
+++ branches/release/boost/intrusive/detail/tree_algorithms.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -721,22 +721,6 @@
 
    static bool is_header(const_node_ptr p)
    {
-/*
- node_ptr p_parent = NodeTraits::get_parent(p);
- if(!p_parent)
- return true;
- if(!NodeTraits::get_parent(p_parent) != p)
- return false;
- if(NodeTraits::get_left(p) != 0){
- if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){
- is_header = true;
- }
- if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){
- is_header = true;
- }
- }
-*/
-
       bool is_header = false;
       if(NodeTraits::get_parent(p) == p){
          is_header = true;
@@ -1015,42 +999,71 @@
       }
    }
 
- //! <b>Requires</b>: "header" must be the header node of a tree.
- //! NodePtrCompare is a function object that induces a strict weak
- //! ordering compatible with the strict weak ordering used to create the
- //! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
- //! the "header"'s tree.
- //!
- //! <b>Effects</b>: Inserts new_node into the tree, using "hint" as a hint to
- //! where it will be inserted. If "hint" is the upper_bound
- //! the insertion takes constant time (two comparisons in the worst case).
- //!
- //! <b>Complexity</b>: Logarithmic in general, but it is amortized
- //! constant time if new_node is inserted immediately before "hint".
- //!
- //! <b>Throws</b>: If "comp" throws.
    template<class NodePtrCompare>
- static node_ptr insert_equal
- (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
+ static void insert_equal_check
+ ( node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp
+ , insert_commit_data &commit_data, std::size_t *pdepth = 0)
    {
       if(hint == header || !comp(hint, new_node)){
          node_ptr prev(hint);
          if(hint == NodeTraits::get_left(header) ||
             !comp(new_node, (prev = prev_node(hint)))){
             bool link_left = unique(header) || !NodeTraits::get_left(hint);
- link(header, new_node, link_left ? hint : prev, link_left);
- if(pdepth) *pdepth = depth(new_node) + 1;
- return new_node;
+ commit_data.link_left = link_left;
+ commit_data.node = link_left ? hint : prev;
+ if(pdepth){
+ *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1;
+ }
          }
          else{
- return insert_equal_upper_bound(header, new_node, comp, pdepth);
+ insert_equal_upper_bound_check(header, new_node, comp, commit_data, pdepth);
          }
       }
       else{
- return insert_equal_lower_bound(header, new_node, comp, pdepth);
+ insert_equal_lower_bound_check(header, new_node, comp, commit_data, pdepth);
       }
    }
 
+ template<class NodePtrCompare>
+ static void insert_equal_upper_bound_check
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
+ { insert_equal_check_impl(true, h, new_node, comp, commit_data, pdepth); }
+
+ template<class NodePtrCompare>
+ static void insert_equal_lower_bound_check
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
+ { insert_equal_check_impl(false, h, new_node, comp, commit_data, pdepth); }
+
+ template<class NodePtrCompare>
+ static node_ptr insert_equal
+ (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ insert_equal_check(h, hint, new_node, comp, commit_data, pdepth);
+ link(h, new_node, commit_data.node, commit_data.link_left);
+ return new_node;
+ }
+
+ template<class NodePtrCompare>
+ static node_ptr insert_equal_upper_bound
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth);
+ link(h, new_node, commit_data.node, commit_data.link_left);
+ return new_node;
+ }
+
+ template<class NodePtrCompare>
+ static node_ptr insert_equal_lower_bound
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth);
+ link(h, new_node, commit_data.node, commit_data.link_left);
+ return new_node;
+ }
+
    //! <b>Requires</b>: p can't be a header node.
    //!
    //! <b>Effects</b>: Calculates the depth of a node: the depth of a
@@ -1071,48 +1084,6 @@
       return depth;
    }
 
- template<class NodePtrCompare>
- static node_ptr insert_equal_upper_bound
- (node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
- {
- std::size_t depth = 0;
- node_ptr y(h);
- node_ptr x(NodeTraits::get_parent(y));
-
- while(x){
- ++depth;
- y = x;
- x = comp(new_node, x) ?
- NodeTraits::get_left(x) : NodeTraits::get_right(x);
- }
-
- bool link_left = (y == h) || comp(new_node, y);
- link(h, new_node, y, link_left);
- if(pdepth) *pdepth = depth;
- return new_node;
- }
-
- template<class NodePtrCompare>
- static node_ptr insert_equal_lower_bound
- (node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
- {
- std::size_t depth = 0;
- node_ptr y(h);
- node_ptr x(NodeTraits::get_parent(y));
-
- while(x){
- ++depth;
- y = x;
- x = !comp(x, new_node) ?
- NodeTraits::get_left(x) : NodeTraits::get_right(x);
- }
-
- bool link_left = (y == h) || !comp(y, new_node);
- link(h, new_node, y, link_left);
- if(pdepth) *pdepth = depth;
- return new_node;
- }
-
    //! <b>Requires</b>: "cloner" must be a function
    //! object taking a node_ptr and returning a new cloned node of it. "disposer" must
    //! take a node_ptr and shouldn't throw.
@@ -1557,6 +1528,39 @@
    }
 
    private:
+ template<class NodePtrCompare>
+ static void insert_equal_check_impl
+ (bool upper, node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
+ {
+ std::size_t depth = 0;
+ node_ptr y(h);
+ node_ptr x(NodeTraits::get_parent(y));
+ bool link_left;
+
+ if(upper){
+ while(x){
+ ++depth;
+ y = x;
+ x = comp(new_node, x) ?
+ NodeTraits::get_left(x) : NodeTraits::get_right(x);
+ }
+ link_left = (y == h) || comp(new_node, y);
+ }
+ else{
+ while(x){
+ ++depth;
+ y = x;
+ x = !comp(x, new_node) ?
+ NodeTraits::get_left(x) : NodeTraits::get_right(x);
+ }
+ link_left = (y == h) || !comp(y, new_node);
+ }
+
+ commit_data.link_left = link_left;
+ commit_data.node = y;
+ if(pdepth) *pdepth = depth;
+ }
+
    static void erase_impl(node_ptr header, node_ptr z, data_for_rebalance &info)
    {
       node_ptr y(z);

Modified: branches/release/boost/intrusive/detail/tree_node.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/tree_node.hpp (original)
+++ branches/release/boost/intrusive/detail/tree_node.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -173,6 +173,9 @@
       return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_container());
    }
 
+ tree_iterator<Container, false> unconst() const
+ { return tree_iterator<Container, false>(this->pointed_node(), this->get_container()); }
+
    private:
    struct members
       : public detail::select_constptr

Modified: branches/release/boost/intrusive/detail/utilities.hpp
==============================================================================
--- branches/release/boost/intrusive/detail/utilities.hpp (original)
+++ branches/release/boost/intrusive/detail/utilities.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -211,20 +211,25 @@
 {
    typedef typename Container::real_value_traits real_value_traits;
    typedef typename real_value_traits::node_ptr node_ptr;
+ typedef typename real_value_traits::const_node_ptr const_node_ptr;
    typedef detail::ebo_functor_holder<KeyValueCompare> base_t;
    key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont)
       : base_t(kcomp), cont_(cont)
    {}
 
    template<class KeyType>
- bool operator()(node_ptr node, const KeyType &key) const
+ bool operator()( const_node_ptr node, const KeyType &key
+ , typename enable_if_c
+ <!is_convertible<KeyType, const_node_ptr>::value>::type * = 0) const
    { return base_t::get()(*cont_->get_real_value_traits().to_value_ptr(node), key); }
 
    template<class KeyType>
- bool operator()(const KeyType &key, node_ptr node) const
+ bool operator()(const KeyType &key, const_node_ptr node
+ , typename enable_if_c
+ <!is_convertible<KeyType, const_node_ptr>::value>::type * = 0) const
    { return base_t::get()(key, *cont_->get_real_value_traits().to_value_ptr(node)); }
 
- bool operator()(node_ptr node1, node_ptr node2) const
+ bool operator()(const_node_ptr node1, const_node_ptr node2) const
    {
       return base_t::get()
          ( *cont_->get_real_value_traits().to_value_ptr(node1)

Modified: branches/release/boost/intrusive/hashtable.hpp
==============================================================================
--- branches/release/boost/intrusive/hashtable.hpp (original)
+++ branches/release/boost/intrusive/hashtable.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -30,6 +30,7 @@
 #include <boost/intrusive/detail/transform_iterator.hpp>
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
 //Implementation utilities
 #include <boost/intrusive/trivial_value_traits.hpp>
 #include <boost/intrusive/unordered_set_hook.hpp>
@@ -572,7 +573,9 @@
 template<class Config>
 #endif
 class hashtable_impl
+ : private detail::clear_on_destructor_base<hashtable_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    public:
    typedef typename Config::value_traits value_traits;
 
@@ -795,7 +798,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    ~hashtable_impl()
- { this->clear(); }
+ {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
    //!
@@ -866,7 +869,7 @@
    key_equal key_eq() const
    { return this->priv_equal(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
    //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
@@ -1045,6 +1048,18 @@
       }
    }
 
+ //! <b>Requires</b>: value must be an lvalue
+ //!
+ //! <b>Effects</b>: Inserts the value into the unordered_set.
+ //!
+ //! <b>Returns</b>: An iterator to the inserted value.
+ //!
+ //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
+ //!
+ //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references.
+ //! No copy-constructors are called.
    iterator insert_equal(reference value)
    {
       size_type bucket_num;
@@ -1055,6 +1070,18 @@
       return priv_insert_equal_find(value, bucket_num, hash_value, it);
    }
 
+ //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
+ //! of type value_type.
+ //!
+ //! <b>Effects</b>: Equivalent to this->insert_equal(t) for each element in [b, e).
+ //!
+ //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e).
+ //! Worst case O(N*this->size()).
+ //!
+ //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
+ //!
+ //! <b>Note</b>: Does not affect the validity of iterators and references.
+ //! No copy-constructors are called.
    template<class Iterator>
    void insert_equal(Iterator b, Iterator e)
    {
@@ -1092,7 +1119,7 @@
    //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
    //! of type value_type.
    //!
- //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
+ //! <b>Effects</b>: Equivalent to this->insert_unique(t) for each element in [b, e).
    //!
    //! <b>Complexity</b>: Average case O(N), where N is std::distance(b, e).
    //! Worst case O(N*this->size()).
@@ -1275,6 +1302,12 @@
       priv_erasure_update_cache();
    }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.

Modified: branches/release/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- branches/release/boost/intrusive/intrusive_fwd.hpp (original)
+++ branches/release/boost/intrusive/intrusive_fwd.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -311,6 +311,51 @@
 #endif
 class avl_set_member_hook;
 
+
+//treap/treap_set/treap_multiset
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
+template
+ < class T
+ , class O1 = none
+ , class O2 = none
+ , class O3 = none
+ , class O4 = none
+ >
+#else
+template<class T, class ...Options>
+#endif
+class treap;
+
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
+template
+ < class T
+ , class O1 = none
+ , class O2 = none
+ , class O3 = none
+ , class O4 = none
+ >
+#else
+template<class T, class ...Options>
+#endif
+class treap_set;
+
+#ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
+template
+ < class T
+ , class O1 = none
+ , class O2 = none
+ , class O3 = none
+ , class O4 = none
+ >
+#else
+template<class T, class ...Options>
+#endif
+class treap_multiset;
+
+//Default priority comparison functor
+template <class T>
+struct priority_compare;
+
 //sgtree/sg_set/sg_multiset
 #ifndef BOOST_INTRUSIVE_VARIADIC_TEMPLATES
 template

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/link_mode.hpp
==============================================================================
--- branches/release/boost/intrusive/link_mode.hpp (original)
+++ branches/release/boost/intrusive/link_mode.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/list.hpp
==============================================================================
--- branches/release/boost/intrusive/list.hpp (original)
+++ branches/release/boost/intrusive/list.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,7 @@
 #include <boost/intrusive/list_hook.hpp>
 #include <boost/intrusive/circular_list_algorithms.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/static_assert.hpp>
@@ -72,7 +73,9 @@
 template<class Config>
 #endif
 class list_impl
+ : private detail::clear_on_destructor_base< list_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    //Public typedefs
    public:
    typedef typename Config::value_traits value_traits;
@@ -219,11 +222,7 @@
    //! <b>Complexity</b>: Linear to the number of elements in the list, if
    //! it's a safe-mode or auto-unlink value . Otherwise constant.
    ~list_impl()
- {
- if(safemode_or_autounlink){
- this->clear();
- }
- }
+ {}
 
    //! <b>Requires</b>: value must be an lvalue.
    //!
@@ -651,6 +650,12 @@
       return i.unconst();
    }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the element range pointed by b and e

Modified: branches/release/boost/intrusive/list_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/list_hook.hpp (original)
+++ branches/release/boost/intrusive/list_hook.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/member_value_traits.hpp
==============================================================================
--- branches/release/boost/intrusive/member_value_traits.hpp (original)
+++ branches/release/boost/intrusive/member_value_traits.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/options.hpp
==============================================================================
--- branches/release/boost/intrusive/options.hpp (original)
+++ branches/release/boost/intrusive/options.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -278,6 +278,20 @@
 /// @endcond
 };
 
+//!This option setter specifies the equality
+//!functor for the value type
+template<class Priority>
+struct priority
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ typedef Priority priority;
+ };
+/// @endcond
+};
+
 //!This option setter specifies the hash
 //!functor for the value type
 template<class Hash>

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/rbtree.hpp
==============================================================================
--- branches/release/boost/intrusive/rbtree.hpp (original)
+++ branches/release/boost/intrusive/rbtree.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -26,7 +26,9 @@
 #include <boost/intrusive/detail/rbtree_node.hpp>
 #include <boost/intrusive/detail/tree_node.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/rbtree_algorithms.hpp>
 #include <boost/intrusive/link_mode.hpp>
@@ -77,7 +79,9 @@
 template<class Config>
 #endif
 class rbtree_impl
+ : private detail::clear_on_destructor_base<rbtree_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    public:
    typedef typename Config::value_traits value_traits;
    /// @cond
@@ -200,8 +204,10 @@
    //!
    //! <b>Complexity</b>: Constant.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
- rbtree_impl( value_compare cmp = value_compare()
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructorof the value_compare object throws. Basic guarantee.
+ rbtree_impl( const value_compare &cmp = value_compare()
               , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
@@ -218,10 +224,12 @@
    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
    //! comp and otherwise N * log N, where N is the distance between first and last.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
    template<class Iterator>
    rbtree_impl( bool unique, Iterator b, Iterator e
- , value_compare cmp = value_compare()
+ , const value_compare &cmp = value_compare()
               , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
@@ -241,7 +249,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    ~rbtree_impl()
- { this->clear(); }
+ {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
    //!
@@ -397,7 +405,7 @@
    value_compare value_comp() const
    { return priv_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -407,7 +415,8 @@
 
    //! <b>Effects</b>: Returns the number of elements stored in the tree.
    //!
- //! <b>Complexity</b>: Linear to elements contained in *this.
+ //! <b>Complexity</b>: Linear to elements contained in *this
+ //! if constant-time size option is disabled. Constant time otherwise.
    //!
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -419,7 +428,7 @@
       }
    }
 
- //! <b>Effects</b>: Swaps the contents of two multisets.
+ //! <b>Effects</b>: Swaps the contents of two rbtrees.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -445,7 +454,7 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -471,7 +480,7 @@
    //! <b>Complexity</b>: Logarithmic in general, but it is amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -524,7 +533,7 @@
    std::pair<iterator, bool> insert_unique(reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), commit_data);
       if(!ret.second)
          return ret;
       return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
@@ -547,7 +556,7 @@
    iterator insert_unique(const_iterator hint, reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), commit_data);
       if(!ret.second)
          return ret.first;
       return insert_unique_commit(value, commit_data);
@@ -580,10 +589,36 @@
       }
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Average complexity is at most logarithmic.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! node that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that
+ //! part to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This gives a total
+ //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
@@ -596,10 +631,38 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_iterator hint, const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(hint, value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself, using "hint"
+ //! as a hint to where it will be inserted.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but it's amortized
+ //! constant time if t is inserted immediately before hint.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! constructing that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that key
+ //! to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This can give a total
+ //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const_iterator hint, const KeyType &key
@@ -613,6 +676,23 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
+ //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
+ //! must have been obtained from a previous call to "insert_check".
+ //! No objects should have been inserted or erased from the container between
+ //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
+ //!
+ //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
+ //! from the "commit_data" that a previous "insert_check" filled.
+ //!
+ //! <b>Returns</b>: An iterator to the newly inserted object.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: This function has only sense if a "insert_check" has been
+ //! previously executed to fill "commit_data". No value should be inserted or
+ //! erased between the "insert_check" and "insert_commit" calls.
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
       node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
@@ -632,9 +712,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    {
- iterator ret(i);
+ const_iterator ret(i);
       ++ret;
       node_ptr to_erase(i.pointed_node());
       if(safemode_or_autounlink)
@@ -643,7 +723,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
- return ret;
+ return ret.unconst();
    }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -655,7 +735,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { size_type n; return private_erase(b, e, n); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -683,7 +763,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -703,7 +787,7 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    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());
       iterator ret(this->erase(i));
@@ -711,21 +795,11 @@
       return ret;
    }
 
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Complexity</b>: Average complexity for erase range is at most
- //! O(log(size() + N)), where N is the number of elements in the range.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
    template<class Disposer>
- iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
- { size_type n; return private_erase(b, e, n, disposer); }
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -751,6 +825,22 @@
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
+ //! <b>Effects</b>: Erases the range pointed to by b end e.
+ //! Disposer::operator()(pointer) is called for the removed elements.
+ //!
+ //! <b>Complexity</b>: Average complexity for erase range is at most
+ //! O(log(size() + N)), where N is the number of elements in the range.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Note</b>: Invalidates the iterators
+ //! to the erased elements.
+ template<class Disposer>
+ iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+ { size_type n; return private_erase(b, e, n, disposer); }
+
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //!
    //! <b>Effects</b>: Erases all the elements with the given key.
    //! according to the comparison functor "comp".
    //! Disposer::operator()(pointer) is called for the removed elements.
@@ -764,7 +854,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -1207,18 +1301,18 @@
    /// @cond
    private:
    template<class Disposer>
- iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
    {
       for(n = 0; b != e; ++n)
         this->erase_and_dispose(b++, disposer);
- return b;
+ return b.unconst();
    }
 
- iterator private_erase(iterator b, iterator e, size_type &n)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n)
    {
       for(n = 0; b != e; ++n)
         this->erase(b++);
- return b;
+ return b.unconst();
    }
    /// @endcond
 

Modified: branches/release/boost/intrusive/rbtree_algorithms.hpp
==============================================================================
--- branches/release/boost/intrusive/rbtree_algorithms.hpp (original)
+++ branches/release/boost/intrusive/rbtree_algorithms.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007.
+// (C) Copyright Ion Gaztanaga 2006-2008.
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/set.hpp
==============================================================================
--- branches/release/boost/intrusive/set.hpp (original)
+++ branches/release/boost/intrusive/set.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,6 +15,7 @@
 
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/rbtree.hpp>
 #include <iterator>
 
@@ -297,7 +298,7 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -499,7 +500,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -513,7 +514,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -541,7 +542,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -558,9 +563,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -576,7 +587,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -611,7 +622,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -1419,7 +1434,7 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1528,7 +1543,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1542,7 +1557,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -1570,7 +1585,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1587,9 +1606,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased elements.
@@ -1605,7 +1630,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1640,7 +1665,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.

Modified: branches/release/boost/intrusive/set_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/set_hook.hpp (original)
+++ branches/release/boost/intrusive/set_hook.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/sg_set.hpp
==============================================================================
--- branches/release/boost/intrusive/sg_set.hpp (original)
+++ branches/release/boost/intrusive/sg_set.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,6 +15,7 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/sgtree.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <iterator>
 
 namespace boost {
@@ -296,7 +297,7 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -498,7 +499,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -512,7 +513,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -540,7 +541,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -557,9 +562,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -575,7 +586,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -610,7 +621,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -1458,7 +1473,7 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1567,7 +1582,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1581,7 +1596,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -1609,7 +1624,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1626,9 +1645,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased elements.
@@ -1644,7 +1669,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1679,7 +1704,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.

Modified: branches/release/boost/intrusive/sgtree.hpp
==============================================================================
--- branches/release/boost/intrusive/sgtree.hpp (original)
+++ branches/release/boost/intrusive/sgtree.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,7 +24,7 @@
 #include <functional>
 #include <iterator>
 #include <utility>
-#include <boost/config/no_tr1/cmath.hpp>
+#include <cmath>
 #include <cstddef>
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/static_assert.hpp>
@@ -33,6 +33,8 @@
 #include <boost/intrusive/detail/tree_node.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/sgtree_algorithms.hpp>
 #include <boost/intrusive/link_mode.hpp>
@@ -204,7 +206,9 @@
 template<class Config>
 #endif
 class sgtree_impl
+ : private detail::clear_on_destructor_base<sgtree_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    public:
    typedef typename Config::value_traits value_traits;
    /// @cond
@@ -354,8 +358,10 @@
    //!
    //! <b>Complexity</b>: Constant.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
- sgtree_impl( value_compare cmp = value_compare()
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructorof the value_compare object throws. Basic guarantee.
+ sgtree_impl( const value_compare &cmp = value_compare()
               , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
@@ -372,10 +378,12 @@
    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
    //! comp and otherwise N * log N, where N is the distance between first and last.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
    template<class Iterator>
    sgtree_impl( bool unique, Iterator b, Iterator e
- , value_compare cmp = value_compare()
+ , const value_compare &cmp = value_compare()
               , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
@@ -395,7 +403,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    ~sgtree_impl()
- { this->clear(); }
+ {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
    //!
@@ -551,7 +559,7 @@
    value_compare value_comp() const
    { return priv_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -561,7 +569,8 @@
 
    //! <b>Effects</b>: Returns the number of elements stored in the tree.
    //!
- //! <b>Complexity</b>: Linear to elements contained in *this.
+ //! <b>Complexity</b>: Linear to elements contained in *this
+ //! if constant-time size option is disabled. Constant time otherwise.
    //!
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -573,7 +582,7 @@
       }
    }
 
- //! <b>Effects</b>: Swaps the contents of two multisets.
+ //! <b>Effects</b>: Swaps the contents of two sgtrees.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -601,7 +610,7 @@
    //! <b>Complexity</b>: Average complexity for insert element is at
    //! most logarithmic.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -688,7 +697,7 @@
    std::pair<iterator, bool> insert_unique(reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), commit_data);
       if(!ret.second)
          return ret;
       return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
@@ -711,7 +720,7 @@
    iterator insert_unique(const_iterator hint, reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), commit_data);
       if(!ret.second)
          return ret.first;
       return insert_unique_commit(value, commit_data);
@@ -744,10 +753,36 @@
       }
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Average complexity is at most logarithmic.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! node that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that
+ //! part to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This gives a total
+ //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
@@ -760,10 +795,38 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_iterator hint, const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(hint, value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself, using "hint"
+ //! as a hint to where it will be inserted.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but it's amortized
+ //! constant time if t is inserted immediately before hint.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! constructing that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that key
+ //! to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This can give a total
+ //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const_iterator hint, const KeyType &key
@@ -777,6 +840,23 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
+ //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
+ //! must have been obtained from a previous call to "insert_check".
+ //! No objects should have been inserted or erased from the container between
+ //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
+ //!
+ //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
+ //! from the "commit_data" that a previous "insert_check" filled.
+ //!
+ //! <b>Returns</b>: An iterator to the newly inserted object.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: This function has only sense if a "insert_check" has been
+ //! previously executed to fill "commit_data". No value should be inserted or
+ //! erased between the "insert_check" and "insert_commit" calls.
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
       node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
@@ -799,9 +879,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    {
- iterator ret(i);
+ const_iterator ret(i);
       ++ret;
       node_ptr to_erase(i.pointed_node());
       if(safemode_or_autounlink)
@@ -814,7 +894,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
- return ret;
+ return ret.unconst();
    }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -826,7 +906,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { size_type n; return private_erase(b, e, n); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -854,7 +934,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -874,7 +958,7 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    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());
       iterator ret(this->erase(i));
@@ -882,6 +966,12 @@
       return ret;
    }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -895,7 +985,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)
    { size_type n; return private_erase(b, e, n, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -935,7 +1025,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -1437,18 +1531,18 @@
    /// @cond
    private:
    template<class Disposer>
- iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
    {
       for(n = 0; b != e; ++n)
         this->erase_and_dispose(b++, disposer);
- return b;
+ return b.unconst();
    }
 
- iterator private_erase(iterator b, iterator e, size_type &n)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n)
    {
       for(n = 0; b != e; ++n)
         this->erase(b++);
- return b;
+ return b.unconst();
    }
    /// @endcond
 

Modified: branches/release/boost/intrusive/slist.hpp
==============================================================================
--- branches/release/boost/intrusive/slist.hpp (original)
+++ branches/release/boost/intrusive/slist.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -22,6 +22,7 @@
 #include <boost/intrusive/circular_slist_algorithms.hpp>
 #include <boost/intrusive/linear_slist_algorithms.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
@@ -102,7 +103,9 @@
 template<class Config>
 #endif
 class slist_impl
+ : private detail::clear_on_destructor_base<slist_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    //Public typedefs
    public:
    typedef typename Config::value_traits value_traits;
@@ -295,7 +298,7 @@
    //! <b>Complexity</b>: Linear to the number of elements in the list, if
    //! it's a safe-mode or auto-unlink value. Otherwise constant.
    ~slist_impl()
- { this->clear(); }
+ {}
 
    //! <b>Effects</b>: Erases all the elements of the container.
    //!
@@ -978,6 +981,12 @@
    iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return this->erase_after_and_dispose(this->previous(i), disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
    //! Disposer::operator()(pointer) shouldn't throw.
    //!

Modified: branches/release/boost/intrusive/slist_hook.hpp
==============================================================================
--- branches/release/boost/intrusive/slist_hook.hpp (original)
+++ branches/release/boost/intrusive/slist_hook.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/splay_set.hpp
==============================================================================
--- branches/release/boost/intrusive/splay_set.hpp (original)
+++ branches/release/boost/intrusive/splay_set.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -15,6 +15,7 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/splaytree.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <iterator>
 
 namespace boost {
@@ -296,7 +297,7 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -497,7 +498,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -511,7 +512,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -539,7 +540,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -556,9 +561,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -574,7 +585,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -609,7 +620,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+)
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.
@@ -1494,7 +1509,7 @@
    value_compare value_comp() const
    { return tree_.value_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -1602,7 +1617,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    { return tree_.erase(i); }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1616,7 +1631,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { return tree_.erase(b, e); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -1644,7 +1659,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase(key, comp); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1661,9 +1680,15 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return tree_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Returns</b>: An iterator to the element after the erased elements.
@@ -1679,7 +1704,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)
    { return tree_.erase_and_dispose(b, e, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1714,7 +1739,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    { return tree_.erase_and_dispose(key, comp, disposer); }
 
    //! <b>Effects</b>: Erases all the elements of the container.

Modified: 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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/splaytree.hpp
==============================================================================
--- branches/release/boost/intrusive/splaytree.hpp (original)
+++ branches/release/boost/intrusive/splaytree.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2007
+// (C) Copyright Ion Gaztanaga 2007-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -25,6 +25,8 @@
 #include <boost/intrusive/splay_set_hook.hpp>
 #include <boost/intrusive/detail/tree_node.hpp>
 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
+#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/splaytree_algorithms.hpp>
 #include <boost/intrusive/link_mode.hpp>
@@ -76,7 +78,9 @@
 template<class Config>
 #endif
 class splaytree_impl
+ : private detail::clear_on_destructor_base<splaytree_impl<Config> >
 {
+ template<class C> friend class detail::clear_on_destructor_base;
    public:
    typedef typename Config::value_traits value_traits;
    /// @cond
@@ -199,9 +203,11 @@
    //!
    //! <b>Complexity</b>: Constant.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
- splaytree_impl( value_compare cmp = value_compare()
- , const value_traits &v_traits = value_traits())
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructorof the value_compare object throws. Basic guarantee.
+ splaytree_impl( const value_compare &cmp = value_compare()
+ , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
       node_algorithms::init_header(&priv_header());
@@ -217,11 +223,13 @@
    //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
    //! comp and otherwise amortized N * log N, where N is the distance between first and last.
    //!
- //! <b>Throws</b>: Nothing unless the copy constructor of the value_compare object throws.
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
    template<class Iterator>
- splaytree_impl( bool unique, Iterator b, Iterator e
- , value_compare cmp = value_compare()
- , const value_traits &v_traits = value_traits())
+ splaytree_impl ( bool unique, Iterator b, Iterator e
+ , const value_compare &cmp = value_compare()
+ , const value_traits &v_traits = value_traits())
       : data_(cmp, v_traits)
    {
       node_algorithms::init_header(&priv_header());
@@ -241,7 +249,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    ~splaytree_impl()
- { this->clear(); }
+ {}
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the tree.
    //!
@@ -397,7 +405,7 @@
    value_compare value_comp() const
    { return priv_comp(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -407,7 +415,8 @@
 
    //! <b>Effects</b>: Returns the number of elements stored in the tree.
    //!
- //! <b>Complexity</b>: Linear to elements contained in *this.
+ //! <b>Complexity</b>: Linear to elements contained in *this
+ //! if constant-time size option is disabled. Constant time otherwise.
    //!
    //! <b>Throws</b>: Nothing.
    size_type size() const
@@ -420,7 +429,7 @@
       }
    }
 
- //! <b>Effects</b>: Swaps the contents of two multisets.
+ //! <b>Effects</b>: Swaps the contents of two splaytrees.
    //!
    //! <b>Complexity</b>: Constant.
    //!
@@ -446,7 +455,7 @@
    //! <b>Complexity</b>: Average complexity for insert element is amortized
    //! logarithmic.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -472,7 +481,7 @@
    //! <b>Complexity</b>: Amortized logarithmic in general, but it is amortized
    //! constant time if t is inserted immediately before hint.
    //!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
    //!
    //! <b>Note</b>: Does not affect the validity of iterators and references.
    //! No copy-constructors are called.
@@ -526,7 +535,7 @@
    std::pair<iterator, bool> insert_unique(reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(value, priv_comp(), commit_data);
       if(!ret.second)
          return ret;
       return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
@@ -549,7 +558,7 @@
    iterator insert_unique(const_iterator hint, reference value)
    {
       insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, commit_data);
+ std::pair<iterator, bool> ret = insert_unique_check(hint, value, priv_comp(), commit_data);
       if(!ret.second)
          return ret.first;
       return insert_unique_commit(value, commit_data);
@@ -575,10 +584,36 @@
          this->insert_unique(*b);
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Average complexity is at most logarithmic.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! node that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that
+ //! part to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This gives a total
+ //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
@@ -591,10 +626,38 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
- std::pair<iterator, bool> insert_unique_check
- (const_iterator hint, const_reference value, insert_commit_data &commit_data)
- { return insert_unique_check(hint, value, priv_comp(), commit_data); }
-
+ //! <b>Requires</b>: key_value_comp must be a comparison function that induces
+ //! the same strict weak ordering as value_compare. The difference is that
+ //! key_value_comp compares an arbitrary key with the contained values.
+ //!
+ //! <b>Effects</b>: Checks if a value can be inserted in the container, using
+ //! a user provided key instead of the value itself, using "hint"
+ //! as a hint to where it will be inserted.
+ //!
+ //! <b>Returns</b>: If there is an equivalent value
+ //! returns a pair containing an iterator to the already present value
+ //! and false. If the value can be inserted returns true in the returned
+ //! pair boolean and fills "commit_data" that is meant to be used with
+ //! the "insert_commit" function.
+ //!
+ //! <b>Complexity</b>: Logarithmic in general, but it's amortized
+ //! constant time if t is inserted immediately before hint.
+ //!
+ //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //!
+ //! <b>Notes</b>: This function is used to improve performance when constructing
+ //! a value_type is expensive: if there is an equivalent value
+ //! the constructed object must be discarded. Many times, the part of the
+ //! constructing that is used to impose the order is much cheaper to construct
+ //! than the value_type and this function offers the possibility to use that key
+ //! to check if the insertion will be successful.
+ //!
+ //! If the check is successful, the user can construct the value_type and use
+ //! "insert_commit" to insert the object in constant-time. This can give a total
+ //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
+ //!
+ //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
+ //! objects are inserted or erased from the container.
    template<class KeyType, class KeyValueCompare>
    std::pair<iterator, bool> insert_unique_check
       (const_iterator hint, const KeyType &key
@@ -608,6 +671,23 @@
       return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
    }
 
+ //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
+ //! must have been obtained from a previous call to "insert_check".
+ //! No objects should have been inserted or erased from the container between
+ //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
+ //!
+ //! <b>Effects</b>: Inserts the value in the avl_set using the information obtained
+ //! from the "commit_data" that a previous "insert_check" filled.
+ //!
+ //! <b>Returns</b>: An iterator to the newly inserted object.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Notes</b>: This function has only sense if a "insert_check" has been
+ //! previously executed to fill "commit_data". No value should be inserted or
+ //! erased between the "insert_check" and "insert_commit" calls.
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
       node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
@@ -627,9 +707,9 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator i)
+ iterator erase(const_iterator i)
    {
- iterator ret(i);
+ const_iterator ret(i);
       ++ret;
       node_ptr to_erase(i.pointed_node());
       if(safemode_or_autounlink)
@@ -638,7 +718,7 @@
       this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
- return ret;
+ return ret.unconst();
    }
 
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -650,7 +730,7 @@
    //!
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
- iterator erase(iterator b, iterator e)
+ iterator erase(const_iterator b, const_iterator e)
    { size_type n; return private_erase(b, e, n); }
 
    //! <b>Effects</b>: Erases all the elements with the given value.
@@ -678,7 +758,11 @@
    //! <b>Note</b>: Invalidates the iterators (but not the references)
    //! to the erased elements. No destructors are called.
    template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp)
+ size_type erase(const KeyType& key, KeyValueCompare comp
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -698,7 +782,7 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    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());
       iterator ret(this->erase(i));
@@ -706,6 +790,12 @@
       return ret;
    }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -719,7 +809,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)
    { size_type n; return private_erase(b, e, n, disposer); }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -759,7 +849,11 @@
    //! <b>Note</b>: Invalidates the iterators
    //! to the erased elements.
    template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
+ size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
+ /// @endcond
+ )
    {
       std::pair<iterator,iterator> p = this->equal_range(key, comp);
       size_type n;
@@ -1293,18 +1387,18 @@
    /// @cond
    private:
    template<class Disposer>
- iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
    {
       for(n = 0; b != e; ++n)
         this->erase_and_dispose(b++, disposer);
- return b;
+ return b.unconst();
    }
 
- iterator private_erase(iterator b, iterator e, size_type &n)
+ iterator private_erase(const_iterator b, const_iterator e, size_type &n)
    {
       for(n = 0; b != e; ++n)
         this->erase(b++);
- return b;
+ return b.unconst();
    }
    /// @endcond
 
@@ -1529,14 +1623,14 @@
    BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
 
    splaytree( const value_compare &cmp = value_compare()
- , const value_traits &v_traits = value_traits())
+ , const value_traits &v_traits = value_traits())
       : Base(cmp, v_traits)
    {}
 
    template<class Iterator>
    splaytree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
- , const value_traits &v_traits = value_traits())
+ , const value_compare &cmp = value_compare()
+ , const value_traits &v_traits = value_traits())
       : Base(unique, b, e, cmp, v_traits)
    {}
 

Modified: branches/release/boost/intrusive/trivial_value_traits.hpp
==============================================================================
--- branches/release/boost/intrusive/trivial_value_traits.hpp (original)
+++ branches/release/boost/intrusive/trivial_value_traits.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at

Modified: branches/release/boost/intrusive/unordered_set.hpp
==============================================================================
--- branches/release/boost/intrusive/unordered_set.hpp (original)
+++ branches/release/boost/intrusive/unordered_set.hpp 2008-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at
@@ -235,7 +235,7 @@
    key_equal key_eq() const
    { return table_.key_eq(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
    //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
@@ -463,6 +463,12 @@
    iterator erase_and_dispose(const_iterator i, Disposer disposer)
    { return table_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.
@@ -1288,7 +1294,7 @@
    key_equal key_eq() const
    { return table_.key_eq(); }
 
- //! <b>Effects</b>: Returns true is the container is empty.
+ //! <b>Effects</b>: Returns true if the container is empty.
    //!
    //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
    //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
@@ -1453,6 +1459,12 @@
    void erase_and_dispose(const_iterator i, Disposer disposer)
    { table_.erase_and_dispose(i, disposer); }
 
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ template<class Disposer>
+ iterator erase_and_dispose(iterator i, Disposer disposer)
+ { return this->erase_and_dispose(const_iterator(i), disposer); }
+ #endif
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range pointed to by b end e.

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-12-20 14:50:13 EST (Sat, 20 Dec 2008)
@@ -1,7 +1,7 @@
 /////////////////////////////////////////////////////////////////////////////
 //
 // (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2007
+// (C) Copyright Ion Gaztanaga 2006-2008
 //
 // Distributed under the Boost Software License, Version 1.0.
 // (See accompanying file LICENSE_1_0.txt or copy at


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