$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r53799 - in branches/sredl_2009_05_proptree_update/boost/property_tree: . detail
From: sebastian.redl_at_[hidden]
Date: 2009-06-11 18:20:07
Author: cornedbee
Date: 2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
New Revision: 53799
URL: http://svn.boost.org/trac/boost/changeset/53799
Log:
This is the fat rewrite. It compiles and the main test case passes. Peripherals (like parsers) not yet converted. This time in the correct directory.
Added:
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/exception_implementation.hpp   (contents, props changed)
   branches/sredl_2009_05_proptree_update/boost/property_tree/exceptions.hpp   (contents, props changed)
   branches/sredl_2009_05_proptree_update/boost/property_tree/id_translator.hpp   (contents, props changed)
   branches/sredl_2009_05_proptree_update/boost/property_tree/stream_translator.hpp   (contents, props changed)
   branches/sredl_2009_05_proptree_update/boost/property_tree/string_path.hpp   (contents, props changed)
Removed:
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/exceptions_implementation.hpp
Text files modified: 
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp |   791 +++++++++++++++++++++++---------------- 
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_utils.hpp          |    18                                         
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp                       |   148 ++++---                                 
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp                   |    70 +-                                      
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_serialization.hpp         |    25                                         
   5 files changed, 623 insertions(+), 429 deletions(-)
