$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r53095 - in branches/sredl_2009_05_proptree_update: boost/property_tree boost/property_tree/detail libs/property_tree
From: sebastian.redl_at_[hidden]
Date: 2009-05-18 14:29:01
Author: cornedbee
Date: 2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
New Revision: 53095
URL: http://svn.boost.org/trac/boost/changeset/53095
Log:
Start implementation using multiindex. Everything's totally broken right now.
Text files modified: 
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp |   689 ++++++++++-----------                   
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp                       |  1226 +++++++++------------------------------ 
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp                   |    86 +                                       
   branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt             |    28                                         
   4 files changed, 707 insertions(+), 1322 deletions(-)
Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp	(original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp	2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -1,8 +1,8 @@
 // ----------------------------------------------------------------------------
 // Copyright (C) 2002-2006 Marcin Kalicinski
 //
-// Distributed under the Boost Software License, Version 1.0. 
-// (See accompanying file LICENSE_1_0.txt or copy at 
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 // For more information, see www.boost.org
@@ -10,494 +10,459 @@
 #ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
 #define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
 
-//////////////////////////////////////////////////////////////////////////////
-// Debug macros
-
-#ifdef BOOST_PROPERTY_TREE_DEBUG
-
-    // Increment instances counter
-    #define BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT()       \
-        {                                                               \
-            typedef boost::detail::lightweight_mutex::scoped_lock lock; \
-            lock l(debug_mutex);                                        \
-            ++debug_instances_count;                                    \
-        }
-
-    // Decrement instances counter
-    #define BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT()       \
-        {                                                               \
-            typedef boost::detail::lightweight_mutex::scoped_lock lock; \
-            lock l(debug_mutex);                                        \
-            BOOST_ASSERT(debug_instances_count > 0);                    \
-            --debug_instances_count;                                    \
-        }
-
-#else // BOOST_PROPERTY_TREE_DEBUG
-
-    #define BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT() static_cast<void>(0)
-    #define BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT() static_cast<void>(0)
-
-#endif // BOOST_PROPERTY_TREE_DEBUG
-
 namespace boost { namespace property_tree
 {
 
-    ///////////////////////////////////////////////////////////////////////////
-    // Construction & destruction
+    // Big four
 
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X>::basic_ptree(allocator_type)
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A>::basic_ptree(allocator_type)
     {
         // FIXME: use allocator
-        BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X>::basic_ptree(const data_type &rhs,
-                                               allocator_type alloc)
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A>::basic_ptree(const data_type &data,
+                                         allocator_type)
         : m_data(rhs)
     {
         // FIXME: use allocator
-        BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X>::basic_ptree(const basic_ptree<D, K, C, A, P, X> &rhs)
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A>::basic_ptree(const basic_ptree<K, D, C, A> &rhs)
     {
         m_data = rhs.m_data;
         insert(end(), rhs.begin(), rhs.end());
-        BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X>::~basic_ptree()
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::operator =(const basic_ptree<K, D, C, A> &rhs)
     {
-        BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT();
+        if (&rhs != this)
+        {
+            clear();
+            data() = rhs.data();
+            insert(end(), rhs.begin(), rhs.end());
+        }
+        return *this;
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // Iterator access
+    template<class K, class D, class C, class A>
+    void basic_ptree<K, D, C, A>::swap(basic_ptree<K, D, C, A> &rhs)
+    {
+        m_data.swap(rhs.m_data);
+        m_children.swap(rhs.m_children);
+    }
+
+    // Container view
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator 
-        basic_ptree<D, K, C, A, P, X>::begin()
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::size_type
+        basic_ptree<K, D, C, A>::size() const
     {
-        return m_container.begin();
+        return m_children.size();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::const_iterator 
-        basic_ptree<D, K, C, A, P, X>::begin() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::size_type
+        basic_ptree<K, D, C, A>::max_size() const
     {
-        return m_container.begin();
+        return m_children.max_size();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator 
-        basic_ptree<D, K, C, A, P, X>::end()
+    template<class K, class D, class C, class A>
+    bool basic_ptree<K, D, C, A>::empty() const
     {
-        return m_container.end();
+        return m_children.empty();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::const_iterator 
-        basic_ptree<D, K, C, A, P, X>::end() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::begin()
     {
-        return m_container.end();
+        return m_children.begin();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::reverse_iterator 
-        basic_ptree<D, K, C, A, P, X>::rbegin()
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_iterator
+        basic_ptree<K, D, C, A>::begin() const
     {
-        return m_container.rbegin();
+        return m_children.begin();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::const_reverse_iterator 
-        basic_ptree<D, K, C, A, P, X>::rbegin() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::end()
     {
-        return m_container.rbegin();
+        return m_children.end();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::reverse_iterator 
-        basic_ptree<D, K, C, A, P, X>::rend()
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_iterator
+        basic_ptree<K, D, C, A>::end() const
     {
-        return m_container.rend();
+        return m_children.end();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::const_reverse_iterator 
-        basic_ptree<D, K, C, A, P, X>::rend() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::reverse_iterator
+        basic_ptree<K, D, C, A>::rbegin()
     {
-        return m_container.rend();
+        return m_children.rbegin();
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // Data access
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_reverse_iterator
+        basic_ptree<K, D, C, A>::rbegin() const
+    {
+        return m_children.rbegin();
+    }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::size_type 
-        basic_ptree<D, K, C, A, P, X>::size() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::reverse_iterator
+        basic_ptree<K, D, C, A>::rend()
     {
-        return m_container.size();
+        return m_children.rend();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::size_type 
-        basic_ptree<D, K, C, A, P, X>::max_size() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_reverse_iterator
+        basic_ptree<K, D, C, A>::rend() const
     {
-        return m_container.max_size();
+        return m_children.rend();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    bool basic_ptree<D, K, C, A, P, X>::empty() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::value_type &
+        basic_ptree<K, D, C, A>::front()
     {
-        return m_container.empty();
+        return m_children.front();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::data_type &
-        basic_ptree<D, K, C, A, P, X>::data()
+    template<class K, class D, class C, class A>
+    const typename basic_ptree<K, D, C, A>::value_type &
+        basic_ptree<K, D, C, A>::front() const
     {
-        return m_data;
+        return m_children.front();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    const typename basic_ptree<D, K, C, A, P, X>::data_type &
-        basic_ptree<D, K, C, A, P, X>::data() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::value_type &
+        basic_ptree<K, D, C, A>::back()
     {
-        return m_data;
+        return m_children.back();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::value_type &
-        basic_ptree<D, K, C, A, P, X>::front()
+    template<class K, class D, class C, class A>
+    const typename basic_ptree<K, D, C, A>::value_type &
+        basic_ptree<K, D, C, A>::back() const
     {
-        return m_container.front();
+        return m_children.back();
     }
-    
-    template<class D, class K, class C, class A, class P, class X>
-    const typename basic_ptree<D, K, C, A, P, X>::value_type &
-        basic_ptree<D, K, C, A, P, X>::front() const
+
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+    basic_ptree<K, D, C, A>::insert(iterator where, const value_type &value)
     {
-        return m_container.front();
+        return m_children.insert(where, value).first;
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::value_type &
-        basic_ptree<D, K, C, A, P, X>::back()
+    template<class K, class D, class C, class A>
+    template<class It>
+    void basic_ptree<K, D, C, A>::insert(iterator where, It first, It last)
     {
-        return m_container.back();
+        m_children.insert(where, first, last);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    const typename basic_ptree<D, K, C, A, P, X>::value_type &
-        basic_ptree<D, K, C, A, P, X>::back() const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::erase(iterator where)
     {
-        return m_container.back();
+        return m_children.erase(where);
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // Operators
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::erase(iterator first, iterator last)
+    {
+        return m_children.erase(first, last);
+    }
 
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::operator =(const basic_ptree<D, K, C, A, P, X> &rhs)
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::push_front(const value_type &value)
     {
-        if (&rhs != this)
-        {
-            clear();
-            data() = rhs.data();
-            insert(end(), rhs.begin(), rhs.end());
-        }
-        return *this;
+        return m_children.push_front(value).first;
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    bool basic_ptree<D, K, C, A, P, X>::operator ==(const basic_ptree<D, K, C, A, P, X> &rhs) const
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::push_back(const value_type &value)
     {
-        
-        // Data and sizes must be equal
-        if (size() != rhs.size() || data() != rhs.data())
-            return false;
-
-        // Keys and children must be equal
-        C comp;
-        const_iterator it = begin();
-        const_iterator it_rhs = rhs.begin();
-        const_iterator it_end = end();
-        for (; it != it_end; ++it, ++it_rhs)
-            if (comp(it->first, it_rhs->first)
-                || comp(it_rhs->first, it->first)
-                || it->second != it_rhs->second)
-            {
-                return false;
-            }
-
-        // Equal
-        return true;
+        return m_children.push_back(value).first;
+    }
 
+    template<class K, class D, class C, class A>
+    void basic_ptree<K, D, C, A>::pop_front()
+    {
+        m_children.pop_front();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    bool basic_ptree<D, K, C, A, P, X>::operator !=(const basic_ptree<D, K, C, A, P, X> &rhs) const
+    template<class K, class D, class C, class A>
+    void basic_ptree<K, D, C, A>::pop_back()
     {
-        return !operator ==(rhs);
+        m_children.pop_back();
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // Container operations
+    template<class K, class D, class C, class A>
+    void basic_ptree<K, D, C, A>::reverse()
+    {
+        m_children.reverse();
+    }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator 
-        basic_ptree<D, K, C, A, P, X>::find(const key_type &key)
+    template<class K, class D, class C, class A>
+    void basic_ptree<K, D, C, A>::sort()
     {
-        C comp;
-        for (iterator it = begin(); it != end(); ++it)
-            if (!comp(it->first, key) && !comp(key, it->first))
-                return it;
-        return end();
+        m_children.sort();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::const_iterator 
-        basic_ptree<D, K, C, A, P, X>::find(const key_type &key) const
+    template<class K, class D, class C, class A>
+    template<class Compare>
+    void basic_ptree<K, D, C, A>::sort(Compare comp)
     {
-        C comp;
-        for (const_iterator it = begin(); it != end(); ++it)
-            if (!comp(it->first, key) && !comp(key, it->first))
-                return it;
-        return end();
+        m_children.sort(comp);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::size_type 
-        basic_ptree<D, K, C, A, P, X>::count(const key_type &key) const
+    // Equality
+
+    template<class K, class D, class C, class A>
+    bool basic_ptree<K, D, C, A>::operator ==(
+                                  const basic_ptree<K, D, C, A> &rhs) const
     {
-        C comp;
-        size_type count = 0;
-        for (const_iterator it = begin(); it != end(); ++it)
-            if (!comp(it->first, key) && !comp(key, it->first))
-                ++count;
-        return count;
+        // The size test is cheap, so add it as an optimization
+        return size() == rhs.size() && data() == rhs.data() &&
+            m_children == rhs.m_children;
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    void basic_ptree<D, K, C, A, P, X>::clear()
+    template<class K, class D, class C, class A>
+    bool basic_ptree<K, D, C, A>::operator !=(
+                                  const basic_ptree<K, D, C, A> &rhs) const
     {
-        m_data = data_type();
-        m_container.clear();
+        return !(*this == rhs);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator 
-    basic_ptree<D, K, C, A, P, X>::insert(iterator where, 
-                                       const value_type &value)
+    // Associative view
+
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::assoc_iterator not_found()
     {
-        return m_container.insert(where, value);
+        return assoc().end();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    template<class It>
-    void basic_ptree<D, K, C, A, P, X>::insert(iterator where, It first, It last)
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_assoc_iterator not_found() const
     {
-        for (; first != last; ++first, ++where)
-            where = insert(where, value_type(first->first, first->second));
+        return assoc().end();
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator 
-        basic_ptree<D, K, C, A, P, X>::erase(iterator where)
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::assoc_iterator
+        basic_ptree<K, D, C, A>::find(const key_type &key)
     {
-        return m_container.erase(where);
+        return assoc().find(key);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::size_type 
-        basic_ptree<D, K, C, A, P, X>::erase(const key_type &key)
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_assoc_iterator
+        basic_ptree<K, D, C, A>::find(const key_type &key) const
     {
-        C comp;
-        size_type count = 0;
-        iterator it = m_container.begin();
-        while (it != m_container.end())
-        {
-            if (!comp(it->first, key) && !comp(key, it->first))
-            {
-                it = erase(it);
-                ++count;
-            }
-            else
-                ++it;
-        }
-        return count;
+        return assoc().find(key);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    template<class It> 
-    typename basic_ptree<D, K, C, A, P, X>::iterator 
-        basic_ptree<D, K, C, A, P, X>::erase(It first, It last)
+    template<class K, class D, class C, class A>
+    std::pair<
+        typename basic_ptree<K, D, C, A>::assoc_iterator,
+        typename basic_ptree<K, D, C, A>::assoc_iterator
+    > basic_ptree<K, D, C, A>::equal_range(const key_type &key)
     {
-        while (first != last)
-            first = erase(first);
-        return first;
+        return assoc().equal_range(key);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator
-        basic_ptree<D, K, C, A, P, X>::push_front(const value_type &value)
+    template<class K, class D, class C, class A>
+    std::pair<
+        typename basic_ptree<K, D, C, A>::const_assoc_iterator,
+        typename basic_ptree<K, D, C, A>::const_assoc_iterator
+    > basic_ptree<K, D, C, A>::equal_range(const key_type &key) const
     {
-        return insert(begin(), value);
+        return assoc().equal_range(key);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::iterator
-        basic_ptree<D, K, C, A, P, X>::push_back(const value_type &value)
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::size_type
+        basic_ptree<K, D, C, A>::count(const key_type &key) const
     {
-        return insert(end(), value);
+        return assoc().count(key);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    void basic_ptree<D, K, C, A, P, X>::pop_front()
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::size_type
+        basic_ptree<K, D, C, A>::erase(const key_type &key)
     {
-        erase(begin());
+        return assoc().erase(key);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    void basic_ptree<D, K, C, A, P, X>::pop_back()
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::iterator
+        basic_ptree<K, D, C, A>::to_iterator(assoc_iterator ai)
     {
-        iterator last = end();
-        --last;
-        erase(last);
+        return m_children.project<0>(ai);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    void basic_ptree<D, K, C, A, P, X>::swap(basic_ptree<D, K, C, A, P, X> &rhs)
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::const_iterator
+        basic_ptree<K, D, C, A>::to_iterator(const_assoc_iterator ai) const
     {
-        m_data.swap(rhs.m_data);
-        m_container.swap(rhs.m_container);
+        return m_children.project<0>(ai);
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    void basic_ptree<D, K, C, A, P, X>::reverse()
+        // Property tree view
+
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::data_type &
+        basic_ptree<K, D, C, A>::data()
     {
-        m_container.reverse();
+        return m_data;
     }
-    
-    template<class D, class K, class C, class A, class P, class X>
-    template<class SortTr> 
-    void basic_ptree<D, K, C, A, P, X>::sort(SortTr tr)
+
+    template<class K, class D, class C, class A>
+    const typename basic_ptree<K, D, C, A>::data_type &
+        basic_ptree<K, D, C, A>::data() const
     {
-        m_container.sort(tr);
+        return m_data;
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // ptree operations
+    template<class K, class D, class C, class A>
+    void basic_ptree<K, D, C, A>::clear()
+    {
+        m_data = data_type();
+        m_children.clear();
+    }
 
-    // Get child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path)
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::get_child(const path_type &path)
     {
-        self_type *child = path.get_child(*this);
-        if (child)
-            return *child;
-        else
-            BOOST_PROPERTY_TREE_THROW(ptree_bad_path("path does not exist", path));
+        path_type p(path);
+        self_type *n = walk_path(p);
+        if (!n) {
+            BOOST_PROPERTY_TREE_THROW(ptree_bad_path(path));
+        }
+        return *n;
     }
 
     // Get child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    const basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path) const
+    template<class K, class D, class C, class A>
+    const basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::get_child(const path_type &path) const
     {
-        self_type *nc_this = const_cast<self_type *>(this);
-        return nc_this->get_child(path);
+        return const_cast<self_type*>(this)->get_child(path);
     }
 
     // Get child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path, 
-                                              basic_ptree<D, K, C, A, P, X> &default_value)
-    {
-        self_type *child = path.get_child(*this);
-        if (child)
-            return *child;
-        else
-            return default_value;
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::get_child(const path_type &path,
+                                           self_type &default_value)
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        return n ? *n : default_value;
     }
 
     // Get child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    const basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path, 
-                                              const basic_ptree<D, K, C, A, P, X> &default_value) const
-    {
-        self_type *nc_this = const_cast<self_type *>(this);
-        self_type &nc_default_value = const_cast<self_type &>(default_value);
-        return nc_this->get_child(path, nc_default_value);
+    template<class K, class D, class C, class A>
+    const basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::get_child(const path_type &path,
+                                           const self_type &default_value) const
+    {
+        return const_cast<self_type*>(this)->get_child(path,
+            onst_cast<self_type&>(default_value));
     }
 
 
     // Get child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    optional<basic_ptree<D, K, C, A, P, X> &> 
-        basic_ptree<D, K, C, A, P, X>::get_child_optional(const path_type &path)
-    {
-        self_type *child = path.get_child(*this);
-        if (child)
-            return optional<self_type &>(*child);
-        else
-            return optional<self_type &>();
+    template<class K, class D, class C, class A>
+    optional<basic_ptree<K, D, C, A> &>
+        basic_ptree<K, D, C, A>::get_child_optional(const path_type &path)
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        if (!n) {
+            return optional<self_type&>();
+        }
+        return *n;
     }
 
     // Get child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    optional<const basic_ptree<D, K, C, A, P, X> &> 
-        basic_ptree<D, K, C, A, P, X>::get_child_optional(const path_type &path) const
-    {
-        self_type *nc_this = const_cast<self_type *>(this);
-        optional<self_type &> tmp = nc_this->get_child_optional(path);
-        if (tmp)
-            return optional<const self_type &>(tmp.get());
-        else
-            return optional<const self_type &>();
+    template<class K, class D, class C, class A>
+    optional<const basic_ptree<K, D, C, A> &>
+        basic_ptree<K, D, C, A>::get_child_optional(const path_type &path) const
+    {
+        path_type p(path);
+        self_type *n = walk_path(p);
+        if (!n) {
+            return optional<const self_type&>();
+        }
+        return *n;
     }
 
     // Put child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::put_child(const path_type &path, 
-                                              const basic_ptree<D, K, C, A, P, X> &value,
-                                              bool do_not_replace)
-    {
-        self_type *child = path.put_child(*this, value, do_not_replace);
-        if (child)
-            return *child;
-        else
-            BOOST_PROPERTY_TREE_THROW(ptree_bad_path("path does not exist", path));
+    template<class K, class D, class C, class A>
+    basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::put_child(const path_type &path,
+                                           const self_type &value)
+    {
+        path_type p(path);
+        self_type &parent = force_path(p);
+        // Got the parent. Now get the correct child.
+        std::pair<key_type, std::size_t> fragment = p.reduce();
+        std::pair<assoc_iterator, assoc_iterator> range =
+            parent.equal_range(fragment.first);
+        std::size_t n = fragment.second;
+        // If the path specifies an index, walk the range.
+        while(n > 0 && range.first != range.second) {
+            --n;
+            ++range.first;
+        }
+        // If there's still something of the index left, add default-constructed
+        // elements.
+        while(n > 0) {
+            parent->push_back(self_type());
+        }
+        // We've finally reached the position for the new child
+        parent->push_back(value);
     }
 
     // Get value from data of ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class Type>
-    Type basic_ptree<D, K, C, A, P, X>::get_value(const translator_type &x) const
+    Type basic_ptree<K, D, C, A>::get_value(const translator_type &x) const
     {
         BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false);   // Disallow pointer types, they are unsafe
         Type value;
         if (x.get_value(*this, value))
             return value;
         else
-            BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of data into type \"") + 
+            BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of data into type \"") +
                                            typeid(Type).name() + "\" failed", data()));
     }
 
     // Get value from data of ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class Type>
-    Type basic_ptree<D, K, C, A, P, X>::get_value(const Type &default_value, 
+    Type basic_ptree<K, D, C, A>::get_value(const Type &default_value,
                                                const translator_type &x) const
     {
         BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false);   // Disallow pointer types, they are unsafe
@@ -509,20 +474,20 @@
     }
 
     // Get value from data of ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class CharType>
-    std::basic_string<CharType> 
-        basic_ptree<D, K, C, A, P, X>::get_value(const CharType *default_value, 
+    std::basic_string<CharType>
+        basic_ptree<K, D, C, A>::get_value(const CharType *default_value,
                                               const translator_type &x) const
     {
         return get_value(std::basic_string<CharType>(default_value), x);
     }
 
     // Get value from data of ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class Type>
-    optional<Type> 
-        basic_ptree<D, K, C, A, P, X>::get_value_optional(const translator_type &x) const
+    optional<Type>
+        basic_ptree<K, D, C, A>::get_value_optional(const translator_type &x) const
     {
         BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false);   // Disallow pointer types, they are unsafe
         Type value;
@@ -533,19 +498,19 @@
     }
 
     // Get value from data of child ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class Type>
-    Type basic_ptree<D, K, C, A, P, X>::get(const path_type &path,
+    Type basic_ptree<K, D, C, A>::get(const path_type &path,
                                          const translator_type &x) const
     {
         return get_child(path).get_value<Type>(x);
     }
 
     // Get value from data of child ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class Type>
-    Type basic_ptree<D, K, C, A, P, X>::get(const path_type &path, 
-                                         const Type &default_value, 
+    Type basic_ptree<K, D, C, A>::get(const path_type &path,
+                                         const Type &default_value,
                                          const translator_type &x) const
     {
         if (optional<Type> result = get_optional<Type>(path, x))
@@ -555,10 +520,10 @@
     }
 
     // Get value from data of child ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class CharType>
-    std::basic_string<CharType> 
-        basic_ptree<D, K, C, A, P, X>::get(const path_type &path, 
+    std::basic_string<CharType>
+        basic_ptree<K, D, C, A>::get(const path_type &path,
                                         const CharType *default_value,
                                         const translator_type &x) const
     {
@@ -566,33 +531,33 @@
     }
 
     // Get value from data of child ptree
-    template<class D, class K, class C, class A, class P, class X>
+    template<class K, class D, class C, class A>
     template<class Type>
-    optional<Type> 
-        basic_ptree<D, K, C, A, P, X>::get_optional(const path_type &path, 
+    optional<Type>
+        basic_ptree<K, D, C, A>::get_optional(const path_type &path,
                                                  const translator_type &x) const
     {
-        if (optional<const basic_ptree<D, K, C, A, P, X> &> child = get_child_optional(path))
+        if (optional<const basic_ptree<K, D, C, A> &> child = get_child_optional(path))
             return child.get().get_value_optional<Type>(x);
         else
             return optional<Type>();
     }
 
     // Put value in data of ptree
-    template<class D, class K, class C, class A, class P, class X>
-    template<class Type> 
-    void basic_ptree<D, K, C, A, P, X>::put_value(const Type &value, const translator_type &x)
+    template<class K, class D, class C, class A>
+    template<class Type>
+    void basic_ptree<K, D, C, A>::put_value(const Type &value, const translator_type &x)
     {
         if (!x.put_value(*this, value))
-            BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of type \"") + typeid(Type).name() + 
+            BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of type \"") + typeid(Type).name() +
                                                        "\" into data failed", boost::any()));
     }
 
     // Put value in data of child ptree
-    template<class D, class K, class C, class A, class P, class X>
-    template<class Type> 
-    basic_ptree<D, K, C, A, P, X> &
-        basic_ptree<D, K, C, A, P, X>::put(const path_type &path, 
+    template<class K, class D, class C, class A>
+    template<class Type>
+    basic_ptree<K, D, C, A> &
+        basic_ptree<K, D, C, A>::put(const path_type &path,
                                         const Type &value,
                                         bool do_not_replace,
                                         const translator_type &x)
@@ -616,36 +581,36 @@
 
 #ifdef BOOST_PROPERTY_TREE_DEBUG
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::size_type 
-        basic_ptree<D, K, C, A, P, X>::debug_get_instances_count() 
-    { 
-        empty_ptree<basic_ptree<D, K, C, A, P, X> >();    // Make sure empty ptree exists
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::size_type
+        basic_ptree<K, D, C, A>::debug_get_instances_count()
+    {
+        empty_ptree<basic_ptree<K, D, C, A> >();    // Make sure empty ptree exists
         return debug_instances_count - 1;              // Do not count empty ptree
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    typename basic_ptree<D, K, C, A, P, X>::size_type 
-        basic_ptree<D, K, C, A, P, X>::debug_instances_count;
-
-    template<class D, class K, class C, class A, class P, class X>
-    boost::detail::lightweight_mutex 
-        basic_ptree<D, K, C, A, P, X>::debug_mutex;
+    template<class K, class D, class C, class A>
+    typename basic_ptree<K, D, C, A>::size_type
+        basic_ptree<K, D, C, A>::debug_instances_count;
+
+    template<class K, class D, class C, class A>
+    boost::detail::lightweight_mutex
+        basic_ptree<K, D, C, A>::debug_mutex;
 
 #endif
 
     ///////////////////////////////////////////////////////////////////////////
     // Free functions
 
-    template<class Ptree> 
+    template<class Ptree>
     inline const Ptree &empty_ptree()
     {
         static Ptree pt;
         return pt;
     }
 
-    template<class D, class K, class C, class A, class P, class X>
-    inline void swap(basic_ptree<D, K, C, A, P, X> &pt1, basic_ptree<D, K, C, A, P, X> &pt2)
+    template<class K, class D, class C, class A>
+    inline void swap(basic_ptree<K, D, C, A> &pt1, basic_ptree<K, D, C, A> &pt2)
     {
         pt1.swap(pt2);
     }
Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp	(original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp	2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -14,32 +14,17 @@
 #ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
 #define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
 
-// Must be the first include, because of config.hpp
 #include <boost/property_tree/ptree_fwd.hpp>
 #include <boost/property_tree/detail/ptree_utils.hpp>
-#include <boost/assert.hpp>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/member.hpp>
+
 #include <boost/optional.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/remove_pointer.hpp>
-#include <boost/any.hpp>
-#include <boost/throw_exception.hpp>
-
-#ifdef BOOST_PROPERTY_TREE_DEBUG
-// For syncing debug instances counter
-#   include <boost/detail/lightweight_mutex.hpp>
-#endif
 
-#include <functional>               // for std::less
-#include <limits>
-#include <list>
-#include <sstream>
-#include <stdexcept>
 #include <utility>                  // for std::pair
-#include <vector>
-#include <cstdlib>
 
 #if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
     // Throwing macro to avoid no return warnings portably
@@ -50,22 +35,21 @@
 {
 
     /**
-     * Class template implementing property tree.
+     * Property tree main structure. A property tree is a hierarchical data
+     * structure which has one element of type @p Data in each node, as well
+     * as an ordered sequence of sub-nodes, which are additionally identified
+     * by a non-unique key of type @p Key.
+     *
+     * Key equivalency is defined by @p KeyCompare, a predicate defining a
+     * strict weak ordering.
      *
-     * A property tree can have data associated with it along with a
-     * sequence of @c (key,basic_ptree) children.
-     * Iterators provide bidirectional iterative access into child sequence.
+     * All data structures are allocated with some version of @p Allocator.
      *
-     * @tparam Key Key type
-     * @tparam Data Data type
-     * @tparam KeyCompare Key comparison predicate
-     * @tparam Allocator Allocator used throughout the class. Should be an
-     *           allocator for Data; will be rebound anyway
-     * @tparam Path Path type
-     * @tparam Translate Utility that converts between key and std::string
+     * Property tree defines a Container-like interface to the (key-node) pairs
+     * of its direct sub-nodes. The iterators are bidirectional. The sequence
+     * of nodes is held in insertion order, not key order.
      */
-    template<class Key, class Data, class KeyCompare, class Allocator,
-             class Path, class Translate>
+    template<class Key, class Data, class KeyCompare, class Allocator>
     class basic_ptree
     {
 #if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
@@ -73,997 +57,379 @@
 #endif
         // Internal types
         /**
-         * Simpler way to refer to this basic_ptree<C,K,P,D,X> type.
+         * Simpler way to refer to this basic_ptree\<C,K,P,A\> type.
          * Note that this is private, and made public only for doxygen.
          */
-        typedef basic_ptree<Key, Data, KeyCompare, Allocator, Path, Translate>
-            self_type; 
+        typedef basic_ptree<Key, Data, KeyCompare, Allocator> self_type;
 
     public:
         // Basic types
-        typedef Key key_type;
-        typedef Data data_type;
-        typedef KeyCompare key_compare;
-        typedef Allocator allocator_type;
-        typedef Path path_type;
-        typedef Translate translator_type;
-
-        /**
-         * Property tree stores a sequence of values of this type.
-         *
-         * The first element is the key and the second is the child property
-         * tree stored at this key.
-         */
-        typedef std::pair<key_type, self_type> value_type;
-
-        typedef typename allocator_type::template rebind<value_type>::other
-            value_allocator_type;
+        typedef Key                                  key_type;
+        typedef Data                                 data_type;
+        typedef KeyCompare                           key_compare;
+        typedef Allocator                            allocator_type;
+
+        // Container view types
+        typedef std::pair<Key, self_type>            value_type;
+        typedef typename Allocator::size_type        size_type;
 
     private:
-        // Internal types
-        typedef std::list<value_type, value_allocator_type> container_type;
+        struct by_name {};
+        // The actual child container.
+        typedef multi_index_container<value_type,
+            indexed_by<
+                multi_index::sequenced<>,
+                multi_index::ordered_non_unique<multi_index::tag<by_name>,
+                    multi_index::member<value_type, key_type,
+                                        &value_type::first>,
+                    key_compare
+                >
+            >
+        > base_container;
+        // The by-name lookup index.
+        typedef typename base_container::template index<by_name>::type
+            by_name_index;
+
+    public:
+        // More container view types
+        typedef typename base_container::iterator         iterator;
+        typedef typename base_container::const_iterator   const_iterator;
+        typedef typename base_container::reverse_iterator reverse_iterator;
+        typedef typename base_container::const_reverse_iterator
+                                                        const_reverse_iterator;
+
+        // Associative view types
+        typedef typename by_name_index::iterator          assoc_iterator;
+        typedef typename by_name_index::const_iterator    const_assoc_iterator;
 
-    public:
-        // Container-related types
-        typedef typename container_type::size_type size_type;
-        typedef typename container_type::iterator iterator;
-        typedef typename container_type::const_iterator const_iterator;
-        typedef typename container_type::reverse_iterator reverse_iterator;
-        typedef typename container_type::const_reverse_iterator
-            const_reverse_iterator;
+        // Property tree view types
+        typedef typename path_of<Key>::type          path_type;
 
-    public:
-        ///////////////////////////////////////////////////////////////////////
-        // Construction & destruction
 
-        /** Creates an empty property tree. */
-        explicit basic_ptree(allocator_type alloc = allocator_type());
+        // The big four
 
-        /**
-         * Creates a property_tree with the given data.
-         * @param data Data to be assigned to the tree's data field.
-         */
+        /** Creates a node with no children and default-constructed data. */
+        explicit basic_ptree(allocator_type alloc = allocator_type());
+        /** Creates a node with no children and a copy of the given data. */
         explicit basic_ptree(const data_type &data,
                              allocator_type alloc = allocator_type());
-
-        /**
-         * Copy constructor from another property_tree.
-         * @param rhs The property tree to be copied.
-         */
         basic_ptree(const self_type &rhs);
+        /** Basic guarantee only. */
+        self_type &operator =(const self_type &rhs);
 
-        /** Destroy the property tree, including all children.
+        /** Swap with other tree. Only constant-time and nothrow if the
+         * data type's swap is.
          */
-        ~basic_ptree();
+        void swap(self_type &rhs);
 
-        ///////////////////////////////////////////////////////////////////////
-        // Iterator access
+        // Container view functions
 
-        /**
-         * Access to the start of the direct children sequence.
-         * @return iterator pointing to the first element of the direct
-         *         children sequence.
-         */
-        iterator begin();
+        /** The number of direct children of this node. */
+        size_type size() const;
+        size_type max_size() const;
+        /** Whether there are any direct children. */
+        bool empty() const;
 
-        /**
-         * Const access to the start of the direct children sequence.
-         * @return const_iterator pointing to the first element of the direct
-         *         children sequence.
-         */
+        iterator begin();
         const_iterator begin() const;
-
-        /**
-         * Access to the end of the direct children sequence.
-         * @return iterator pointing just past the end of the direct
-         *         children sequence.
-         */
         iterator end();
-
-        /**
-         * Const access to the end of the direct children sequence.
-         * @return const_iterator pointing just past the end of the direct
-         *         children sequence.
-         */
         const_iterator end() const;
-
-        /**
-         * Access to the start of the reversed direct children sequence.
-         * @return reverse_iterator pointing to first element of the reversed
-         *         direct children sequence.
-         */
         reverse_iterator rbegin();
-
-        /**
-         * Const access to the start of the reversed direct children sequence.
-         * @return const_reverse_iterator pointing to first element of the
-         *         reversed direct children sequence.
-         */
         const_reverse_iterator rbegin() const;
-
-        /**
-         * Access to the end of the reverse direct children sequence.
-         * @return reverse_iterator pointing just past the end of the reversed
-         *         direct children sequence.
-         */
         reverse_iterator rend();
-
-        /**
-         * Const access to the end of the reverse direct children sequence.
-         * @return const_reverse_iterator pointing just past the end of the
-         *         reversed direct children sequence.
-         */
         const_reverse_iterator rend() const;
 
-        ///////////////////////////////////////////////////////////////////////////
-        // Data access
-
-        /**
-         * The size of the direct children sequnce.
-         * @return Number of direct children of the property tree.
-         */
-        size_type size() const;
-
-        size_type max_size() const;
-
-        /**
-         * Determine whether the children sequence is empty.
-         * @note empty() should be prefered over <tt>size() == 0</tt>
-         * @retval true There are no direct children.
-         * @retval false There is at least one direct child.
-         */
-        bool empty() const;
-
-        /**
-         * Returns a reference to the data of a property tree.
-         * @return Reference to the stored data which can be used to
-         *   modify the data.
-         */
-        data_type &data();
-
-        /**
-         * Returns a const reference to the data of a property tree.
-         * @return Const reference to the stored data.
-         */
-        const data_type &data() const;
-
-        /**
-         * Returns a reference to the first element in the direct
-         * children sequence.
-         * @pre !(this->empty())
-         * @return Reference to the first element in the direct
-         *   children sequence.
-         */
         value_type &front();
-
-        /**
-         * Returns a const reference to the first element in the direct
-         * children sequence.
-         * @pre !(this->empty())
-         * @return Const reference to the first element in the direct
-         *   children sequence.
-         */
         const value_type &front() const;
-
-        /**
-         * Returns a reference to the last element in the direct
-         * children sequence.
-         * @pre !(this->empty())
-         * @return Reference to the last element in the direct
-         *   children sequence.
-         */
         value_type &back();
-
-        /**
-         * Returns a const reference to the last element in the direct
-         * children sequence.
-         * @pre !(this->empty())
-         * @return Const reference to the last element in the direct
-         *   children sequence.
-         */
         const value_type &back() const;
 
-        ///////////////////////////////////////////////////////////////////////////
-        // Operators
-
-        /**
-         * Replaces current contents of this property tree with another's
-         * contents.
-         * @param rhs The property tree to assign to this property tree.
-         */
-        self_type &operator =(const self_type &rhs);
-
-        /**
-         * Check for equality of property trees.
-         * @retval true If both property trees contain the same data values
-         *   and equivalent children sequences, recursively.
-         * @retval false Otherwise.
-         */
-        bool operator ==(const self_type &rhs) const;
-
-        /**
-         * Check for inequality of property trees.
-         * @return !(*this == rhs)
-         */
-        bool operator !=(const self_type &rhs) const;
-
-        ///////////////////////////////////////////////////////////////////////
-        // Container operations
-
-        /**
-         * Finds direct child stored at specified key.
-         *
-         * If there is more than one child with the same key, the first one is
-         * returned. Time complexity is <tt>O(log n)</tt>. Keys equivalence is
-         * tested with a predicate supplied as basic_ptree template parameter.
-         * If childe is not found, returns end(). Both const and non-const 
-         * versions are provided. To find non-direct children use get_child 
-         * function.
-         *
-         * @param key The key to search in the direct children sequence.
-         * @return iterator pointing to the found sequence element, or end()
-         *         if no such element exists.
-         */
-        iterator find(const key_type &key);
-
-        /**
-         * Finds direct child stored at specified key.
-         *
-         * If there is more than one child with the same key, the first one is
-         * returned. Time complexity is <tt>O(log n)</tt>. Keys equivalence is
-         * tested with a predicate supplied as basic_ptree template parameter.
-         * If child is not found, returns end(). Both const and non-const 
-         * versions are provided. To find non-direct children use get_child 
-         * function.
-         *
-         * @param key The key to search in the direct children sequence.
-         * @return const_iterator pointing to the found sequence element,
-         *         or end() if no such element exists.
-         */
-        const_iterator find(const key_type &key) const;
-
-        /**
-         * Count the number of direct children with the given key.
-         *
-         * Keys equivalence is tested with a predicate supplied as basic_ptree 
-         * template parameter.
-         * @param key Key to count.
-         * @return Number of direct children with given key. 
-         */
-        size_type count(const key_type &key) const;
-
-        /**
-         * Recursively deletes all children of the property tree and clears the
-         * data from the property tree.
-         */
-        void clear();
-
-        /**
-         * Inserts a new direct child into the property tree.
-         *
-         * @param where Iterator pointing at the position where new element will
-         *              be inserted. Passing begin() will insert at the front of
-         *              the list. Passing end() will insert at the back. Any
-         *              other valid iterator will insert in the appropriate
-         *              place in the middle.
-         * @param value value to be inserted.
-         * @return iterator pointing to newly inserted element of the sequence.
+        /** Insert a copy of the given tree with its key just before the given
+         * position in this node. This operation invalidates no iterators.
+         * @return An iterator to the newly created child.
          */
         iterator insert(iterator where, const value_type &value);
 
-        /**
-         * Inserts a range of direct children into the property tree.
-         *
-         * Time complexity is <tt>O(m log n)</tt>, where @c m is number of
-         * inserted children, @c n is number of existing children.
-         *
-         * @param where Iterator pointing at the position where new elements
-         *              will be inserted. Passing begin() will insert at the
-         *              front of the list. Passing end() will insert at the
-         *              back. Any other valid iterator will insert in the
-         *              appropriate place in the middle.
-         * @param first Iterator designating the first element of range to be
-         *              inserted.
-         * @param last Iterator referring to just past the end of the range to
-         *             be inserted.
+        /** Range insert. Equivalent to:
+         * @code
+         * for(; first != last; ++first) insert(where, *first);
+         * @endcode
          */
         template<class It> void insert(iterator where, It first, It last);
 
-        /**
-         * Erases a direct child from the property tree.
-         *
-         * @param where Iterator pointing at the child to be erased from the
-         *              property tree.
-         * @return Iterator pointing to the element after the erased element of
-         *         the sequence, or end() if the element erased was the last in
-         *         the sequence.
+        /** Erase the child pointed at by the iterator. This operation
+         * invalidates the given iterator, as well as its equivalent
+         * assoc_iterator.
+         * @return A valid iterator pointing to the element after the erased.
          */
         iterator erase(iterator where);
 
-        /**
-         * Erases direct children from the property tree matching the given key.
-         *
-         * @param key Key designating child or children to erase.
-         * @return Number of children that were erased.
+        /** Range erase. Equivalent to:
+         * @code
+         * while(first != last;) first = erase(first);
+         * @endcode
          */
-        size_type erase(const key_type &key);
+        iterator erase(iterator first, iterator last);
 
-        /**
-         * Erases a range of direct children from the property tree.
-         *
-         * @param first Iterator designating the first element of range to be
-         *              erased.
-         * @param last Iterator referring to just past the end of the range to
-         *             be erased.
-         */
-        template<class It> iterator erase(It first, It last);
-
-        /**
-         * Inserts a new direct child at the front of the sequence.
-         *
-         * Equivalent to insert(begin(), value).
-         * @param value Value to be inserted.
-         * @return Iterator pointing to newly inserted element of the sequence.
-         */
+        /** Equivalent to insert(begin(), value). */
         iterator push_front(const value_type &value);
 
-        /**
-         * Inserts a new direct child at the back of the sequence.
-         *
-         * Equivalent to insert(end(), value)
-         * @param value Value to be inserted.
-         * @return Iterator pointing to newly inserted element of the sequence.
-         */
+        /** Equivalent to insert(end(), value). */
         iterator push_back(const value_type &value);
 
-        /**
-         * Erases the first direct child in the sequence.
-         *
-         * Equivalent to erase(begin()).
-         * @pre !(this->empty())
-         */
+        /** Equivalent to erase(begin()). */
         void pop_front();
 
-        /**
-         * Erases the last direct child in the sequence.
-         *
-         * Equivalent to erase(boost::prior(end())).
-         * @pre !(this->empty())
-         */
+        /** Equivalent to erase(boost::prior(end())). */
         void pop_back();
 
-        /**
-         * Swaps contents of this property tree with the contents of another.
-         *
-         * Time complexity is <tt>O(1)</tt>.
-         * @param rhs Property tree with which to swap.
-         */
-        void swap(self_type &rhs);
-
         /** Reverses the order of direct children in the property tree. */
         void reverse();
 
-        /**
-         * Sorts direct children of the property tree in ascending order.
-         * @param tr The binary predicate used to sort child values of type
-         *           @c #value_type.
-         * @post For each adjacent child of the sequence, @c v1 followed by
-         *       @c v2, @c tr(v1,v2) evaluates to true.
-         */
-        template<class SortTr> void sort(SortTr tr);
-
-        ///////////////////////////////////////////////////////////////////////
-        // ptree operations
-
-        /**
-         * Get a reference to the child property tree at the given path.
-         *
-         * Traverses the tree using the given path and retrieves a child
-         * property tree stored there.  This function will retrieve indirect
-         * children if the path contains at least one separator.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @throw ptree_bad_path if child property tree cannot be located.
-         * @return A reference to the child property tree at the given path
-         *         relative to this property tree.
-         */
-        self_type &get_child(const path_type &path);
-
-        /**
-         * Get a const reference to the child property tree at the given path.
-         *
-         * Traverses the tree using the given path and retrieves a child
-         * property tree stored there.  This function will retrieve indirect
-         * children if the path contains at least one separator.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @throw ptree_bad_path if child property tree cannot be located.
-         * @return A const reference to the child property tree at the given
-         *         path relative to this property tree.
+        /** Sorts the direct children of this node according to the predicate.
+         * The predicate is passed the whole pair of key and child.
          */
-        const self_type &get_child(const path_type &path) const;
+        template<class Compare> void sort(Compare comp);
 
-        /**
-         * Get a reference to the child property tree at the given path or a
-         * default if none found.
-         *
-         * Traverses the tree using the given path and retrieves a child
-         * property tree stored there.  This function will retrieve indirect
-         * children if the path contains at least one separator.  If child isn't
-         * found then the @p default_value will be returned.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @param default_value The value to be returned if no child is found
-         *                      at @c path.
-         * @return A reference to the child property tree at the given path
-         *         relative to this property tree or the @c default_value if
-         *         that child isn't found
-         */
-        self_type &get_child(const path_type &path, self_type &default_value);
+        /** Sorts the direct children of this node according to key order. */
+        void sort();
 
-        /**
-         * Get a const reference to the child property tree at the given path
-         * or a default if none found.
-         *
-         * Traverses the tree using the given path and retrieves a child
-         * property tree stored there.  This function will retrieve indirect
-         * children if the path contains at least one separator.  If child isn't
-         * found then the @c default_value will be returned.
-         * @note One use of default value is to return a reference to empty
-         *       property tree if the required one is not found. In many cases,
-         *       the subsequent code using the return value can be then made
-         *       simpler. @see boost::property_tree::empty_ptree.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @param default_value The value to be returned if no child is found
-         *                      at @c path.
-         * @return A const reference to the child property tree at the given
-         *         path relative to this property tree or the @c default_value
-         *         if that child isn't found.
-         */
-        const self_type &get_child(const path_type &path,
-                                   const self_type &default_value) const;
-
-        /**
-         * Get a reference to the child property tree at the given path if
-         * it exists.
-         *
-         * Traverses the tree using the given path and retrieves a child
-         * property tree stored there.  This function will retrieve indirect
-         * children if the path contains  at least one separator.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @return If the child is found, the function returns a boost::optional
-         *         initialized with a reference to it. Otherwise it returns
-         *         a null boost::optional.
-         */
-        optional<self_type &> get_child_optional(const path_type &path);
-
-        /**
-         * Get a const reference to the child property tree at the given path
-         * if it exists.
-         *
-         * Traverses the tree using the given path and retrieves a child
-         * property tree stored there.  This function will retrieve indirect
-         * children if the path contains at least one separator.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @return If the child is found, the function returns a boost::optional
-         *         initialized with a reference to it. Otherwise it returns
-         *         a null boost::optional.
-         */
-        optional<const self_type &>
-          get_child_optional(const path_type &path) const;
-
-        /**
-         * Traverses the tree using given path, and inserts a new property tree
-         * or replaces existing one.  If any of the intermediate keys specified
-         * by path does not exist, it is inserted, with empty data and no
-         * children, at the back of existing sequence.
-         *
-         * For example, if @c path is "key1.key2.key3", the function will find
-         * a child designated by "key1.key2" path. This child will be checked
-         * for presence of "key3" subkey. If it exists, it will be replaced with
-         * the one specified by value parameter. If it does not exist, "key3"
-         * will be added at the back of existing sequence (if any). If either
-         * "key1" or "key1.key2" do not exist, the function will insert them as
-         * well.
-         *
-         * This function is a complement to @c #get_child.
-         * If @c put_child(path,value) was called, @c get_child(path) will
-         * return a reference to element inserted/replaced by put_child.
-         *
-         * @param path Location to place value.  A sequence of keys with zero
-         *             or more separator characters.
-         * @param value Property tree to be inserted as a child of this
-         *              property tree.
-         * @param do_not_replace If set to true, causes function to always
-         *                       insert a new key, even if there already exists
-         *                       key with the same name.
-         * @return Reference to the inserted property tree.
-         */
-        self_type &put_child(const path_type &path, const self_type &value,
-                             bool do_not_replace = false);
-
-        /**
-         * Extracts value stored in property tree data and translates it to
-         * Type using the given translator.
-         * @throw ptree_bad_data If data cannot be translated to an instance of
-         *                       @c Type using the given translator_type.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c Type using
-         *   <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
-         * @return The extracted value as an instance of @c Type.
-         */
-        template<class Type> Type get_value(
-                            const translator_type &x = translator_type()) const;
+        // Equality
 
-        /**
-         * Extracts value stored in property tree data and translates it to
-         * Type using the given translator. If extraction does not succeed
-         * then return the given default value.
-         * @param default_value The value to be returned if the the given
-         *                      translator cannot extract the data as an
-         *                      instance of @c Type.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c Type using
-         *   <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
-         * @return The extracted value as an instance of @c Type if extraction
-         *         succeeds. Otherwise it returns the @c default_value.
+        /** Two property trees are the same if they have the same data, the keys
+         * and order of their children are the same, and the children compare
+         * equal, recursively.
          */
-        template<class Type> Type get_value(const Type &default_value,
-                            const translator_type &x = translator_type()) const;
-
-        /**
-         * Extracts value stored in property tree data and translates it to
-         * @c std::basic_string<CharType>  using the given translator. If
-         * extraction does not succeed then return the given default string.
-         * @param default_value The string to be returned if the the given
-         *                      translator cannot extract the data as an
-         *                      instance of @c Type.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c std::basic_string<CharType> using
-         *  <tt>bool translator_type::get_value(self_type const&,
-         *                                  std::basic_string<CharType>&)</tt>.
-         * @return The extracted value as an instance of
-         *         @c std::basic_string<CharType> if extraction succeeds.
-         *         Otherwise it returns the @c default_value.
-         */
-        template<class CharType> std::basic_string<CharType> get_value(
-                          const CharType *default_value,
-                          const translator_type &x = translator_type()) const;
+        bool operator ==(const self_type &rhs) const;
+        bool operator !=(const self_type &rhs) const;
 
-        /**
-         * Extracts value stored in property tree data and translates it to
-         * Type using the given translator.
-         * @param default_value The value to be returned if the the given
-         *                      translator cannot extract the data as an
-         *                      instance of @c Type.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c Type using
-         *   <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
-         * @return The extracted value as an instance of @c Type if extraction
-         *         succeeds. Otherwise it returns an empty
-         *         @c boost::optional\<Type\>.
-         */
-        template<class Type> optional<Type> get_value_optional(
-                          const translator_type &x = translator_type()) const;
+        // Associative view
 
-        /**
-         * Get the property tree value at the given path.
-         *
-         * Traverses the tree using the given path and retrieves the value
-         * stored there. This function will retrieve values of indirect children
-         * if the path contains at least one separator. The value will be
-         * converted to an instance of @c Type using the given translator.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c Type using
-         *   <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
-         * @throw ptree_bad_path if child property tree cannot be located using
-         *                       the given path.
-         * @return The child property tree's value at the given path relative
-         *         to this property tree.
+        /** Returns the not-found iterator. Equivalent to end() in a real
+         * associative container.
          */
-        template<class Type> Type get(const path_type &path,
-                            const translator_type &x = translator_type()) const;
-
-        /**
-         * Get the property tree value at the given path or a default if none
-         * found.
-         *
-         * Traverses the tree using the given path and retrieves the value
-         * stored there This function will retrieve values of indirect children
-         * if the path contains at least one separator. The value will be
-         * converted to an instance of @c Type using the given translator. If
-         * child isn't found then the @c default_value will be returned.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @param default_value The value to be returned if no child is found
-         *                      at @c path or translation fails.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c Type using
-         *   <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
-         * @return The child property tree's value at the given path relative to
-         *         this property tree or the @c default_value if that child is
-         *         not found.
-         */
-        template<class Type> Type get(const path_type &path,
-                                      const Type &default_value,
-                                      const translator_type &x =
-                                                    translator_type()) const;
-
-        /**
-         * Get the property tree value as @c std::basic_string<CharType> at the
-         * given path or a default if none found.
-         *
-         * Traverses the tree using the given path and retrieves the value
-         * stored there This function will retrieve values of indirect children
-         * if the path contains at least one separator. The value will be
-         * converted to an instance of @c std::basic_string<CharType> using the
-         * given translator. If child isn't found then the @c default_value
-         * will be returned.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @param default_value The string to be returned if no child is found
-         *                      at @c path or translation fails.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c std::basic_string<CharType> using
-         * <tt>bool translator_type::get_value(self_type const&,
-         *                                 std::basic_string<CharType>&)</tt>.
-         * @return The child property tree's value as
-         *         @c std::basic_string<CharType> at the given path relative to
-         *         this property tree or the @c default_value if that child is
-         *         not found or translation fails.
-         */
-        template<class CharType> std::basic_string<CharType> get(
-                          const path_type &path,
-                          const CharType *default_value,
-                          const translator_type &x = translator_type()) const;
-
-        /**
-         * Get the property tree value at the given path or an uninitialized
-         * @c boost::optional<Type> if none found.
-         *
-         * Traverses the tree using the given path and retrieves the value
-         * stored there. This function will retrieve values of indirect children
-         * if the path contains at least one separator.  The value will be
-         * converted to an instance of @c Type using the given translator.  If
-         * child isn't found then an unitialized @c boost::optional<Type>
-         * will be returned.
-         * @param path A sequence of keys with zero or more separator
-         *             characters. Can indicate indirect children if path
-         *             contains at least one separator character.
-         * @param x Translator to use to extract and convert the contained
-         *          #data_type to @c Type using
-         *   <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
-         * @return The child property tree's value at the given path relative to
-         *         this property tree or an unitialized @c boost::optional<Type>
-         *         if that child is not found or translation fails.
+        assoc_iterator not_found();
+        /** Returns the not-found iterator. Equivalent to end() in a real
+         * associative container.
          */
-        template<class Type> optional<Type> get_optional(const path_type &path,
-                          const translator_type &x = translator_type()) const;
+        const_assoc_iterator not_found() const;
 
-        /**
-         * Store the given value as the data of this property tree.
-         *
-         * Translates @c value from @c Type to @c #data_type using the given
-         * translator, and stores the result as the data value of this property
-         * tree.
-         * @throw ptree_bad_data If the given value cannot be translated to
-         *                       @c #data_type.
-         * @param value The parameter to store as the data of this property
-         *              tree.
-         * @param x Translator to use to convert @c value to an instance of
-         *          @c #data_type using
-         *   <tt>bool translator_type::put_value(self_type&, Type const&)</tt>.
+        /** Find a child with the given key, or not_found() if there is none.
+         * There is no guarantee about which child is returned if multiple have
+         * the same key.
          */
-        template<class Type> void put_value(const Type &value,
-                                const translator_type &x = translator_type());
+        assoc_iterator find(const key_type &key);
 
-        /**
-         * Traverses the tree using given path, and inserts a new value or
-         * replaces existing one. If any of the intermediate keys specified by
-         * path does not exist, it is inserted, with empty data and no children,
-         * at the back of existing sequence.
-         *
-         * For example, if @c path is "key1.key2.key3", the function will find
-         * a child designated by "key1.key2" path. This child will be checked
-         * for presence of "key3" subkey. If it exists, it will be replaced with
-         * the one specified by value parameter. If it does not exist, "key3"
-         * will be added at the back of existing sequence (if any). If either
-         * "key1" or "key1.key2" do not exist, the function will insert them as
-         * well.
-         *
-         * This function is a complement to @c #get. If @c put(path,value) was
-         * called, @c get(path) will return the value inserted by @c #put.
-         *
-         * @param path Location to place value.  A sequence of keys with zero
-         *             or more separator characters.
-         * @param value value to be inserted as the data of a child of this
-         *              property tree.
-         * @param do_not_replace If set to true, causes function to always
-         *                       insert a new key, even if there already exists
-         *                       key with the same name.
-         * @param x Translator to use to convert @c value to an instance of
-         *          @c #data_type using
-         *   <tt>bool translator_type::put_value(self_type&,Type const&)</tt>.
-         * @return Reference to the property tree where the value was inserted. 
-         *         It is either a newly inserted property tree or an existing
-         *         one if it was there prior to this call.
-         */
-        template<class Type> self_type &put(const path_type &path,
-                                            const Type &value,
-                                            bool do_not_replace = false,
-                                            const translator_type &x =
-                                                translator_type());
-
-    private:
-        data_type m_data;
-        container_type m_container;
-
-        ///////////////////////////////////////////////////////////////////////
-        // Debugging
-
-#ifdef BOOST_PROPERTY_TREE_DEBUG
-    private:
-        // Mutex for syncing instances counter
-        static boost::detail::lightweight_mutex debug_mutex;
-        // Total number of instances of this ptree class
-        static size_type debug_instances_count;
-    public:
-        static size_type debug_get_instances_count();
-#endif
-
-    };
-
-    ///////////////////////////////////////////////////////////////////////////
-    // basic_path class template
-
-    /** Class template used to represent a path containing a sequence of Key
-     * instances.
-     */
-    template<class Key>
-    class basic_path
-    {
-#if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
-    public:
-#endif
-        /**
-         * Simpler way to refer to the Key::value_type type.
-         * Do not use in client code; exposed only for documentation purposes.
+        /** Find a child with the given key, or not_found() if there is none.
+         * There is no guarantee about which child is returned if multiple have
+         * the same key.
          */
-        typedef typename Key::value_type char_type;
+        const_assoc_iterator find(const key_type &key) const;
 
-    public:
-
-        ///////////////////////////////////////////////////////////////////////
-        // Construction & destruction
+        /** Find the range of children that have the given key. */
+        std::pair<assoc_iterator, assoc_iterator>
+            equal_range(const key_type &key);
 
-        /** Constructs an empty basic_path<Key> instance */
-        basic_path();
-
-        /**
-         * Constructs an path using the given path using the given separator to
-         * split it.
-         * @param path The path to which to initialize the constructed instance.
-         * @param separator The separator to use to split the @c path parameter.
-         */
-        basic_path(const Key &path, char_type separator = char_type('.'));
+        /** Find the range of children that have the given key. */
+        std::pair<const_assoc_iterator, const_assoc_iterator>
+            equal_range(const key_type &key) const;
 
-        /**
-         * Constructs an path using the given path using the given separator to
-         * split it.
-         * @param path The path to which to initialize the constructed instance.
-         *             This path instance must be terminated with
-         *             char_type('\\0');
-         * @param separator The separator to use to split the @c path parameter.
-         */
-        basic_path(const char_type *path, char_type separator = char_type('.'));
+        /** Count the number of direct children with the given key. */
+        size_type count(const key_type &key) const;
 
-        ///////////////////////////////////////////////////////////////////////
-        // Path manipulation
+        /** Erase all direct children with the given key. */
+        void erase(const key_type &key);
 
-        /**
-         * Append the given path to this instance.
-         * @param rhs The path to append.
-         * @return A reference to this path instance after appending @c rhs.
+        /** Get the iterator that points to the same element as the argument.
+         * @note A valid assoc_iterator range (a, b) does not imply that
+         *       (to_iterator(a), to_iterator(b)) is a valid range.
          */
-        basic_path<Key> &operator /=(const basic_path<Key> &rhs);
+        iterator to_iterator(assoc_iterator it);
 
-        /**
-         * Convert this path instance to a @c std::string representation.
-         * @return A string representation of this path.
+        /** Get the iterator that points to the same element as the argument.
+         * @note A valid const_assoc_iterator range (a, b) does not imply that
+         *       (to_iterator(a), to_iterator(b)) is a valid range.
          */
-        std::string to_string() const;
+        const_iterator to_iterator(const_assoc_iterator it);
 
-        ///////////////////////////////////////////////////////////////////////
-        // Operations
-
-        /**
-         * Extract the child subtree of the given property tree at the location
-         * indicated by this path instance.
-         * @param root The property tree from which to extract the child
-         *             subtree.
-         * @return Pointer to the child subtree of the input property tree
-         *         indicated by the location given by this path instance. If no
-         *         child exists at the indicated location then NULL is returned.
-         */
-        template<class D, class C, class A, class X>
-        basic_ptree<Key, D, C, A, basic_path<Key>, X> *get_child(
-                    basic_ptree<Key, D, C, A, basic_path<Key>, X> &root) const;
+        // Property tree view
 
-        /**
-         * Extract the child subtree of the given property tree at the location
-         * indicated by this path instance.
-         * @param root The property tree from which to extract the child
-         *             subtree.
-         * @return Pointer to the constant child subtree of the input property
-         *         tree indicated by the location given by this path instance.
-         *         If no child exists at the indicated location then NULL is
-         *         returned.
-         */
-        template<class D, class C, class A, class X>
-        const basic_ptree<Key, D, C, A, basic_path<Key>, X> *get_child(
-              const basic_ptree<Key, D, C, A, basic_path<Key>, X> &root) const;
-
-        /**
-         * Insert or replace in the given property tree at the location
-         * indicated by this path instance the second given property tree as a
-         * child.
-         * @param root The property tree in which to insert or replace the
-         *             child.
-         * @param child The property tree to insert within the tree given by
-         *              that @c root parameter.
-         * @param do_not_replace If set to true, causes function to always
-         *                       insert a new key, even if there already exists
-         *                       key with the same name. Otherwise an existing
-         *                       key is replaced.
-         * @return Pointer to the child property tree inserted at the location
-         *         given by this path instance.  If this path is empty then
-         *         return NULL.
-         */
-        template<class D, class C, class A, class X>
-        basic_ptree<Key, D, C, A, basic_path<Key>, X> *put_child(
-                    basic_ptree<Key, D, C, A, basic_path<Key>, X> &root,
-                    const basic_ptree<Key, D, C, A, basic_path<Key>, X> &child,
-                    bool do_not_replace) const;
-
-    private:
-
-        std::vector<Key> m_path;
-
-        ///////////////////////////////////////////////////////////////////////
-        // Internal
-
-        template<class RanIt> void parse(RanIt begin, RanIt end,
-                                         char_type separator);
-
-    };
-
-    ///////////////////////////////////////////////////////////////////////////
-    // translator class
-
-    class translator
-    {
-    public:
-        /** Default construct a translator instance. */
-        translator();
+        /** Reference to the actual data in this node. */
+        data_type &data();
 
-        /**
-         * Construct a translator instance setting the internal locale state
-         * using the given input locale.
-         * @param loc The locale to use in this instance.
-         */
-        translator(const std::locale &loc);
+        /** Reference to the actual data in this node. */
+        const data_type &data() const;
 
-        /**
-         * Extract data value from the given property tree and convert it to an 
-         * instance of type @c T.
-         * @param pt Property tree from which to retrieve the data value.
-         * @param[out] value The variable in which to store the retrieved data
-         *                   value.
-         * @return @c true if the data value was sucessfully converted and
-         *         retrieved. Otherwise return @c false.
-         */
-        template<class Ptree, class T> bool get_value(const Ptree &pt, T &value)
-                                                const;
+        /** Clear this tree completely, of both data and children. */
+        void clear();
 
-        /**
-         * Insert the given value as the data member in the given property tree
-         * after converting it to instance of type @c Ptree::data_type.
-         * @param pt Property tree in which to insert the given value as data.
-         * @param value The value to store as data in the given property tree.
-         * @return @c true If the data value was sucessfully converted and
-         *         retrieved. Otherwise return @c false.
+        /** Get the child at the given path, or throw @c ptree_bad_path.
+         * @note Depending on the path, the result at each level may not be
+         *       completely determinate, i.e. if the same key appears multiple
+         *       times, which child is chosen is not specified. This can lead
+         *       to the path not being resolved even though there is a
+         *       descendant with this path. Example:
+         * @code
+         *   a -> b -> c
+         *     -> b
+         * @endcode
+         *       The path "a.b.c" will succeed if the resolution of "b" chooses
+         *       the first such node, but fail if it chooses the second.
          */
-        template<class Ptree, class T> bool put_value(Ptree &pt, const T &value)
-                                                const;
-
-    private:
+        self_type &get_child(const path_type &path);
 
-        std::locale m_locale;
+        /** Get the child at the given path, or throw @c ptree_bad_path. */
+        const self_type &get_child(const path_type &path) const;
 
-    };
+        /** Get the child at the given path, or return @p default_value. */
+        self_type &get_child(const path_type &path, self_type &default_value);
 
-    ///////////////////////////////////////////////////////////////////////////
-    // exceptions
+        /** Get the child at the given path, or return @p default_value. */
+        const self_type &get_child(const path_type &path,
+                                   const self_type &default_value) const;
 
-    /// Base class for all property tree errors. Derives from
-    /// @c std::runtime_error. Call member function @c what to get human
-    /// readable message associated with the error.
-    class ptree_error: public std::runtime_error
-    {
-    public:
-        /// Instantiate a ptree_error instance with the given message.
-        /// @param what The message to associate with this error.
-        ptree_error(const std::string &what);
+        /** Get the child at the given path, or return boost::null. */
+        optional<self_type &> get_child_optional(const path_type &path);
 
-        ~ptree_error() throw();
-    };
+        /** Get the child at the given path, or return boost::null. */
+        optional<const self_type &>
+          get_child_optional(const path_type &path) const;
 
+        /** Set the node at the given path to the given value. Create any
+         * missing parents. If the node at the path already exists, replace it.
+         * @return A reference to the inserted subtree.
+         * @note Because of the way paths work, it is not generally guaranteed
+         *       that a node newly created can be accessed using the same path.
+         * @note If the path could refer to multiple nodes, it is unspecified
+         *       which one gets replaced.
+         */
+        self_type &put_child(const path_type &path, const self_type &value);
+
+        /** Add the node at the given path. Create any missing parents. If there
+         * already is a node at the path, add another one with the same key.
+         * @return A reference to the inserted subtree.
+         * @note Because of the way paths work, it is not generally guaranteed
+         *       that a node newly created can be accessed using the same path.
+         */
+        self_type &add_child(const path_type &path, const self_type &value);
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the supplied translator.
+         * @throw ptree_bad_data if the conversion fails.
+         */
+        template<class Type, class Translator>
+        Type get_value(Translator tr =
+            typename translator_between<data_type, Type>::type()) const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the supplied translator. Return @p default_value
+         * if this fails.
+         */
+        template<class Type, class Translator>
+        Type get_value(const Type &default_value,
+                       Translator tr =
+            typename translator_between<data_type, Type>::type()) const;
+
+        /** Take the value of this node and attempt to translate it to a
+         * @c Type object using the supplied translator. Return boost::null if
+         * this fails.
+         */
+        template<class Type, class Translator>
+        optional<Type> get_value_optional(Translator tr =
+            typename translator_between<data_type, Type>::type()) const;
+
+        /** Replace the value at this node with the given value, translated
+         * to the tree's data type using the supplied translator.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type, class Translator>
+        void put_value(const Type &value,
+                       Translator tr =
+                       typename translator_between<data_type, Type>::type());
+
+        /** Shorthand for get_child(path).get_value(tr). */
+        template<class Type, class Translator>
+        Type get(const path_type &path,
+                 Translator tr =
+                     typename translator_between<data_type, Type>::type()
+                ) const;
+
+        /** Shorthand for get_child(path, empty_ptree())
+         *                    .get_value(default_value, tr).
+         * That is, return the translated value if possible, and the default
+         * value if the node doesn't exist or conversion fails.
+         */
+        template<class Type, class Translator>
+        Type get(const path_type &path,
+                 const Type &default_value,
+                 Translator tr =
+                     typename translator_between<data_type, Type>::type()
+                ) const;
+
+        /** Shorthand for:
+         * @code
+         * if(optional\<self_type&\> node = get_child_optional(path))
+         *   return node->get_value_optional(tr);
+         * return boost::null;
+         * @endcode
+        */
+        template<class Type, class Translator>
+        Type get_optional(const path_type &path,
+                          Translator tr =
+                            typename translator_between<data_type, Type>::type()
+                         ) const;
+
+        /** Set the value of the node at the given path to the supplied value,
+         * translated to the tree's data type. If the node doesn't exist, it is
+         * created, including all its missing parents.
+         * @return The node that had its value changed.
+         * @throw ptree_bad_data if the conversion fails.
+        */
+        template<class Type, class Translator>
+        self_type &put(const path_type &path,
+                       const Type &value,
+                       Translator tr =
+                           typename translator_between<data_type, Type>::type()
+                      );
+
+        /** If the node identified by the path does not exist, create it,
+         * including all its missing parents.
+         * If the node already exists, add a sibling with the same key.
+         * Set the newly created node's value to the given paremeter,
+         * translated with the supplied translator.
+        */
+        template<class Type, class Translator>
+        self_type &add(const path_type &path,
+                       const Type &value,
+                       Translator tr =
+                           typename translator_between<data_type, Type>::type()
+                      );
 
-    /// Error indicating that translation from given value to the property tree
-    /// data_type (or vice versa) failed. Derives from ptree_error.
-    class ptree_bad_data: public ptree_error
-    {
-    public:
-        /// Instantiate a ptree_bad_data instance with the given message and
-        /// data.
-        /// @param what The message to associate with this error.
-        /// @param data The value associated with this error that was the source
-        ///             of the translation failure.
-        template<class T> ptree_bad_data(const std::string &what,
-                                         const T &data);
-
-        ~ptree_bad_data() throw();
-
-        /// Retrieve the data associated with this error. This is the source
-        /// value that failed to be translated.
-        template<class T> T data();
     private:
-        boost::any m_data;
-    };
-
-
-    /// Error indicating that specified path does not exist. Derives from
-    /// ptree_error.
-    class ptree_bad_path: public ptree_error
-    {
-    public:
-        /// Instantiate a ptree_bad_path with the given message and path data.
-        /// @param what The message to associate with this error.
-        /// @param path The path that could not be found in the property_tree.
-        template<class T> ptree_bad_path(const std::string &what,
-                                         const T &path);
-
-        ~ptree_bad_path() throw();
+        // Hold the data of this node
+        data_type m_data;
+        // Hold the children
+        base_container m_children;
 
-        /// Retrieve the invalid path.
-        template<class T> T path();
-    private:
-        boost::any m_path;
+        // Convenience
+        by_name_index& assoc() { return m_children.get<by_name>(); }
+        const by_name_index& assoc() const {
+            return m_children.get<by_name>();
+        }
+
+        // Getter tree-walk. Not const-safe! Gets the node the path refers to,
+        // or null. Destroys p's value.
+        self_type* walk_path(path_type& p) const;
+
+        // Modifer tree-walk. Gets the parent of the node referred to by the
+        // path, creating nodes as necessary. p is the path to the remaining
+        // child.
+        self_type& force_path(path_type& p);
     };
 
 } }
 
 // Include implementations
 #include <boost/property_tree/detail/ptree_implementation.hpp>
-// FIXME: There's a very nasty order dependency between exceptions_impl and
-// the other two headers on compilers that do really compliant ADL, like
-// GCC 4.3.
-#include <boost/property_tree/detail/path_implementation.hpp>
-#include <boost/property_tree/detail/translator_implementation.hpp>
-#include <boost/property_tree/detail/exceptions_implementation.hpp>
 
 #endif
Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp	(original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp	2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -23,15 +23,49 @@
     ///////////////////////////////////////////////////////////////////////////
     // Classes
 
-    template<class Key> class basic_path;
-    class translator;
-    //template<class C, class K, class P, class D, class X> class basic_ptree;
     template <class Key, class Data,
               class KeyCompare = std::less<Key>,
-              class Allocator = std::allocator<Data>,
-              class Path = basic_path<Key>,
-              class Translate = translator>
-        class basic_ptree;
+              class Allocator = std::allocator<Data>>
+    class basic_ptree;
+
+    struct id_translator;
+
+    template <typename String, typename Translator>
+    class string_path;
+
+    // We'll want to do this with concepts in C++0x.
+#if 0
+    concept PropertyTreePath<Path> {
+      // The key type for which this path works.
+      typedef key_type;
+      // Return the key and index that the first segment of the path name.
+      // Split the head off the state.
+      std::pair<key_type, std::size_t> Path::reduce();
+
+      // Return true if the path is empty.
+      bool Path::empty();
+
+      // Return true if the path contains a single element.
+      bool Path::single();
+    }
+    concept PropertyTreeKey<Key> {
+        PropertyTreePath path;
+        requires SameType<Key, PropertyTreePath<path>::key_type>;
+    }
+#endif
+    /// If you want to use a custom key type, specialize this struct for it
+    /// and give it a 'type' typedef that specifies your path type. The path
+    /// type must conform to the Path concept described in the documentation.
+    /// This is already specialized for std::basic_string.
+    template <typename Key>
+    struct path_of;
+
+    /// Specialize this struct to specify a default translator between the data
+    /// in a tree whose data_type is TreeData, and the external data_type
+    /// specified in a get_value, get, put_value or put operation.
+    /// This is already specialized for TreeData being std::basic_string.
+    template <typename TreeData, typename External>
+    struct translator_between;
 
     class ptree_error;
     class ptree_bad_data;
@@ -41,20 +75,20 @@
     // Typedefs
 
     /** Implements a path using a std::string as the key. */
-    typedef basic_path<std::string> path;
+    typedef string_path<std::string, id_translator> path;
 
     /** Implements a path using a std::wstring as the key. */
-    typedef basic_path<std::wstring> wpath;
+    typedef string_path<std::wstring, id_translator> wpath;
 
     /**
-     * A property tree that uses a path type based upon std::string.
-     * Comparisons of keys are performed in a case-sensitive manner.
+     * A property tree with std::string for key and data, and default
+     * comparison.
      */
     typedef basic_ptree<std::string, std::string> ptree;
 
     /**
-     * A property tree that uses a path type based upon std::string.
-     * Comparisons of keys are performed in a case-insensitive manner.
+     * A property tree with std::string for key and data, and case-insensitive
+     * comparison.
      */
     typedef basic_ptree<std::string, std::string,
                         detail::less_nocase<std::string> >
@@ -62,15 +96,15 @@
 
 #ifndef BOOST_NO_CWCHAR
     /**
-     * A property tree that uses a wide-character path type based upon std::wstring.
-     * Comparisons of keys are performed in a case-sensitive manner.
+     * A property tree with std::wstring for key and data, and default
+     * comparison.
      * @note The type only exists if the platform supports @c wchar_t.
      */
     typedef basic_ptree<std::wstring, std::wstring> wptree;
 
     /**
-     * A property tree that uses a wide-character path type based upon std::wstring.
-     * Comparisons of keys are performed in a case-insensitive manner.
+     * A property tree with std::wstring for key and data, and case-insensitive
+     * comparison.
      * @note The type only exists if the platform supports @c wchar_t.
      */
     typedef basic_ptree<std::wstring, std::wstring,
@@ -83,12 +117,10 @@
 
     /**
      * Swap two property tree instances.
-     * @param pt1 Reference to first property tree involved in swap.
-     * @param pt2 Reference to second property tree involved in swap.
      */
-    template<class K, class D, class C, class A, class P, class X>
-    void swap(basic_ptree<K, D, C, A, P, X> &pt1,
-              basic_ptree<K, D, C, A, P, X> &pt2);
+    template<class K, class D, class C, class A>
+    void swap(basic_ptree<K, D, C, A> &pt1,
+              basic_ptree<K, D, C, A> &pt2);
 
     /**
      * Reference to empty property tree. Can be used as a default value of
@@ -96,11 +128,11 @@
      */
     template<class Ptree> const Ptree &empty_ptree();
 
-    /** Join two path objects. */
-    path operator /(const path &p1, const path &p2);
-
-    /** Join two wide-path objects. */
-    wpath operator /(const wpath &p1, const wpath &p2);
+    /** Join two string_path objects. */
+    template <typename String, typename Translator>
+    string_path<String, Translator> operator /(
+                                  const string_path<String, Translator> &p1,
+                                  const string_path<String, Translator> &p2);
 
 } }
 
Modified: branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt
==============================================================================
--- branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt	(original)
+++ branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt	2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -1,5 +1,27 @@
 List all breaking changes done to the interface during the update here.
 
-- Template parameters.
-Template parameters have been reordered, and an allocator parameter has been
-added.
+- Template parameters
+Template parameters have been thoroughly changed.
+Impact: If you were using a custom instantiation of basic_ptree, you have to
+  change your code.
+
+- put*
+The put and put_child functions of basic_ptree had add and add_child split from
+them, by splitting the functionality of the third parameter.
+Impact: If you were using the third parameter of these functions, you have to
+  change your code.
+
+- Custom paths
+Custom paths have been thoroughly changed.
+Impact: If you were using custom paths, you have to change your code. If you
+  referred to the basic_path template by name, you have to change your code.
+
+- Translators
+Translators have been thoroughly changed.
+Impact: If you were using translators at all, you probably have to change your
+  code.
+
+- find
+find() returns an assoc_iterator.
+Impact: If you use find, you may have to change your code.
+Rationale: equal_range() also returns assoc_iterators.