Added: branches/sredl_2009_05_proptree_update/boost/property_tree/detail/exception_implementation.hpp
==============================================================================
--- (empty file)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/detail/exception_implementation.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -0,0 +1,83 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// 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
+// ----------------------------------------------------------------------------
+#ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
+
+namespace boost { namespace property_tree
+{
+
+    namespace detail
+    {
+
+        // Helper for preparing what string in ptree_bad_path exception
+        template<class P> inline
+        std::string prepare_bad_path_what(const std::string &what,
+                                          const P &path)
+        {
+            return what + " (" + path.dump() + ")";
+        }
+
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ptree_error
+
+    inline ptree_error::ptree_error(const std::string &what): 
+        std::runtime_error(what) 
+    {
+    }
+
+    inline ptree_error::~ptree_error() throw()
+    {
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ptree_bad_data
+
+    template<class D> inline
+    ptree_bad_data::ptree_bad_data(const std::string &what, const D &data):
+        ptree_error(what), m_data(data)
+    {
+    }
+
+    inline ptree_bad_data::~ptree_bad_data() throw()
+    {
+    }
+
+    template<class D> inline
+    D ptree_bad_data::data()
+    {
+        return boost::any_cast<D>(m_data);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // ptree_bad_path
+
+    template<class P> inline
+    ptree_bad_path::ptree_bad_path(const std::string &what, const P &path):
+        ptree_error(detail::prepare_bad_path_what(what, path)), m_path(path)
+    {
+
+    }
+
+    inline ptree_bad_path::~ptree_bad_path() throw()
+    {
+    }
+
+    template<class P> inline
+    P ptree_bad_path::path()
+    {
+        return boost::any_cast<P>(m_path);
+    }
+
+}}
+
+#endif
Deleted: branches/sredl_2009_05_proptree_update/boost/property_tree/detail/exceptions_implementation.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/detail/exceptions_implementation.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
+++ (empty file)
@@ -1,111 +0,0 @@
-// ----------------------------------------------------------------------------
-// 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 
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-// For more information, see www.boost.org
-// ----------------------------------------------------------------------------
-#ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
-#define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
-
-namespace boost { namespace property_tree
-{
-
-    namespace detail
-    {
-
-        // Default path-to-string converter; this is overridden for default path
-        template<class P>
-        std::string path_to_string(const P &path)
-        {
-            return std::string("<cannot convert path to string>");
-        }
-
-        // Helper for preparing what string in ptree_bad_path exception
-        template<class P> 
-        std::string prepare_bad_path_what(const std::string &what,
-                                          const P &path)
-        {
-            // To allow correct resolution of path_to_string()
-            using namespace detail;
-            return what + " (" + path_to_string(path) + ")";
-        }
-
-        // Default data-to-string converter; this is overridden for default
-        // data (string)
-        template<class D>
-        std::string data_to_string(const D &data)
-        {
-            return std::string("<cannot convert data to string>");
-        }
-
-        // Helper for preparing what string in ptree_bad_data exception
-        template<class D>
-        std::string prepare_bad_data_what(const std::string &what,
-                                          const D &data)
-        {
-            // To allow correct resolution of data_to_string()
-            using namespace detail;
-            return what + " (" + data_to_string(data) + ")";
-        }
-
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // ptree_error
-
-    inline ptree_error::ptree_error(const std::string &what): 
-        std::runtime_error(what) 
-    {
-    }
-
-    inline ptree_error::~ptree_error() throw()
-    {
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // ptree_bad_data
-
-    template<class D>
-    ptree_bad_data::ptree_bad_data(const std::string &what, const D &data):
-        ptree_error(detail::prepare_bad_data_what(what, data)),
-        m_data(data)
-    {
-    }
-
-    inline ptree_bad_data::~ptree_bad_data() throw()
-    {
-    }
-
-    template<class D>
-    D ptree_bad_data::data()
-    {
-        return boost::any_cast<D>(m_data);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // ptree_bad_path
-
-    template<class P>
-    ptree_bad_path::ptree_bad_path(const std::string &what, const P &path):
-        ptree_error(detail::prepare_bad_path_what(what, path)),
-        m_path(path)
-    {
-
-    }
-
-    inline ptree_bad_path::~ptree_bad_path() throw()
-    {
-    }
-
-    template<class P>
-    P ptree_bad_path::path()
-    {
-        return boost::any_cast<P>(m_path);
-    }
-
-} }
-
-#endif
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-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -11,388 +11,528 @@
 #ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
 #define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
 
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <memory>
+
 namespace boost { namespace property_tree
 {
+    template <class K, class D, class C>
+    struct basic_ptree<K, D, C>::subs
+    {
+        struct by_name {};
+        // The actual child container.
+        typedef multi_index_container<value_type,
+            multi_index::indexed_by<
+                multi_index::sequenced<>,
+                multi_index::ordered_non_unique<multi_index::tag<by_name>,
+                    multi_index::member<value_type, const 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;
+
+        // Access functions for getting to the children of a tree.
+        static base_container& ch(self_type *s) {
+            return *static_cast<base_container*>(s->m_children);
+        }
+        static const base_container& ch(const self_type *s) {
+            return *static_cast<const base_container*>(s->m_children);
+        }
+        static by_name_index& assoc(self_type *s) {
+            return ch(s).get<by_name>();
+        }
+        static const by_name_index& assoc(const self_type *s) {
+            return ch(s).get<by_name>();
+        }
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor<
+        iterator, typename subs::base_container::iterator, value_type>
+    {
+        friend class boost::iterator_core_access;
+    public:
+        iterator() {}
+        explicit iterator(typename iterator::base_type b)
+            : iterator::iterator_adaptor_(b)
+        {}
+        typename iterator::reference dereference() const
+        {
+            // multi_index doesn't allow modification of its values, because
+            // indexes could sort by anything, and modification screws that up.
+            // However, we only sort by the key, and it's protected against
+            // modification in the value_type, so this const_cast is safe.
+            return const_cast<typename iterator::reference>(
+                *this->base_reference());
+        }
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor<
+        const_iterator, typename subs::base_container::const_iterator>
+    {
+    public:
+        const_iterator() {}
+        explicit const_iterator(typename const_iterator::base_type b)
+            : const_iterator::iterator_adaptor_(b)
+        {}
+        const_iterator(iterator b)
+            : const_iterator::iterator_adaptor_(b.base())
+        {}
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::reverse_iterator
+        : public boost::reverse_iterator<iterator>
+    {
+    public:
+        reverse_iterator() {}
+        explicit reverse_iterator(iterator b)
+            : boost::reverse_iterator<iterator>(b)
+        {}
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::const_reverse_iterator
+        : public boost::reverse_iterator<const_iterator>
+    {
+    public:
+        const_reverse_iterator() {}
+        explicit const_reverse_iterator(const_iterator b)
+            : boost::reverse_iterator<const_iterator>(b)
+        {}
+        const_reverse_iterator(reverse_iterator b)
+            : boost::reverse_iterator<const_iterator>(b)
+        {}
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::assoc_iterator
+        : public boost::iterator_adaptor<assoc_iterator,
+                                         typename subs::by_name_index::iterator,
+                                         value_type>
+    {
+        friend class boost::iterator_core_access;
+    public:
+        assoc_iterator() {}
+        explicit assoc_iterator(typename assoc_iterator::base_type b)
+            : assoc_iterator::iterator_adaptor_(b)
+        {}
+        typename assoc_iterator::reference dereference() const
+        {
+            return const_cast<typename assoc_iterator::reference>(
+                *this->base_reference());
+        }
+    };
+    template <class K, class D, class C>
+    class basic_ptree<K, D, C>::const_assoc_iterator
+        : public boost::iterator_adaptor<const_assoc_iterator,
+                                   typename subs::by_name_index::const_iterator>
+    {
+    public:
+        const_assoc_iterator() {}
+        explicit const_assoc_iterator(
+            typename const_assoc_iterator::base_type b)
+            : const_assoc_iterator::iterator_adaptor_(b)
+        {}
+        const_assoc_iterator(assoc_iterator b)
+            : const_assoc_iterator::iterator_adaptor_(b.base())
+        {}
+    };
+
+
+    // Big five
 
-    // Big four
+    // Perhaps the children collection could be created on-demand only, to
+    // reduce heap traffic. But that's a lot more work to implement.
 
-    template<class K, class D, class C, class A> inline
-    basic_ptree<K, D, C, A>::basic_ptree(allocator_type)
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C>::basic_ptree()
+        : m_children(new typename subs::base_container)
     {
-        // FIXME: use allocator
     }
 
-    template<class K, class D, class C, class A> inline
-    basic_ptree<K, D, C, A>::basic_ptree(const data_type &data,
-                                         allocator_type)
-        : m_data(rhs)
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C>::basic_ptree(const data_type &data)
+        : m_data(data), m_children(new typename subs::base_container)
     {
-        // FIXME: use allocator
     }
 
-    template<class K, class D, class C, class A> inline
-    basic_ptree<K, D, C, A>::basic_ptree(const basic_ptree<K, D, C, A> &rhs)
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs)
+        : m_data(rhs.m_data),
+          m_children(new typename subs::base_container(subs::ch(&rhs)))
     {
-        m_data = rhs.m_data;
-        insert(end(), rhs.begin(), rhs.end());
     }
 
-    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)
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs)
     {
-        if (&rhs != this)
-        {
-            clear();
-            data() = rhs.data();
-            insert(end(), rhs.begin(), rhs.end());
-        }
+        self_type(rhs).swap(*this);
         return *this;
     }
 
-    template<class K, class D, class C, class A> inline
-    void basic_ptree<K, D, C, A>::swap(basic_ptree<K, D, C, A> &rhs)
+    template<class K, class D, class C>
+    basic_ptree<K, D, C>::~basic_ptree()
+    {
+        delete &subs::ch(this);
+    }
+
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs)
     {
         m_data.swap(rhs.m_data);
-        m_children.swap(rhs.m_children);
+        // Void pointers, no ADL necessary
+        std::swap(m_children, rhs.m_children);
     }
 
     // Container view
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::size_type
-        basic_ptree<K, D, C, A>::size() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::size() const
     {
-        return m_children.size();
+        return subs::ch(this).size();
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::size_type
-        basic_ptree<K, D, C, A>::max_size() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::max_size() const
     {
-        return m_children.max_size();
+        return subs::ch(this).max_size();
     }
 
-    template<class K, class D, class C, class A> inline
-    bool basic_ptree<K, D, C, A>::empty() const
+    template<class K, class D, class C> inline
+    bool basic_ptree<K, D, C>::empty() const
     {
-        return m_children.empty();
+        return subs::ch(this).empty();
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::begin()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::begin()
     {
-        return m_children.begin();
+        return iterator(subs::ch(this).begin());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_iterator
-        basic_ptree<K, D, C, A>::begin() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_iterator
+        basic_ptree<K, D, C>::begin() const
     {
-        return m_children.begin();
+        return const_iterator(subs::ch(this).begin());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::end()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::end()
     {
-        return m_children.end();
+        return iterator(subs::ch(this).end());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_iterator
-        basic_ptree<K, D, C, A>::end() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_iterator
+        basic_ptree<K, D, C>::end() const
     {
-        return m_children.end();
+        return const_iterator(subs::ch(this).end());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::reverse_iterator
-        basic_ptree<K, D, C, A>::rbegin()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::reverse_iterator
+        basic_ptree<K, D, C>::rbegin()
     {
-        return m_children.rbegin();
+        return reverse_iterator(this->end());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_reverse_iterator
-        basic_ptree<K, D, C, A>::rbegin() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_reverse_iterator
+        basic_ptree<K, D, C>::rbegin() const
     {
-        return m_children.rbegin();
+        return const_reverse_iterator(this->end());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::reverse_iterator
-        basic_ptree<K, D, C, A>::rend()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::reverse_iterator
+        basic_ptree<K, D, C>::rend()
     {
-        return m_children.rend();
+        return reverse_iterator(this->begin());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_reverse_iterator
-        basic_ptree<K, D, C, A>::rend() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_reverse_iterator
+        basic_ptree<K, D, C>::rend() const
     {
-        return m_children.rend();
+        return const_reverse_iterator(this->begin());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::value_type &
-        basic_ptree<K, D, C, A>::front()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::front()
     {
-        return m_children.front();
+        return const_cast<value_type&>(subs::ch(this).front());
     }
 
-    template<class K, class D, class C, class A> inline
-    const typename basic_ptree<K, D, C, A>::value_type &
-        basic_ptree<K, D, C, A>::front() const
+    template<class K, class D, class C> inline
+    const typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::front() const
     {
-        return m_children.front();
+        return subs::ch(this).front();
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::value_type &
-        basic_ptree<K, D, C, A>::back()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::back()
     {
-        return m_children.back();
+        return const_cast<value_type&>(subs::ch(this).back());
     }
 
-    template<class K, class D, class C, class A> inline
-    const typename basic_ptree<K, D, C, A>::value_type &
-        basic_ptree<K, D, C, A>::back() const
+    template<class K, class D, class C> inline
+    const typename basic_ptree<K, D, C>::value_type &
+        basic_ptree<K, D, C>::back() const
     {
-        return m_children.back();
+        return subs::ch(this).back();
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-    basic_ptree<K, D, C, A>::insert(iterator where, const value_type &value)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+    basic_ptree<K, D, C>::insert(iterator where, const value_type &value)
     {
-        return m_children.insert(where, value).first;
+        return iterator(subs::ch(this).insert(where.base(), value).first);
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class It> inline
-    void basic_ptree<K, D, C, A>::insert(iterator where, It first, It last)
+    void basic_ptree<K, D, C>::insert(iterator where, It first, It last)
     {
-        m_children.insert(where, first, last);
+        subs::ch(this).insert(where.base(), first, last);
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::erase(iterator where)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::erase(iterator where)
     {
-        return m_children.erase(where);
+        return iterator(subs::ch(this).erase(where.base()));
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::erase(iterator first, iterator last)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::erase(iterator first, iterator last)
     {
-        return m_children.erase(first, last);
+        return iterator(subs::ch(this).erase(first.base(), last.base()));
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::push_front(const value_type &value)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::push_front(const value_type &value)
     {
-        return m_children.push_front(value).first;
+        return iterator(subs::ch(this).push_front(value).first);
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::push_back(const value_type &value)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::push_back(const value_type &value)
     {
-        return m_children.push_back(value).first;
+        return iterator(subs::ch(this).push_back(value).first);
     }
 
-    template<class K, class D, class C, class A> inline
-    void basic_ptree<K, D, C, A>::pop_front()
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::pop_front()
     {
-        m_children.pop_front();
+        subs::ch(this).pop_front();
     }
 
-    template<class K, class D, class C, class A> inline
-    void basic_ptree<K, D, C, A>::pop_back()
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::pop_back()
     {
-        m_children.pop_back();
+        subs::ch(this).pop_back();
     }
 
-    template<class K, class D, class C, class A> inline
-    void basic_ptree<K, D, C, A>::reverse()
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::reverse()
     {
-        m_children.reverse();
+        subs::ch(this).reverse();
     }
 
-    template<class K, class D, class C, class A> inline
-    void basic_ptree<K, D, C, A>::sort()
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::sort()
     {
-        m_children.sort();
+        subs::ch(this).sort();
     }
 
-    template<class K, class D, class C, class A> inline
-    template<class Compare>
-    void basic_ptree<K, D, C, A>::sort(Compare comp)
+    template<class K, class D, class C>
+    template<class Compare> inline
+    void basic_ptree<K, D, C>::sort(Compare comp)
     {
-        m_children.sort(comp);
+        subs::ch(this).sort(comp);
     }
 
     // Equality
 
-    template<class K, class D, class C, class A> inline
-    bool basic_ptree<K, D, C, A>::operator ==(
-                                  const basic_ptree<K, D, C, A> &rhs) const
+    template<class K, class D, class C> inline
+    bool basic_ptree<K, D, C>::operator ==(
+                                  const basic_ptree<K, D, C> &rhs) const
     {
         // The size test is cheap, so add it as an optimization
         return size() == rhs.size() && data() == rhs.data() &&
-            m_children == rhs.m_children;
+            subs::ch(this) == subs::ch(&rhs);
     }
 
-    template<class K, class D, class C, class A> inline
-    bool basic_ptree<K, D, C, A>::operator !=(
-                                  const basic_ptree<K, D, C, A> &rhs) const
+    template<class K, class D, class C> inline
+    bool basic_ptree<K, D, C>::operator !=(
+                                  const basic_ptree<K, D, C> &rhs) const
     {
         return !(*this == rhs);
     }
 
     // Associative view
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::assoc_iterator not_found()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::assoc_iterator
+        basic_ptree<K, D, C>::not_found()
     {
-        return assoc().end();
+        return assoc_iterator(subs::assoc(this).end());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_assoc_iterator not_found() const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_assoc_iterator
+        basic_ptree<K, D, C>::not_found() const
     {
-        return assoc().end();
+        return const_assoc_iterator(subs::assoc(this).end());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::assoc_iterator
-        basic_ptree<K, D, C, A>::find(const key_type &key)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::assoc_iterator
+        basic_ptree<K, D, C>::find(const key_type &key)
     {
-        return assoc().find(key);
+        return assoc_iterator(subs::assoc(this).find(key));
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_assoc_iterator
-        basic_ptree<K, D, C, A>::find(const key_type &key) const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_assoc_iterator
+        basic_ptree<K, D, C>::find(const key_type &key) const
     {
-        return assoc().find(key);
+        return const_assoc_iterator(subs::assoc(this).find(key));
     }
 
-    template<class K, class D, class C, class A> inline
+    template<class K, class D, class C> inline
     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)
-    {
-        return assoc().equal_range(key);
+        typename basic_ptree<K, D, C>::assoc_iterator,
+        typename basic_ptree<K, D, C>::assoc_iterator
+    > basic_ptree<K, D, C>::equal_range(const key_type &key)
+    {
+        std::pair<typename subs::by_name_index::iterator,
+                  typename subs::by_name_index::iterator> r(
+            subs::assoc(this).equal_range(key));
+        return std::pair<assoc_iterator, assoc_iterator>(r.first.base(),
+                                                         r.second.base());
     }
 
-    template<class K, class D, class C, class A> inline
+    template<class K, class D, class C> inline
     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
+        typename basic_ptree<K, D, C>::const_assoc_iterator,
+        typename basic_ptree<K, D, C>::const_assoc_iterator
+    > basic_ptree<K, D, C>::equal_range(const key_type &key) const
     {
-        return assoc().equal_range(key);
+        std::pair<typename subs::by_name_index::const_iterator,
+                  typename subs::by_name_index::const_iterator> r(
+            subs::assoc(this).equal_range(key));
+        return std::pair<const_assoc_iterator, const_assoc_iterator>(
+            r.first.base(), r.second.base());
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::size_type
-        basic_ptree<K, D, C, A>::count(const key_type &key) const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::count(const key_type &key) const
     {
-        return assoc().count(key);
+        return subs::assoc(this).count(key);
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::size_type
-        basic_ptree<K, D, C, A>::erase(const key_type &key)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::size_type
+        basic_ptree<K, D, C>::erase(const key_type &key)
     {
-        return assoc().erase(key);
+        return subs::assoc(this).erase(key);
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::iterator
-        basic_ptree<K, D, C, A>::to_iterator(assoc_iterator ai)
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::iterator
+        basic_ptree<K, D, C>::to_iterator(assoc_iterator ai)
     {
-        return m_children.project<0>(ai);
+        return iterator(subs::ch(this).project<0>(ai.base()));
     }
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::const_iterator
-        basic_ptree<K, D, C, A>::to_iterator(const_assoc_iterator ai) const
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::const_iterator
+        basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const
     {
-        return m_children.project<0>(ai);
+        return const_iterator(subs::ch(this).project<0>(ai.base()));
     }
 
-        // Property tree view
+    // Property tree view
 
-    template<class K, class D, class C, class A> inline
-    typename basic_ptree<K, D, C, A>::data_type &
-        basic_ptree<K, D, C, A>::data()
+    template<class K, class D, class C> inline
+    typename basic_ptree<K, D, C>::data_type &
+        basic_ptree<K, D, C>::data()
     {
         return m_data;
     }
 
-    template<class K, class D, class C, class A> inline
-    const typename basic_ptree<K, D, C, A>::data_type &
-        basic_ptree<K, D, C, A>::data() const
+    template<class K, class D, class C> inline
+    const typename basic_ptree<K, D, C>::data_type &
+        basic_ptree<K, D, C>::data() const
     {
         return m_data;
     }
 
-    template<class K, class D, class C, class A> inline
-    void basic_ptree<K, D, C, A>::clear()
+    template<class K, class D, class C> inline
+    void basic_ptree<K, D, C>::clear()
     {
         m_data = data_type();
-        m_children.clear();
+        subs::ch(this).clear();
     }
 
-    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)
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::get_child(const path_type &path)
     {
         path_type p(path);
         self_type *n = walk_path(p);
         if (!n) {
-            BOOST_PROPERTY_TREE_THROW(ptree_bad_path(path));
+            BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path));
         }
         return *n;
     }
 
-    template<class K, class D, class C, class A> inline
-    const basic_ptree<K, D, C, A> &
-        basic_ptree<K, D, C, A>::get_child(const path_type &path) const
+    template<class K, class D, class C> inline
+    const basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::get_child(const path_type &path) const
     {
         return const_cast<self_type*>(this)->get_child(path);
     }
 
-    template<class K, class D, class C, class A> inline
-    basic_ptree<K, D, C, A> &
-        basic_ptree<K, D, C, A>::get_child(const path_type &path,
-                                           self_type &default_value)
+    template<class K, class D, class C> inline
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::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;
     }
 
-    template<class K, class D, class C, class A> inline
-    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
+    template<class K, class D, class C> inline
+    const basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::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));
+            const_cast<self_type&>(default_value));
     }
 
 
-    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)
+    template<class K, class D, class C>
+    optional<basic_ptree<K, D, C> &>
+        basic_ptree<K, D, C>::get_child_optional(const path_type &path)
     {
         path_type p(path);
         self_type *n = walk_path(p);
@@ -402,9 +542,9 @@
         return *n;
     }
 
-    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
+    template<class K, class D, class C>
+    optional<const basic_ptree<K, D, C> &>
+        basic_ptree<K, D, C>::get_child_optional(const path_type &path) const
     {
         path_type p(path);
         self_type *n = walk_path(p);
@@ -414,56 +554,42 @@
         return *n;
     }
 
-    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)
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::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. If it exists,
-        // replace it.
-        if(range.first != range.second) {
-            return *range.first = value;
+        key_type fragment = p.reduce();
+        assoc_iterator el = parent.find(fragment);
+        // If the new child exists, replace it.
+        if(el != parent.not_found()) {
+            return el->second = value;
         } else {
-            return parent->push_back(value_type(fragment.first, value));
+            return parent.push_back(value_type(fragment, value))->second;
         }
     }
 
-    template<class K, class D, class C, class A>
-    basic_ptree<K, D, C, A> &
-        basic_ptree<K, D, C, A>::add_child(const path_type &path,
-                                           const self_type &value)
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> &
+        basic_ptree<K, D, C>::add_child(const path_type &path,
+                                        const self_type &value)
     {
         path_type p(path);
         self_type &parent = force_path(p);
         // Got the parent.
-        std::pair<key_type, std::size_t> fragment = p.reduce();
-        assert(fragment.second == 0 &&
-            "Cannot specify an index for the last fragment of the path");
-        return parent->push_back(value_type(fragment.first, value));
+        key_type fragment = p.reduce();
+        return parent.push_back(value_type(fragment, value))->second;
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, class Translator>
-    Type basic_ptree<K, D, C, A>::get_value(Translator tr) const
+    typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+    basic_ptree<K, D, C>::get_value(Translator tr) const
     {
-        if(boost::optional<Type> o = get_value_optional(tr)) {
+        if(boost::optional<Type> o = get_value_optional<Type>(tr)) {
             return *o;
         }
         BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
@@ -471,80 +597,130 @@
             typeid(Type).name() + "\" failed", data()));
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type> inline
-    Type basic_ptree<K, D, C, A>::get_value() const
+    Type basic_ptree<K, D, C>::get_value() const
     {
-        return get_value(typename translator_between<data_type, Type>::type());
+        return get_value<Type>(
+            typename translator_between<data_type, Type>::type());
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, class Translator> inline
-    Type basic_ptree<K, D, C, A>::get_value(const Type &default_value,
-                                            Translator tr) const
+    Type basic_ptree<K, D, C>::get_value(const Type &default_value,
+                                         Translator tr) const
     {
-        return get_value_optional(tr).get_value_or(default_value);
+        return get_value_optional<Type>(tr).get_value_or(default_value);
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
+    template <class Ch, class Translator>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const
+    {
+        return get_value<std::basic_string<Ch>, Translator>(default_value, tr);
+    }
+
+    template<class K, class D, class C>
     template<class Type> inline
-    Type basic_ptree<K, D, C, A>::get_value(const Type &default_value) const
+    typename boost::disable_if<detail::is_translator<Type>, Type>::type
+    basic_ptree<K, D, C>::get_value(const Type &default_value) const
     {
         return get_value(default_value,
                          typename translator_between<data_type, Type>::type());
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
+    template <class Ch>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get_value(const Ch *default_value) const
+    {
+        return get_value< std::basic_string<Ch> >(default_value);
+    }
+
+    template<class K, class D, class C>
     template<class Type, class Translator> inline
-    optional<Type> basic_ptree<K, D, C, A>::get_value_optional(
+    optional<Type> basic_ptree<K, D, C>::get_value_optional(
                                                 Translator tr) const
     {
         return tr.get_value(data());
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type> inline
-    optional<Type> basic_ptree<K, D, C, A>::get_value_optional() const
+    optional<Type> basic_ptree<K, D, C>::get_value_optional() const
     {
-        return get_value_optional(
+        return get_value_optional<Type>(
             typename translator_between<data_type, Type>::type());
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, class Translator> inline
-    Type basic_ptree<K, D, C, A>::get(const path_type &path,
-                                      Translator tr) const
+    typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+    basic_ptree<K, D, C>::get(const path_type &path,
+                              Translator tr) const
     {
         return get_child(path).get_value<Type>(tr);
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type> inline
-    Type basic_ptree<K, D, C, A>::get(const path_type &path) const
+    Type basic_ptree<K, D, C>::get(const path_type &path) const
     {
         return get_child(path).get_value<Type>();
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, class Translator> inline
-    Type basic_ptree<K, D, C, A>::get(const path_type &path,
-                                      const Type &default_value,
-                                      Translator tr) const
+    Type basic_ptree<K, D, C>::get(const path_type &path,
+                                   const Type &default_value,
+                                   Translator tr) const
     {
         return get_optional<Type>(path, tr).get_value_or(default_value);
     }
 
-    template<class K, class D, class C, class A>
-    template<class Type, class Translator> inline
-    Type basic_ptree<K, D, C, A>::get(const path_type &path,
-                                      const Type &default_value) const
+    template<class K, class D, class C>
+    template <class Ch, class Translator>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get(
+        const path_type &path, const Ch *default_value, Translator tr) const
+    {
+        return get<std::basic_string<Ch>, Translator>(path, default_value, tr);
+    }
+
+    template<class K, class D, class C>
+    template<class Type> inline
+    typename boost::disable_if<detail::is_translator<Type>, Type>::type
+    basic_ptree<K, D, C>::get(const path_type &path,
+                              const Type &default_value) const
     {
         return get_optional<Type>(path).get_value_or(default_value);
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
+    template <class Ch>
+    typename boost::enable_if<
+        detail::is_character<Ch>,
+        std::basic_string<Ch>
+    >::type
+    basic_ptree<K, D, C>::get(
+        const path_type &path, const Ch *default_value) const
+    {
+        return get< std::basic_string<Ch> >(path, default_value);
+    }
+
+    template<class K, class D, class C>
     template<class Type, class Translator>
-    optional<Type> basic_ptree<K, D, C, A>::get_optional(const path_type &path,
+    optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path,
                                                          Translator tr) const
     {
         if (optional<const self_type&> child = get_child_optional(path))
@@ -553,9 +729,9 @@
             return optional<Type>();
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type>
-    optional<Type> basic_ptree<K, D, C, A>::get_optional(
+    optional<Type> basic_ptree<K, D, C>::get_optional(
                                                 const path_type &path) const
     {
         if (optional<const self_type&> child = get_child_optional(path))
@@ -564,9 +740,9 @@
             return optional<Type>();
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, class Translator>
-    void basic_ptree<K, D, C, A>::put_value(const Type &value, Translator tr)
+    void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr)
     {
         if(optional<data_type> o = tr.put_value(value)) {
             data() = *o;
@@ -577,16 +753,16 @@
         }
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type> inline
-    void basic_ptree<K, D, C, A>::put_value(const Type &value)
+    void basic_ptree<K, D, C>::put_value(const Type &value)
     {
         put_value(value, typename translator_between<data_type, Type>::type());
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, typename Translator>
-    basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::put(
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
         const path_type &path, const Type &value, Translator tr)
     {
         if(optional<self_type &> child = get_child_optional(path)) {
@@ -599,28 +775,28 @@
         }
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type> inline
-    basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::put(
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
         const path_type &path, const Type &value)
     {
         return put(path, value,
                    typename translator_between<data_type, Type>::type());
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type, typename Translator> inline
-    basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::add(
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
         const path_type &path, const Type &value, Translator tr)
     {
-        self_type &child = put_child(path, self_type());
+        self_type &child = add_child(path, self_type());
         child.put_value(value, tr);
         return child;
     }
 
-    template<class K, class D, class C, class A>
+    template<class K, class D, class C>
     template<class Type> inline
-    basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::add(
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
         const path_type &path, const Type &value)
     {
         return add(path, value,
@@ -628,65 +804,46 @@
     }
 
 
-    template<class K, class D, class C, class A>
-    basic_ptree<K, D, C, A> *
-    basic_ptree<K, D, C, A>::walk_path(path_type &p) const
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> *
+    basic_ptree<K, D, C>::walk_path(path_type &p) const
     {
         if(p.empty()) {
             // I'm the child we're looking for.
-            return this;
+            return const_cast<basic_ptree*>(this);
         }
         // Recurse down the tree to find the path.
-        std::pair<key_type, std::size_t> fragment = p.reduce();
-        std::pair<const_assoc_iterator, const_assoc_iterator> range =
-            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(range.first == range.second) {
+        key_type fragment = p.reduce();
+        const_assoc_iterator el = find(fragment);
+        if(el == not_found()) {
             // No such child.
             return 0;
         }
         // Not done yet, recurse.
-        return range.first->walk_path(p);
+        return el->second.walk_path(p);
     }
 
-    template<class K, class D, class C, class A>
-    basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::force_path(path_type &p)
+    template<class K, class D, class C>
+    basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p)
     {
         assert(!p.empty() && "Empty path not allowed for put_child.");
         if(p.single()) {
             // I'm the parent we're looking for.
             return *this;
         }
-        std::pair<key_type, std::size_t> fragment = p.reduce();
-        std::pair<const_assoc_iterator, const_assoc_iterator> range =
-            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) {
-            push_back(self_type());
-        }
-        // Now if we've found an existing child, go down that path. Else
+        key_type fragment = p.reduce();
+        assoc_iterator el = find(fragment);
+        // If we've found an existing child, go down that path. Else
         // create a new one.
-        self_type& child = range.first == range.second ?
-                               push_back(self_type()) : *range.first;
+        self_type& child = el == not_found() ?
+            push_back(value_type(fragment, self_type()))->second : el->second;
         return child.force_path(p);
     }
 
     // Free functions
 
-    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)
+    template<class K, class D, class C>
+    inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2)
     {
         pt1.swap(pt2);
     }
Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_utils.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_utils.hpp	(original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_utils.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -11,6 +11,9 @@
 #define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
 
 #include <boost/limits.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/and.hpp>
 #include <string>
 #include <algorithm>
 #include <locale>
@@ -34,6 +37,21 @@
         }
     };
 
+    template <typename Ch>
+    struct is_character : public boost::false_type {};
+    template <>
+    struct is_character<char> : public boost::true_type {};
+    template <>
+    struct is_character<wchar_t> : public boost::true_type {};
+
+
+    BOOST_MPL_HAS_XXX_TRAIT_DEF(internal_type)
+    BOOST_MPL_HAS_XXX_TRAIT_DEF(external_type)
+    template <typename T>
+    struct is_translator : public boost::mpl::and_<
+        has_internal_type<T>, has_external_type<T> > {};
+
+
 
     // Naively convert narrow string to another character type
     template<class Ch>
Added: branches/sredl_2009_05_proptree_update/boost/property_tree/exceptions.hpp
==============================================================================
--- (empty file)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/exceptions.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -0,0 +1,84 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2002-2006 Marcin Kalicinski
+// Copyright (C) 2009 Sebastian Redl
+//
+// 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
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_EXCEPTIONS_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+#include <boost/any.hpp>
+#include <string>
+#include <stdexcept>
+
+namespace boost { namespace property_tree
+{
+
+    /// 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);
+
+        ~ptree_error() throw();
+    };
+
+
+    /// 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();
+
+        /// Retrieve the invalid path.
+        template<class T> T path();
+    private:
+        boost::any m_path;
+    };
+
+}}
+
+#include <boost/property_tree/detail/exception_implementation.hpp>
+
+#endif
Added: branches/sredl_2009_05_proptree_update/boost/property_tree/id_translator.hpp
==============================================================================
--- (empty file)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/id_translator.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -0,0 +1,51 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2009 Sebastian Redl
+//
+// 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
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_ID_TRANSLATOR_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+#include <boost/optional.hpp>
+#include <string>
+
+namespace boost { namespace property_tree
+{
+
+    /// Simple implementation of the Translator concept. It does no translation.
+    template <typename T>
+    struct id_translator
+    {
+        typedef T internal_type;
+        typedef T external_type;
+
+        boost::optional<T> get_value(const T &v) { return v; }
+        boost::optional<T> put_value(const T &v) { return v; }
+    };
+
+    // This is the default translator whenever you get two equal types.
+    template <typename T>
+    struct translator_between<T, T>
+    {
+        typedef id_translator<T> type;
+    };
+
+    // A more specific specialization for std::basic_string. Otherwise,
+    // stream_translator's specialization wins.
+    template <typename Ch, typename Traits, typename Alloc>
+    struct translator_between< std::basic_string<Ch, Traits, Alloc>,
+                               std::basic_string<Ch, Traits, Alloc> >
+    {
+        typedef id_translator< std::basic_string<Ch, Traits, Alloc> > type;
+    };
+
+}}
+
+#endif
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-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -9,29 +9,25 @@
 // For more information, see www.boost.org
 // ----------------------------------------------------------------------------
 
-/// This header contains definition of basic_ptree class template and
-/// supporting definitions.
-
 #ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
 #define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
 
 #include <boost/property_tree/ptree_fwd.hpp>
+#include <boost/property_tree/string_path.hpp>
+#include <boost/property_tree/stream_translator.hpp>
+#include <boost/property_tree/exceptions.hpp>
 #include <boost/property_tree/detail/ptree_utils.hpp>
 
 #include <boost/multi_index_container.hpp>
+#include <boost/multi_index/indexed_by.hpp>
 #include <boost/multi_index/sequenced_index.hpp>
 #include <boost/multi_index/ordered_index.hpp>
 #include <boost/multi_index/member.hpp>
-
+#include <boost/utility/enable_if.hpp>
+#include <boost/throw_exception.hpp>
 #include <boost/optional.hpp>
-
 #include <utility>                  // for std::pair
 
-#if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
-    // Throwing macro to avoid no return warnings portably
-#   define BOOST_PROPERTY_TREE_THROW(e) { throw_exception(e); std::exit(1); }
-#endif
-
 namespace boost { namespace property_tree
 {
 
@@ -44,13 +40,11 @@
      * Key equivalency is defined by @p KeyCompare, a predicate defining a
      * strict weak ordering.
      *
-     * All data structures are allocated with some version of @p Allocator.
-     *
      * 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>
+    template<class Key, class Data, class KeyCompare>
     class basic_ptree
     {
 #if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
@@ -61,60 +55,41 @@
          * 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> self_type;
+        typedef basic_ptree<Key, Data, KeyCompare> self_type;
 
     public:
         // Basic types
         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:
-        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;
+        typedef std::pair<const Key, self_type>      value_type;
+        typedef std::size_t                          size_type;
 
-    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;
+        // The problem with the iterators is that I can't make them complete
+        // until the container is complete. Sucks. Especially for the reverses.
+        class iterator;
+        class const_iterator;
+        class reverse_iterator;
+        class const_reverse_iterator;
 
         // Associative view types
-        typedef typename by_name_index::iterator          assoc_iterator;
-        typedef typename by_name_index::const_iterator    const_assoc_iterator;
+        class assoc_iterator;
+        class const_assoc_iterator;
 
         // Property tree view types
         typedef typename path_of<Key>::type          path_type;
 
 
-        // The big four
+        // The big five
 
         /** Creates a node with no children and default-constructed data. */
-        explicit basic_ptree(allocator_type alloc = allocator_type());
+        basic_ptree();
         /** 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());
+        explicit basic_ptree(const data_type &data);
         basic_ptree(const self_type &rhs);
+        ~basic_ptree();
         /** Basic guarantee only. */
         self_type &operator =(const self_type &rhs);
 
@@ -238,8 +213,9 @@
         /** Count the number of direct children with the given key. */
         size_type count(const key_type &key) const;
 
-        /** Erase all direct children with the given key. */
-        void erase(const key_type &key);
+        /** Erase all direct children with the given key and return the count.
+         */
+        size_type erase(const key_type &key);
 
         /** Get the iterator that points to the same element as the argument.
          * @note A valid assoc_iterator range (a, b) does not imply that
@@ -251,7 +227,7 @@
          * @note A valid const_assoc_iterator range (a, b) does not imply that
          *       (to_iterator(a), to_iterator(b)) is a valid range.
          */
-        const_iterator to_iterator(const_assoc_iterator it);
+        const_iterator to_iterator(const_assoc_iterator it) const;
 
         // Property tree view
 
@@ -321,8 +297,8 @@
          * @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;
+        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+        get_value(Translator tr) const;
 
         /** Take the value of this node and attempt to translate it to a
          * @c Type object using the default translator.
@@ -338,12 +314,29 @@
         template<class Type, class Translator>
         Type get_value(const Type &default_value, Translator tr) const;
 
+        /** Make get_value do the right thing for string literals. */
+        template <class Ch, class Translator>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get_value(const Ch *default_value, Translator tr) const;
+
         /** Take the value of this node and attempt to translate it to a
          * @c Type object using the default translator. Return @p default_value
          * if this fails.
          */
         template<class Type>
-        Type get_value(const Type &default_value) const;
+        typename boost::disable_if<detail::is_translator<Type>, Type>::type
+        get_value(const Type &default_value) const;
+
+        /** Make get_value do the right thing for string literals. */
+        template <class Ch>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get_value(const Ch *default_value) 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
@@ -375,7 +368,8 @@
 
         /** Shorthand for get_child(path).get_value(tr). */
         template<class Type, class Translator>
-        Type get(const path_type &path, Translator tr) const;
+        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
+        get(const path_type &path, Translator tr) const;
 
         /** Shorthand for get_child(path).get_value\<Type\>(). */
         template<class Type>
@@ -391,13 +385,30 @@
                  const Type &default_value,
                  Translator tr) const;
 
+        /** Make get do the right thing for string literals. */
+        template <class Ch, class Translator>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get(const path_type &path, const Ch *default_value, Translator tr)const;
+
         /** Shorthand for get_child(path, empty_ptree())
          *                    .get_value(default_value).
          * That is, return the translated value if possible, and the default
          * value if the node doesn't exist or conversion fails.
          */
         template<class Type>
-        Type get(const path_type &path, const Type &default_value) const;
+        typename boost::disable_if<detail::is_translator<Type>, Type>::type
+        get(const path_type &path, const Type &default_value) const;
+
+        /** Make get do the right thing for string literals. */
+        template <class Ch>
+        typename boost::enable_if<
+            detail::is_character<Ch>,
+            std::basic_string<Ch>
+        >::type
+        get(const path_type &path, const Ch *default_value) const;
 
         /** Shorthand for:
          * @code
@@ -405,9 +416,10 @@
          *   return node->get_value_optional(tr);
          * return boost::null;
          * @endcode
+         * That is, return the value if it exists and can be converted, or nil.
         */
         template<class Type, class Translator>
-        Type get_optional(const path_type &path, Translator tr) const;
+        optional<Type> get_optional(const path_type &path, Translator tr) const;
 
         /** Shorthand for:
          * @code
@@ -417,7 +429,7 @@
          * @endcode
         */
         template<class Type>
-        Type get_optional(const path_type &path) const;
+        optional<Type> get_optional(const path_type &path) 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
@@ -471,14 +483,9 @@
     private:
         // Hold the data of this node
         data_type m_data;
-        // Hold the children
-        base_container m_children;
-
-        // Convenience
-        by_name_index& assoc() { return m_children.get<by_name>(); }
-        const by_name_index& assoc() const {
-            return m_children.get<by_name>();
-        }
+        // Hold the children - this is a void* because we can't complete the
+        // container type within the class.
+        void* m_children;
 
         // Getter tree-walk. Not const-safe! Gets the node the path refers to,
         // or null. Destroys p's value.
@@ -488,11 +495,18 @@
         // path, creating nodes as necessary. p is the path to the remaining
         // child.
         self_type& force_path(path_type& p);
+
+        // This struct contains typedefs for the concrete types.
+        struct subs;
+        friend struct subs;
+        friend class iterator;
+        friend class const_iterator;
+        friend class reverse_iterator;
+        friend class const_reverse_iterator;
     };
 
-} }
+}}
 
-// Include implementations
 #include <boost/property_tree/detail/ptree_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-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -12,8 +12,10 @@
 #define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
 
 #include <boost/config.hpp>
+#include <boost/optional/optional_fwd.hpp>
 #include <functional>           // for std::less
 #include <memory>               // for std::allocator
+#include <string>
 
 namespace boost { namespace property_tree
 {
@@ -21,14 +23,12 @@
         template <typename T> struct less_nocase;
     }
 
-    ///////////////////////////////////////////////////////////////////////////
     // Classes
 
-    template <class Key, class Data,
-              class KeyCompare = std::less<Key>,
-              class Allocator = std::allocator<Data>>
+    template < class Key, class Data, class KeyCompare = std::less<Key> >
     class basic_ptree;
 
+    template <typename T>
     struct id_translator;
 
     template <typename String, typename Translator>
@@ -36,23 +36,33 @@
 
     // 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();
+    concept PropertyTreePath<class Path> {
+        // The key type for which this path works.
+        typename key_type;
+        // Return the key that the first segment of the path names.
+        // Split the head off the state.
+        key_type Path::reduce();
 
-      // Return true if the path is empty.
-      bool Path::empty();
+        // Return true if the path is empty.
+        bool Path::empty() const;
 
-      // Return true if the path contains a single element.
-      bool Path::single();
+        // Return true if the path contains a single element.
+        bool Path::single() const;
+
+        // Dump as a std::string, for exception messages.
+        std::string Path::dump() const;
     }
-    concept PropertyTreeKey<Key> {
+    concept PropertyTreeKey<class Key> {
         PropertyTreePath path;
         requires SameType<Key, PropertyTreePath<path>::key_type>;
     }
+    concept PropertyTreeTranslator<class Tr> {
+        typename internal_type;
+        typename external_type;
+
+        boost::optional<external_type> Tr::get_value(internal_type);
+        boost::optional<internal_type> Tr::put_value(external_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
@@ -62,24 +72,23 @@
     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
+    /// in a tree whose data_type is Internal, 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>
+    /// This is already specialized for Internal being std::basic_string.
+    template <typename Internal, typename External>
     struct translator_between;
 
     class ptree_error;
     class ptree_bad_data;
     class ptree_bad_path;
 
-    ///////////////////////////////////////////////////////////////////////////
     // Typedefs
 
     /** Implements a path using a std::string as the key. */
-    typedef string_path<std::string, id_translator> path;
+    typedef string_path<std::string, id_translator<std::string> > path;
 
     /** Implements a path using a std::wstring as the key. */
-    typedef string_path<std::wstring, id_translator> wpath;
+    typedef string_path<std::wstring, id_translator<std::wstring> > wpath;
 
     /**
      * A property tree with std::string for key and data, and default
@@ -113,22 +122,21 @@
         wiptree;
 #endif
 
-    ///////////////////////////////////////////////////////////////////////////
     // Free functions
 
     /**
      * Swap two property tree instances.
      */
-    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);
-
-    /** 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);
+    template<class K, class D, class C>
+    void swap(basic_ptree<K, D, C> &pt1,
+              basic_ptree<K, D, C> &pt2);
 
 } }
 
+
+#if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
+    // Throwing macro to avoid no return warnings portably
+#   define BOOST_PROPERTY_TREE_THROW(e) { throw_exception(e); std::exit(1); }
+#endif
+
 #endif
Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_serialization.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_serialization.hpp	(original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_serialization.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -38,14 +38,13 @@
      * @param file_version file_version for the archive.
      * @post @c ar will contain the serialized form of @c t.
      */
-    template<class Archive, class D, class K,
-             class C, class A, class P, class X>
+    template<class Archive, class K, class D, class C>
     inline void save(Archive &ar,
-                     const basic_ptree<D, K, C, A, P, X> &t,
+                     const basic_ptree<K, D, C> &t,
                      const unsigned int file_version)
     {
         using namespace boost::serialization;
-        stl::save_collection<Archive, basic_ptree<D, K, C, A, P, X> >(ar, t);
+        stl::save_collection<Archive, basic_ptree<K, D, C> >(ar, t);
         ar << make_nvp("data", t.data());
     }
 
@@ -62,24 +61,23 @@
      * @param file_version file_version for the archive.
      * @post @c t will contain the de-serialized data from @c ar.
      */
-    template<class Archive, class D, class K,
-             class C, class A, class P, class X>
+    template<class Archive, class K, class D, class C>
     inline void load(Archive &ar,
-                     basic_ptree<D, K, C, A, P, X> &t,
+                     basic_ptree<K, D, C> &t,
                      const unsigned int file_version)
     {
         using namespace boost::serialization;
         // Load children
         stl::load_collection<Archive,
-                             basic_ptree<D, K, C, A, P, X>,
+                             basic_ptree<K, D, C>,
                              stl::archive_input_seq<Archive,
-                                 basic_ptree<D, K, C, A, P, X> >,
+                                 basic_ptree<K, D, C> >,
                              stl::no_reserve_imp<
-                                 basic_ptree<D, K, C, A, P, X> >
+                                 basic_ptree<K, D, C> >
                             >(ar, t);
 
         // Load data (must be after load_collection, as it calls clear())
-        ar >> serialization::make_nvp("data", t.data());
+        ar >> make_nvp("data", t.data());
     }
 
     /**
@@ -90,10 +88,9 @@
      * @param t The property tree to load or save.
      * @param file_version file_version for the archive.
      */
-    template<class Archive, class D, class K,
-             class C, class A, class P, class X>
+    template<class Archive, class K, class D, class C>
     inline void serialize(Archive &ar,
-                          basic_ptree<D, K, C, A, P, X> &t,
+                          basic_ptree<K, D, C> &t,
                           const unsigned int file_version)
     {
         using namespace boost::serialization;
Added: branches/sredl_2009_05_proptree_update/boost/property_tree/stream_translator.hpp
==============================================================================
--- (empty file)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/stream_translator.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -0,0 +1,188 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2009 Sebastian Redl
+//
+// 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
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_STREAM_TRANSLATOR_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+#include <boost/optional.hpp>
+#include <boost/optional/optional_io.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <sstream>
+#include <string>
+#include <locale>
+#include <limits>
+
+namespace boost { namespace property_tree
+{
+
+    template <typename Ch, typename Traits, typename E, typename Enabler = void>
+    struct customize_stream
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, const E& e) {
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, E& e) {
+            s >> e;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    // No whitespace skipping for single characters.
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, Ch, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, Ch e) {
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, Ch& e) {
+            s.unsetf(std::ios_base::skipws);
+            s >> e;
+        }
+    };
+
+    template <typename Ch, typename Traits, typename F>
+    struct customize_stream<Ch, Traits, F,
+        typename boost::enable_if_c<
+            std::numeric_limits<typename boost::decay<F>::type>::is_specialized
+            && !std::numeric_limits<typename boost::decay<F>::type>::is_exact
+        >::type
+    >
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, const F& e) {
+            s.precision(std::numeric_limits<F>::digits10 + 1);
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, F& e) {
+            s >> e;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, bool, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, bool e) {
+            s.setf(std::ios_base::boolalpha);
+            s << e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, bool& e) {
+            s >> e;
+            if(s.fail()) {
+                // Try again in word form.
+                s.clear();
+                s.setf(std::ios_base::boolalpha);
+                s >> e;
+            }
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, signed char, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, signed char e) {
+            s << (int)e;
+        }
+        static void extract(std::basic_istream<Ch, Traits>& s, signed char& e) {
+            int i;
+            s >> i;
+            // out of range?
+            if(i > std::numeric_limits<signed char>::max() ||
+                i < std::numeric_limits<signed char>::min())
+            {
+                s.clear(); // guarantees eof to be unset
+                return;
+            }
+            e = (signed char)i;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    template <typename Ch, typename Traits>
+    struct customize_stream<Ch, Traits, unsigned char, void>
+    {
+        static void insert(std::basic_ostream<Ch, Traits>& s, unsigned char e) {
+            s << (unsigned)e;
+        }
+        static void extract(std::basic_istream<Ch,Traits>& s, unsigned char& e){
+            unsigned i;
+            s >> i;
+            // out of range?
+            if(i > std::numeric_limits<unsigned char>::max()) {
+                s.clear(); // guarantees eof to be unset
+                return;
+            }
+            e = (unsigned char)i;
+            if(!s.eof()) {
+                s >> std::ws;
+            }
+        }
+    };
+
+    /// Implementation of Translator that uses the stream overloads.
+    template <typename Ch, typename Traits, typename Alloc, typename E>
+    class stream_translator
+    {
+        typedef customize_stream<Ch, Traits, E> customized;
+    public:
+        typedef std::basic_string<Ch, Traits, Alloc> internal_type;
+        typedef E external_type;
+
+        explicit stream_translator(std::locale loc = std::locale())
+            : m_loc(loc)
+        {}
+
+        boost::optional<E> get_value(const internal_type &v) {
+            std::basic_istringstream<Ch, Traits, Alloc> iss(v);
+            iss.imbue(m_loc);
+            E e;
+            customized::extract(iss, e);
+            if(iss.fail() || iss.bad() || iss.get() != Traits::eof()) {
+                return boost::optional<E>();
+            }
+            return e;
+        }
+        boost::optional<internal_type> put_value(const E &v) {
+            std::basic_ostringstream<Ch, Traits, Alloc> oss;
+            oss.imbue(m_loc);
+            customized::insert(oss, v);
+            if(oss) {
+                return oss.str();
+            }
+            return boost::optional<internal_type>();
+        }
+
+    private:
+        std::locale m_loc;
+    };
+
+    // This is the default translator when basic_string is the internal type.
+    // Unless the external type is also basic_string, in which case
+    // id_translator takes over.
+    template <typename Ch, typename Traits, typename Alloc, typename E>
+    struct translator_between<std::basic_string<Ch, Traits, Alloc>, E>
+    {
+        typedef stream_translator<Ch, Traits, Alloc, E> type;
+    };
+
+}}
+
+#endif
Added: branches/sredl_2009_05_proptree_update/boost/property_tree/string_path.hpp
==============================================================================
--- (empty file)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/string_path.hpp	2009-06-11 18:20:05 EDT (Thu, 11 Jun 2009)
@@ -0,0 +1,270 @@
+// ----------------------------------------------------------------------------
+// Copyright (C) 2009 Sebastian Redl
+//
+// 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
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED
+#define BOOST_PROPERTY_TREE_STRING_PATH_HPP_INCLUDED
+
+#include <boost/property_tree/ptree_fwd.hpp>
+#include <boost/property_tree/id_translator.hpp>
+#include <boost/property_tree/exceptions.hpp>
+#include <boost/property_tree/detail/ptree_utils.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/optional.hpp>
+#include <boost/throw_exception.hpp>
+#include <algorithm>
+#include <string>
+#include <iterator>
+
+namespace boost { namespace property_tree
+{
+    namespace detail
+    {
+        template <typename Sequence, typename Iterator>
+        void append_and_preserve_iter(Sequence &s, const Sequence &r,
+                                      Iterator &, std::forward_iterator_tag)
+        {
+            // Here we boldly assume that anything that is not random-access
+            // preserves validity. This is valid for the STL sequences.
+            s.insert(s.end(), r.begin(), r.end());
+        }
+        template <typename Sequence, typename Iterator>
+        void append_and_preserve_iter(Sequence &s, const Sequence &r,
+                                      Iterator &it,
+                                      std::random_access_iterator_tag)
+        {
+            // Convert the iterator to an index, and later back.
+            typename std::iterator_traits<Iterator>::difference_type idx =
+                it - s.begin();
+            s.insert(s.end(), r.begin(), r.end());
+            it = s.begin() + idx;
+        }
+
+        template <typename Sequence>
+        std::string dump_sequence(const Sequence &)
+        {
+            return "<undumpable sequence>";
+        }
+        std::string dump_sequence(const std::string &s)
+        {
+            return s;
+        }
+        std::string dump_sequence(const std::wstring &s)
+        {
+            return narrow(s.c_str());
+        }
+    }
+
+    /// Default path class. A path is a sequence of values. Groups of values
+    /// are separated by the separator value, which defaults to '.' cast to
+    /// the sequence's value type. The group of values is then passed to the
+    /// translator to get a key.
+    ///
+    /// If instantiated with std::string and id_translator\<std::string\>,
+    /// it accepts paths of the form "one.two.three.four".
+    ///
+    /// @tparam String Any Sequence. If the sequence does not support random-
+    ///                access iteration, concatenation of paths assumes that
+    ///                insertions at the end preserve iterator validity.
+    /// @tparam Translator A translator with internal_type == String.
+    template <typename String, typename Translator>
+    class string_path
+    {
+        BOOST_STATIC_ASSERT((is_same<String,
+                                   typename Translator::internal_type>::value));
+    public:
+        typedef typename Translator::external_type key_type;
+        typedef typename String::value_type char_type;
+
+        /// Create an empty path.
+        string_path();
+        /// Create a path by parsing the given string.
+        /// @param value A sequence, possibly with separators, that describes
+        ///              the path, e.g. "one.two.three".
+        /// @param separator The separator used in parsing. Defaults to '.'.
+        /// @param tr The translator used by this path to convert the individual
+        ///           parts to keys.
+        string_path(const String &value, char_type separator = char_type('.'),
+                    Translator tr = Translator());
+        /// Create a path by parsing the given string.
+        /// @param value A zero-terminated array of values. Only use if zero-
+        ///              termination makes sense for your type, and your
+        ///              sequence supports construction from it. Intended for
+        ///              string literals.
+        /// @param separator The separator used in parsing. Defaults to '.'.
+        /// @param tr The translator used by this path to convert the individual
+        ///           parts to keys.
+        string_path(const char_type *value,
+                    char_type separator = char_type('.'),
+                    Translator tr = Translator());
+
+        // Default copying doesn't do the right thing with the iterator
+        string_path(const string_path &o);
+        string_path& operator =(const string_path &o);
+
+        /// Take a single element off the path at the front and return it.
+        key_type reduce();
+
+        /// Test if the path is empty.
+        bool empty() const;
+
+        /// Test if the path contains a single element, i.e. no separators.
+        bool single() const;
+
+        std::string dump() const {
+            return detail::dump_sequence(m_value);
+        }
+
+        /// Append a second path to this one.
+        /// @pre o's separator is the same as this one's, or o has no separators
+        string_path& operator /=(const string_path &o) {
+            // If it's single, there's no separator. This allows to do
+            // p /= "piece";
+            // even for non-default separators.
+            assert((m_separator == o.m_separator || o.empty() || o.single())
+                   && "Incompatible paths.");
+            if(!o.empty()) {
+                String sub;
+                if(!this->empty()) {
+                    sub.push_back(m_separator);
+                }
+                sub.insert(sub.end(), o.cstart(), o.m_value.end());
+                detail::append_and_preserve_iter(m_value, sub, m_start,
+                    typename std::iterator_traits<s_iter>::iterator_category());
+            }
+            return *this;
+        }
+
+    private:
+        typedef typename String::iterator s_iter;
+        typedef typename String::const_iterator s_c_iter;
+        String m_value;
+        char_type m_separator;
+        Translator m_tr;
+        s_iter m_start;
+        s_c_iter cstart() const { return m_start; }
+    };
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path()
+        : m_start(m_value.begin())
+    {}
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(const String &value,
+                                                 char_type separator,
+                                                 Translator tr)
+        : m_value(value), m_separator(separator),
+          m_tr(tr), m_start(m_value.begin())
+    {}
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(const char_type *value,
+                                                 char_type separator,
+                                                 Translator tr)
+        : m_value(value), m_separator(separator),
+          m_tr(tr), m_start(m_value.begin())
+    {}
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>::string_path(const string_path &o)
+        : m_value(o.m_value), m_separator(o.m_separator),
+          m_tr(o.m_tr), m_start(m_value.begin())
+    {
+        std::advance(m_start, std::distance(o.m_value.begin(), o.cstart()));
+    }
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator>&
+    string_path<String, Translator>::operator =(const string_path &o)
+    {
+        m_value = o.m_value;
+        m_separator = o.m_separator;
+        m_tr = o.m_tr;
+        m_start = m_value.begin();
+        std::advance(m_start, std::distance(o.m_value.begin(), o.cstart()));
+        return *this;
+    }
+
+    template <typename String, typename Translator>
+    typename Translator::external_type string_path<String, Translator>::reduce()
+    {
+        assert(!empty() && "Reducing empty path");
+
+        s_iter next_sep = std::find(m_start, m_value.end(), m_separator);
+        String part(m_start, next_sep);
+        m_start = next_sep;
+        if(!empty()) {
+          // Unless we're at the end, skip the separator we found.
+          ++m_start;
+        }
+
+        if(optional<key_type> key = m_tr.get_value(part)) {
+            return *key;
+        }
+        BOOST_PROPERTY_TREE_THROW(ptree_bad_path("Path syntax error", *this));
+    }
+
+    template <typename String, typename Translator> inline
+    bool string_path<String, Translator>::empty() const
+    {
+        return m_start == m_value.end();
+    }
+
+    template <typename String, typename Translator> inline
+    bool string_path<String, Translator>::single() const
+    {
+        return std::find(static_cast<s_c_iter>(m_start),
+                         m_value.end(), m_separator)
+            == m_value.end();
+    }
+
+    // By default, this is the path for strings. You can override this by
+    // specializing path_of for a more specific form of std::basic_string.
+    template <typename Ch, typename Traits, typename Alloc>
+    struct path_of< std::basic_string<Ch, Traits, Alloc> >
+    {
+        typedef std::basic_string<Ch, Traits, Alloc> _string;
+        typedef string_path< _string, id_translator<_string> > type;
+    };
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator> operator /(
+                                  string_path<String, Translator> p1,
+                                  const string_path<String, Translator> &p2)
+    {
+        p1 /= p2;
+        return p1;
+    }
+
+    // These shouldn't be necessary, but GCC won't find the one above.
+    template <typename String, typename Translator> inline
+    string_path<String, Translator> operator /(
+                                  string_path<String, Translator> p1,
+                                  const typename String::value_type *p2)
+    {
+        p1 /= p2;
+        return p1;
+    }
+
+    template <typename String, typename Translator> inline
+    string_path<String, Translator> operator /(
+                                  const typename String::value_type *p1,
+                                  const string_path<String, Translator> &p2)
+    {
+        string_path<String, Translator> t(p1);
+        t /= p2;
+        return t;
+    }
+
+}}
+
+#endif