Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53095 - in branches/sredl_2009_05_proptree_update: boost/property_tree boost/property_tree/detail libs/property_tree
From: sebastian.redl_at_[hidden]
Date: 2009-05-18 14:29:01


Author: cornedbee
Date: 2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
New Revision: 53095
URL: http://svn.boost.org/trac/boost/changeset/53095

Log:
Start implementation using multiindex. Everything's totally broken right now.
Text files modified:
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp | 689 ++++++++++-----------
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp | 1226 +++++++++------------------------------
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp | 86 +
   branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt | 28
   4 files changed, 707 insertions(+), 1322 deletions(-)

Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp (original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp 2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -1,8 +1,8 @@
 // ----------------------------------------------------------------------------
 // Copyright (C) 2002-2006 Marcin Kalicinski
 //
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 // For more information, see www.boost.org
@@ -10,494 +10,459 @@
 #ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
 #define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
 
-//////////////////////////////////////////////////////////////////////////////
-// Debug macros
-
-#ifdef BOOST_PROPERTY_TREE_DEBUG
-
- // Increment instances counter
- #define BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT() \
- { \
- typedef boost::detail::lightweight_mutex::scoped_lock lock; \
- lock l(debug_mutex); \
- ++debug_instances_count; \
- }
-
- // Decrement instances counter
- #define BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT() \
- { \
- typedef boost::detail::lightweight_mutex::scoped_lock lock; \
- lock l(debug_mutex); \
- BOOST_ASSERT(debug_instances_count > 0); \
- --debug_instances_count; \
- }
-
-#else // BOOST_PROPERTY_TREE_DEBUG
-
- #define BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT() static_cast<void>(0)
- #define BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT() static_cast<void>(0)
-
-#endif // BOOST_PROPERTY_TREE_DEBUG
-
 namespace boost { namespace property_tree
 {
 
- ///////////////////////////////////////////////////////////////////////////
- // Construction & destruction
+ // Big four
 
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X>::basic_ptree(allocator_type)
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A>::basic_ptree(allocator_type)
     {
         // FIXME: use allocator
- BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X>::basic_ptree(const data_type &rhs,
- allocator_type alloc)
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A>::basic_ptree(const data_type &data,
+ allocator_type)
         : m_data(rhs)
     {
         // FIXME: use allocator
- BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X>::basic_ptree(const basic_ptree<D, K, C, A, P, X> &rhs)
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A>::basic_ptree(const basic_ptree<K, D, C, A> &rhs)
     {
         m_data = rhs.m_data;
         insert(end(), rhs.begin(), rhs.end());
- BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X>::~basic_ptree()
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::operator =(const basic_ptree<K, D, C, A> &rhs)
     {
- BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT();
+ if (&rhs != this)
+ {
+ clear();
+ data() = rhs.data();
+ insert(end(), rhs.begin(), rhs.end());
+ }
+ return *this;
     }
 
- ///////////////////////////////////////////////////////////////////////////
- // Iterator access
+ template<class K, class D, class C, class A>
+ void basic_ptree<K, D, C, A>::swap(basic_ptree<K, D, C, A> &rhs)
+ {
+ m_data.swap(rhs.m_data);
+ m_children.swap(rhs.m_children);
+ }
+
+ // Container view
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::begin()
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::size_type
+ basic_ptree<K, D, C, A>::size() const
     {
- return m_container.begin();
+ return m_children.size();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::const_iterator
- basic_ptree<D, K, C, A, P, X>::begin() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::size_type
+ basic_ptree<K, D, C, A>::max_size() const
     {
- return m_container.begin();
+ return m_children.max_size();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::end()
+ template<class K, class D, class C, class A>
+ bool basic_ptree<K, D, C, A>::empty() const
     {
- return m_container.end();
+ return m_children.empty();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::const_iterator
- basic_ptree<D, K, C, A, P, X>::end() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::begin()
     {
- return m_container.end();
+ return m_children.begin();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::reverse_iterator
- basic_ptree<D, K, C, A, P, X>::rbegin()
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_iterator
+ basic_ptree<K, D, C, A>::begin() const
     {
- return m_container.rbegin();
+ return m_children.begin();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::const_reverse_iterator
- basic_ptree<D, K, C, A, P, X>::rbegin() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::end()
     {
- return m_container.rbegin();
+ return m_children.end();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::reverse_iterator
- basic_ptree<D, K, C, A, P, X>::rend()
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_iterator
+ basic_ptree<K, D, C, A>::end() const
     {
- return m_container.rend();
+ return m_children.end();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::const_reverse_iterator
- basic_ptree<D, K, C, A, P, X>::rend() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::reverse_iterator
+ basic_ptree<K, D, C, A>::rbegin()
     {
- return m_container.rend();
+ return m_children.rbegin();
     }
 
- ///////////////////////////////////////////////////////////////////////////
- // Data access
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_reverse_iterator
+ basic_ptree<K, D, C, A>::rbegin() const
+ {
+ return m_children.rbegin();
+ }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::size_type
- basic_ptree<D, K, C, A, P, X>::size() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::reverse_iterator
+ basic_ptree<K, D, C, A>::rend()
     {
- return m_container.size();
+ return m_children.rend();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::size_type
- basic_ptree<D, K, C, A, P, X>::max_size() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_reverse_iterator
+ basic_ptree<K, D, C, A>::rend() const
     {
- return m_container.max_size();
+ return m_children.rend();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- bool basic_ptree<D, K, C, A, P, X>::empty() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::value_type &
+ basic_ptree<K, D, C, A>::front()
     {
- return m_container.empty();
+ return m_children.front();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::data_type &
- basic_ptree<D, K, C, A, P, X>::data()
+ template<class K, class D, class C, class A>
+ const typename basic_ptree<K, D, C, A>::value_type &
+ basic_ptree<K, D, C, A>::front() const
     {
- return m_data;
+ return m_children.front();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- const typename basic_ptree<D, K, C, A, P, X>::data_type &
- basic_ptree<D, K, C, A, P, X>::data() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::value_type &
+ basic_ptree<K, D, C, A>::back()
     {
- return m_data;
+ return m_children.back();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::value_type &
- basic_ptree<D, K, C, A, P, X>::front()
+ template<class K, class D, class C, class A>
+ const typename basic_ptree<K, D, C, A>::value_type &
+ basic_ptree<K, D, C, A>::back() const
     {
- return m_container.front();
+ return m_children.back();
     }
-
- template<class D, class K, class C, class A, class P, class X>
- const typename basic_ptree<D, K, C, A, P, X>::value_type &
- basic_ptree<D, K, C, A, P, X>::front() const
+
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::insert(iterator where, const value_type &value)
     {
- return m_container.front();
+ return m_children.insert(where, value).first;
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::value_type &
- basic_ptree<D, K, C, A, P, X>::back()
+ template<class K, class D, class C, class A>
+ template<class It>
+ void basic_ptree<K, D, C, A>::insert(iterator where, It first, It last)
     {
- return m_container.back();
+ m_children.insert(where, first, last);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- const typename basic_ptree<D, K, C, A, P, X>::value_type &
- basic_ptree<D, K, C, A, P, X>::back() const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::erase(iterator where)
     {
- return m_container.back();
+ return m_children.erase(where);
     }
 
- ///////////////////////////////////////////////////////////////////////////
- // Operators
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::erase(iterator first, iterator last)
+ {
+ return m_children.erase(first, last);
+ }
 
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::operator =(const basic_ptree<D, K, C, A, P, X> &rhs)
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::push_front(const value_type &value)
     {
- if (&rhs != this)
- {
- clear();
- data() = rhs.data();
- insert(end(), rhs.begin(), rhs.end());
- }
- return *this;
+ return m_children.push_front(value).first;
     }
 
- template<class D, class K, class C, class A, class P, class X>
- bool basic_ptree<D, K, C, A, P, X>::operator ==(const basic_ptree<D, K, C, A, P, X> &rhs) const
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::push_back(const value_type &value)
     {
-
- // Data and sizes must be equal
- if (size() != rhs.size() || data() != rhs.data())
- return false;
-
- // Keys and children must be equal
- C comp;
- const_iterator it = begin();
- const_iterator it_rhs = rhs.begin();
- const_iterator it_end = end();
- for (; it != it_end; ++it, ++it_rhs)
- if (comp(it->first, it_rhs->first)
- || comp(it_rhs->first, it->first)
- || it->second != it_rhs->second)
- {
- return false;
- }
-
- // Equal
- return true;
+ return m_children.push_back(value).first;
+ }
 
+ template<class K, class D, class C, class A>
+ void basic_ptree<K, D, C, A>::pop_front()
+ {
+ m_children.pop_front();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- bool basic_ptree<D, K, C, A, P, X>::operator !=(const basic_ptree<D, K, C, A, P, X> &rhs) const
+ template<class K, class D, class C, class A>
+ void basic_ptree<K, D, C, A>::pop_back()
     {
- return !operator ==(rhs);
+ m_children.pop_back();
     }
 
- ///////////////////////////////////////////////////////////////////////////
- // Container operations
+ template<class K, class D, class C, class A>
+ void basic_ptree<K, D, C, A>::reverse()
+ {
+ m_children.reverse();
+ }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::find(const key_type &key)
+ template<class K, class D, class C, class A>
+ void basic_ptree<K, D, C, A>::sort()
     {
- C comp;
- for (iterator it = begin(); it != end(); ++it)
- if (!comp(it->first, key) && !comp(key, it->first))
- return it;
- return end();
+ m_children.sort();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::const_iterator
- basic_ptree<D, K, C, A, P, X>::find(const key_type &key) const
+ template<class K, class D, class C, class A>
+ template<class Compare>
+ void basic_ptree<K, D, C, A>::sort(Compare comp)
     {
- C comp;
- for (const_iterator it = begin(); it != end(); ++it)
- if (!comp(it->first, key) && !comp(key, it->first))
- return it;
- return end();
+ m_children.sort(comp);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::size_type
- basic_ptree<D, K, C, A, P, X>::count(const key_type &key) const
+ // Equality
+
+ template<class K, class D, class C, class A>
+ bool basic_ptree<K, D, C, A>::operator ==(
+ const basic_ptree<K, D, C, A> &rhs) const
     {
- C comp;
- size_type count = 0;
- for (const_iterator it = begin(); it != end(); ++it)
- if (!comp(it->first, key) && !comp(key, it->first))
- ++count;
- return count;
+ // The size test is cheap, so add it as an optimization
+ return size() == rhs.size() && data() == rhs.data() &&
+ m_children == rhs.m_children;
     }
 
- template<class D, class K, class C, class A, class P, class X>
- void basic_ptree<D, K, C, A, P, X>::clear()
+ template<class K, class D, class C, class A>
+ bool basic_ptree<K, D, C, A>::operator !=(
+ const basic_ptree<K, D, C, A> &rhs) const
     {
- m_data = data_type();
- m_container.clear();
+ return !(*this == rhs);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::insert(iterator where,
- const value_type &value)
+ // Associative view
+
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::assoc_iterator not_found()
     {
- return m_container.insert(where, value);
+ return assoc().end();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- template<class It>
- void basic_ptree<D, K, C, A, P, X>::insert(iterator where, It first, It last)
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_assoc_iterator not_found() const
     {
- for (; first != last; ++first, ++where)
- where = insert(where, value_type(first->first, first->second));
+ return assoc().end();
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::erase(iterator where)
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::assoc_iterator
+ basic_ptree<K, D, C, A>::find(const key_type &key)
     {
- return m_container.erase(where);
+ return assoc().find(key);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::size_type
- basic_ptree<D, K, C, A, P, X>::erase(const key_type &key)
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_assoc_iterator
+ basic_ptree<K, D, C, A>::find(const key_type &key) const
     {
- C comp;
- size_type count = 0;
- iterator it = m_container.begin();
- while (it != m_container.end())
- {
- if (!comp(it->first, key) && !comp(key, it->first))
- {
- it = erase(it);
- ++count;
- }
- else
- ++it;
- }
- return count;
+ return assoc().find(key);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- template<class It>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::erase(It first, It last)
+ template<class K, class D, class C, class A>
+ std::pair<
+ typename basic_ptree<K, D, C, A>::assoc_iterator,
+ typename basic_ptree<K, D, C, A>::assoc_iterator
+ > basic_ptree<K, D, C, A>::equal_range(const key_type &key)
     {
- while (first != last)
- first = erase(first);
- return first;
+ return assoc().equal_range(key);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::push_front(const value_type &value)
+ template<class K, class D, class C, class A>
+ std::pair<
+ typename basic_ptree<K, D, C, A>::const_assoc_iterator,
+ typename basic_ptree<K, D, C, A>::const_assoc_iterator
+ > basic_ptree<K, D, C, A>::equal_range(const key_type &key) const
     {
- return insert(begin(), value);
+ return assoc().equal_range(key);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::iterator
- basic_ptree<D, K, C, A, P, X>::push_back(const value_type &value)
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::size_type
+ basic_ptree<K, D, C, A>::count(const key_type &key) const
     {
- return insert(end(), value);
+ return assoc().count(key);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- void basic_ptree<D, K, C, A, P, X>::pop_front()
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::size_type
+ basic_ptree<K, D, C, A>::erase(const key_type &key)
     {
- erase(begin());
+ return assoc().erase(key);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- void basic_ptree<D, K, C, A, P, X>::pop_back()
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::iterator
+ basic_ptree<K, D, C, A>::to_iterator(assoc_iterator ai)
     {
- iterator last = end();
- --last;
- erase(last);
+ return m_children.project<0>(ai);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- void basic_ptree<D, K, C, A, P, X>::swap(basic_ptree<D, K, C, A, P, X> &rhs)
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::const_iterator
+ basic_ptree<K, D, C, A>::to_iterator(const_assoc_iterator ai) const
     {
- m_data.swap(rhs.m_data);
- m_container.swap(rhs.m_container);
+ return m_children.project<0>(ai);
     }
 
- template<class D, class K, class C, class A, class P, class X>
- void basic_ptree<D, K, C, A, P, X>::reverse()
+ // Property tree view
+
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::data_type &
+ basic_ptree<K, D, C, A>::data()
     {
- m_container.reverse();
+ return m_data;
     }
-
- template<class D, class K, class C, class A, class P, class X>
- template<class SortTr>
- void basic_ptree<D, K, C, A, P, X>::sort(SortTr tr)
+
+ template<class K, class D, class C, class A>
+ const typename basic_ptree<K, D, C, A>::data_type &
+ basic_ptree<K, D, C, A>::data() const
     {
- m_container.sort(tr);
+ return m_data;
     }
 
- ///////////////////////////////////////////////////////////////////////////
- // ptree operations
+ template<class K, class D, class C, class A>
+ void basic_ptree<K, D, C, A>::clear()
+ {
+ m_data = data_type();
+ m_children.clear();
+ }
 
- // Get child ptree
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path)
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::get_child(const path_type &path)
     {
- self_type *child = path.get_child(*this);
- if (child)
- return *child;
- else
- BOOST_PROPERTY_TREE_THROW(ptree_bad_path("path does not exist", path));
+ path_type p(path);
+ self_type *n = walk_path(p);
+ if (!n) {
+ BOOST_PROPERTY_TREE_THROW(ptree_bad_path(path));
+ }
+ return *n;
     }
 
     // Get child ptree
- template<class D, class K, class C, class A, class P, class X>
- const basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path) const
+ template<class K, class D, class C, class A>
+ const basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::get_child(const path_type &path) const
     {
- self_type *nc_this = const_cast<self_type *>(this);
- return nc_this->get_child(path);
+ return const_cast<self_type*>(this)->get_child(path);
     }
 
     // Get child ptree
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path,
- basic_ptree<D, K, C, A, P, X> &default_value)
- {
- self_type *child = path.get_child(*this);
- if (child)
- return *child;
- else
- return default_value;
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::get_child(const path_type &path,
+ self_type &default_value)
+ {
+ path_type p(path);
+ self_type *n = walk_path(p);
+ return n ? *n : default_value;
     }
 
     // Get child ptree
- template<class D, class K, class C, class A, class P, class X>
- const basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::get_child(const path_type &path,
- const basic_ptree<D, K, C, A, P, X> &default_value) const
- {
- self_type *nc_this = const_cast<self_type *>(this);
- self_type &nc_default_value = const_cast<self_type &>(default_value);
- return nc_this->get_child(path, nc_default_value);
+ template<class K, class D, class C, class A>
+ const basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::get_child(const path_type &path,
+ const self_type &default_value) const
+ {
+ return const_cast<self_type*>(this)->get_child(path,
+ onst_cast<self_type&>(default_value));
     }
 
 
     // Get child ptree
- template<class D, class K, class C, class A, class P, class X>
- optional<basic_ptree<D, K, C, A, P, X> &>
- basic_ptree<D, K, C, A, P, X>::get_child_optional(const path_type &path)
- {
- self_type *child = path.get_child(*this);
- if (child)
- return optional<self_type &>(*child);
- else
- return optional<self_type &>();
+ template<class K, class D, class C, class A>
+ optional<basic_ptree<K, D, C, A> &>
+ basic_ptree<K, D, C, A>::get_child_optional(const path_type &path)
+ {
+ path_type p(path);
+ self_type *n = walk_path(p);
+ if (!n) {
+ return optional<self_type&>();
+ }
+ return *n;
     }
 
     // Get child ptree
- template<class D, class K, class C, class A, class P, class X>
- optional<const basic_ptree<D, K, C, A, P, X> &>
- basic_ptree<D, K, C, A, P, X>::get_child_optional(const path_type &path) const
- {
- self_type *nc_this = const_cast<self_type *>(this);
- optional<self_type &> tmp = nc_this->get_child_optional(path);
- if (tmp)
- return optional<const self_type &>(tmp.get());
- else
- return optional<const self_type &>();
+ template<class K, class D, class C, class A>
+ optional<const basic_ptree<K, D, C, A> &>
+ basic_ptree<K, D, C, A>::get_child_optional(const path_type &path) const
+ {
+ path_type p(path);
+ self_type *n = walk_path(p);
+ if (!n) {
+ return optional<const self_type&>();
+ }
+ return *n;
     }
 
     // Put child ptree
- template<class D, class K, class C, class A, class P, class X>
- basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::put_child(const path_type &path,
- const basic_ptree<D, K, C, A, P, X> &value,
- bool do_not_replace)
- {
- self_type *child = path.put_child(*this, value, do_not_replace);
- if (child)
- return *child;
- else
- BOOST_PROPERTY_TREE_THROW(ptree_bad_path("path does not exist", path));
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::put_child(const path_type &path,
+ const self_type &value)
+ {
+ path_type p(path);
+ self_type &parent = force_path(p);
+ // Got the parent. Now get the correct child.
+ std::pair<key_type, std::size_t> fragment = p.reduce();
+ std::pair<assoc_iterator, assoc_iterator> range =
+ parent.equal_range(fragment.first);
+ std::size_t n = fragment.second;
+ // If the path specifies an index, walk the range.
+ while(n > 0 && range.first != range.second) {
+ --n;
+ ++range.first;
+ }
+ // If there's still something of the index left, add default-constructed
+ // elements.
+ while(n > 0) {
+ parent->push_back(self_type());
+ }
+ // We've finally reached the position for the new child
+ parent->push_back(value);
     }
 
     // Get value from data of ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class Type>
- Type basic_ptree<D, K, C, A, P, X>::get_value(const translator_type &x) const
+ Type basic_ptree<K, D, C, A>::get_value(const translator_type &x) const
     {
         BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false); // Disallow pointer types, they are unsafe
         Type value;
         if (x.get_value(*this, value))
             return value;
         else
- BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of data into type \"") +
+ BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of data into type \"") +
                                            typeid(Type).name() + "\" failed", data()));
     }
 
     // Get value from data of ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class Type>
- Type basic_ptree<D, K, C, A, P, X>::get_value(const Type &default_value,
+ Type basic_ptree<K, D, C, A>::get_value(const Type &default_value,
                                                const translator_type &x) const
     {
         BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false); // Disallow pointer types, they are unsafe
@@ -509,20 +474,20 @@
     }
 
     // Get value from data of ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class CharType>
- std::basic_string<CharType>
- basic_ptree<D, K, C, A, P, X>::get_value(const CharType *default_value,
+ std::basic_string<CharType>
+ basic_ptree<K, D, C, A>::get_value(const CharType *default_value,
                                               const translator_type &x) const
     {
         return get_value(std::basic_string<CharType>(default_value), x);
     }
 
     // Get value from data of ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class Type>
- optional<Type>
- basic_ptree<D, K, C, A, P, X>::get_value_optional(const translator_type &x) const
+ optional<Type>
+ basic_ptree<K, D, C, A>::get_value_optional(const translator_type &x) const
     {
         BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false); // Disallow pointer types, they are unsafe
         Type value;
@@ -533,19 +498,19 @@
     }
 
     // Get value from data of child ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class Type>
- Type basic_ptree<D, K, C, A, P, X>::get(const path_type &path,
+ Type basic_ptree<K, D, C, A>::get(const path_type &path,
                                          const translator_type &x) const
     {
         return get_child(path).get_value<Type>(x);
     }
 
     // Get value from data of child ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class Type>
- Type basic_ptree<D, K, C, A, P, X>::get(const path_type &path,
- const Type &default_value,
+ Type basic_ptree<K, D, C, A>::get(const path_type &path,
+ const Type &default_value,
                                          const translator_type &x) const
     {
         if (optional<Type> result = get_optional<Type>(path, x))
@@ -555,10 +520,10 @@
     }
 
     // Get value from data of child ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class CharType>
- std::basic_string<CharType>
- basic_ptree<D, K, C, A, P, X>::get(const path_type &path,
+ std::basic_string<CharType>
+ basic_ptree<K, D, C, A>::get(const path_type &path,
                                         const CharType *default_value,
                                         const translator_type &x) const
     {
@@ -566,33 +531,33 @@
     }
 
     // Get value from data of child ptree
- template<class D, class K, class C, class A, class P, class X>
+ template<class K, class D, class C, class A>
     template<class Type>
- optional<Type>
- basic_ptree<D, K, C, A, P, X>::get_optional(const path_type &path,
+ optional<Type>
+ basic_ptree<K, D, C, A>::get_optional(const path_type &path,
                                                  const translator_type &x) const
     {
- if (optional<const basic_ptree<D, K, C, A, P, X> &> child = get_child_optional(path))
+ if (optional<const basic_ptree<K, D, C, A> &> child = get_child_optional(path))
             return child.get().get_value_optional<Type>(x);
         else
             return optional<Type>();
     }
 
     // Put value in data of ptree
- template<class D, class K, class C, class A, class P, class X>
- template<class Type>
- void basic_ptree<D, K, C, A, P, X>::put_value(const Type &value, const translator_type &x)
+ template<class K, class D, class C, class A>
+ template<class Type>
+ void basic_ptree<K, D, C, A>::put_value(const Type &value, const translator_type &x)
     {
         if (!x.put_value(*this, value))
- BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of type \"") + typeid(Type).name() +
+ BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of type \"") + typeid(Type).name() +
                                                        "\" into data failed", boost::any()));
     }
 
     // Put value in data of child ptree
- template<class D, class K, class C, class A, class P, class X>
- template<class Type>
- basic_ptree<D, K, C, A, P, X> &
- basic_ptree<D, K, C, A, P, X>::put(const path_type &path,
+ template<class K, class D, class C, class A>
+ template<class Type>
+ basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::put(const path_type &path,
                                         const Type &value,
                                         bool do_not_replace,
                                         const translator_type &x)
@@ -616,36 +581,36 @@
 
 #ifdef BOOST_PROPERTY_TREE_DEBUG
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::size_type
- basic_ptree<D, K, C, A, P, X>::debug_get_instances_count()
- {
- empty_ptree<basic_ptree<D, K, C, A, P, X> >(); // Make sure empty ptree exists
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::size_type
+ basic_ptree<K, D, C, A>::debug_get_instances_count()
+ {
+ empty_ptree<basic_ptree<K, D, C, A> >(); // Make sure empty ptree exists
         return debug_instances_count - 1; // Do not count empty ptree
     }
 
- template<class D, class K, class C, class A, class P, class X>
- typename basic_ptree<D, K, C, A, P, X>::size_type
- basic_ptree<D, K, C, A, P, X>::debug_instances_count;
-
- template<class D, class K, class C, class A, class P, class X>
- boost::detail::lightweight_mutex
- basic_ptree<D, K, C, A, P, X>::debug_mutex;
+ template<class K, class D, class C, class A>
+ typename basic_ptree<K, D, C, A>::size_type
+ basic_ptree<K, D, C, A>::debug_instances_count;
+
+ template<class K, class D, class C, class A>
+ boost::detail::lightweight_mutex
+ basic_ptree<K, D, C, A>::debug_mutex;
 
 #endif
 
     ///////////////////////////////////////////////////////////////////////////
     // Free functions
 
- template<class Ptree>
+ template<class Ptree>
     inline const Ptree &empty_ptree()
     {
         static Ptree pt;
         return pt;
     }
 
- template<class D, class K, class C, class A, class P, class X>
- inline void swap(basic_ptree<D, K, C, A, P, X> &pt1, basic_ptree<D, K, C, A, P, X> &pt2)
+ template<class K, class D, class C, class A>
+ inline void swap(basic_ptree<K, D, C, A> &pt1, basic_ptree<K, D, C, A> &pt2)
     {
         pt1.swap(pt2);
     }

Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp (original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp 2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -14,32 +14,17 @@
 #ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
 #define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
 
-// Must be the first include, because of config.hpp
 #include <boost/property_tree/ptree_fwd.hpp>
 #include <boost/property_tree/detail/ptree_utils.hpp>
-#include <boost/assert.hpp>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/member.hpp>
+
 #include <boost/optional.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/remove_pointer.hpp>
-#include <boost/any.hpp>
-#include <boost/throw_exception.hpp>
-
-#ifdef BOOST_PROPERTY_TREE_DEBUG
-// For syncing debug instances counter
-# include <boost/detail/lightweight_mutex.hpp>
-#endif
 
-#include <functional> // for std::less
-#include <limits>
-#include <list>
-#include <sstream>
-#include <stdexcept>
 #include <utility> // for std::pair
-#include <vector>
-#include <cstdlib>
 
 #if !defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
     // Throwing macro to avoid no return warnings portably
@@ -50,22 +35,21 @@
 {
 
     /**
- * Class template implementing property tree.
+ * Property tree main structure. A property tree is a hierarchical data
+ * structure which has one element of type @p Data in each node, as well
+ * as an ordered sequence of sub-nodes, which are additionally identified
+ * by a non-unique key of type @p Key.
+ *
+ * Key equivalency is defined by @p KeyCompare, a predicate defining a
+ * strict weak ordering.
      *
- * A property tree can have data associated with it along with a
- * sequence of @c (key,basic_ptree) children.
- * Iterators provide bidirectional iterative access into child sequence.
+ * All data structures are allocated with some version of @p Allocator.
      *
- * @tparam Key Key type
- * @tparam Data Data type
- * @tparam KeyCompare Key comparison predicate
- * @tparam Allocator Allocator used throughout the class. Should be an
- * allocator for Data; will be rebound anyway
- * @tparam Path Path type
- * @tparam Translate Utility that converts between key and std::string
+ * Property tree defines a Container-like interface to the (key-node) pairs
+ * of its direct sub-nodes. The iterators are bidirectional. The sequence
+ * of nodes is held in insertion order, not key order.
      */
- template<class Key, class Data, class KeyCompare, class Allocator,
- class Path, class Translate>
+ template<class Key, class Data, class KeyCompare, class Allocator>
     class basic_ptree
     {
 #if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
@@ -73,997 +57,379 @@
 #endif
         // Internal types
         /**
- * Simpler way to refer to this basic_ptree<C,K,P,D,X> type.
+ * Simpler way to refer to this basic_ptree\<C,K,P,A\> type.
          * Note that this is private, and made public only for doxygen.
          */
- typedef basic_ptree<Key, Data, KeyCompare, Allocator, Path, Translate>
- self_type;
+ typedef basic_ptree<Key, Data, KeyCompare, Allocator> self_type;
 
     public:
         // Basic types
- typedef Key key_type;
- typedef Data data_type;
- typedef KeyCompare key_compare;
- typedef Allocator allocator_type;
- typedef Path path_type;
- typedef Translate translator_type;
-
- /**
- * Property tree stores a sequence of values of this type.
- *
- * The first element is the key and the second is the child property
- * tree stored at this key.
- */
- typedef std::pair<key_type, self_type> value_type;
-
- typedef typename allocator_type::template rebind<value_type>::other
- value_allocator_type;
+ typedef Key key_type;
+ typedef Data data_type;
+ typedef KeyCompare key_compare;
+ typedef Allocator allocator_type;
+
+ // Container view types
+ typedef std::pair<Key, self_type> value_type;
+ typedef typename Allocator::size_type size_type;
 
     private:
- // Internal types
- typedef std::list<value_type, value_allocator_type> container_type;
+ struct by_name {};
+ // The actual child container.
+ typedef multi_index_container<value_type,
+ indexed_by<
+ multi_index::sequenced<>,
+ multi_index::ordered_non_unique<multi_index::tag<by_name>,
+ multi_index::member<value_type, key_type,
+ &value_type::first>,
+ key_compare
+ >
+ >
+ > base_container;
+ // The by-name lookup index.
+ typedef typename base_container::template index<by_name>::type
+ by_name_index;
+
+ public:
+ // More container view types
+ typedef typename base_container::iterator iterator;
+ typedef typename base_container::const_iterator const_iterator;
+ typedef typename base_container::reverse_iterator reverse_iterator;
+ typedef typename base_container::const_reverse_iterator
+ const_reverse_iterator;
+
+ // Associative view types
+ typedef typename by_name_index::iterator assoc_iterator;
+ typedef typename by_name_index::const_iterator const_assoc_iterator;
 
- public:
- // Container-related types
- typedef typename container_type::size_type size_type;
- typedef typename container_type::iterator iterator;
- typedef typename container_type::const_iterator const_iterator;
- typedef typename container_type::reverse_iterator reverse_iterator;
- typedef typename container_type::const_reverse_iterator
- const_reverse_iterator;
+ // Property tree view types
+ typedef typename path_of<Key>::type path_type;
 
- public:
- ///////////////////////////////////////////////////////////////////////
- // Construction & destruction
 
- /** Creates an empty property tree. */
- explicit basic_ptree(allocator_type alloc = allocator_type());
+ // The big four
 
- /**
- * Creates a property_tree with the given data.
- * @param data Data to be assigned to the tree's data field.
- */
+ /** Creates a node with no children and default-constructed data. */
+ explicit basic_ptree(allocator_type alloc = allocator_type());
+ /** Creates a node with no children and a copy of the given data. */
         explicit basic_ptree(const data_type &data,
                              allocator_type alloc = allocator_type());
-
- /**
- * Copy constructor from another property_tree.
- * @param rhs The property tree to be copied.
- */
         basic_ptree(const self_type &rhs);
+ /** Basic guarantee only. */
+ self_type &operator =(const self_type &rhs);
 
- /** Destroy the property tree, including all children.
+ /** Swap with other tree. Only constant-time and nothrow if the
+ * data type's swap is.
          */
- ~basic_ptree();
+ void swap(self_type &rhs);
 
- ///////////////////////////////////////////////////////////////////////
- // Iterator access
+ // Container view functions
 
- /**
- * Access to the start of the direct children sequence.
- * @return iterator pointing to the first element of the direct
- * children sequence.
- */
- iterator begin();
+ /** The number of direct children of this node. */
+ size_type size() const;
+ size_type max_size() const;
+ /** Whether there are any direct children. */
+ bool empty() const;
 
- /**
- * Const access to the start of the direct children sequence.
- * @return const_iterator pointing to the first element of the direct
- * children sequence.
- */
+ iterator begin();
         const_iterator begin() const;
-
- /**
- * Access to the end of the direct children sequence.
- * @return iterator pointing just past the end of the direct
- * children sequence.
- */
         iterator end();
-
- /**
- * Const access to the end of the direct children sequence.
- * @return const_iterator pointing just past the end of the direct
- * children sequence.
- */
         const_iterator end() const;
-
- /**
- * Access to the start of the reversed direct children sequence.
- * @return reverse_iterator pointing to first element of the reversed
- * direct children sequence.
- */
         reverse_iterator rbegin();
-
- /**
- * Const access to the start of the reversed direct children sequence.
- * @return const_reverse_iterator pointing to first element of the
- * reversed direct children sequence.
- */
         const_reverse_iterator rbegin() const;
-
- /**
- * Access to the end of the reverse direct children sequence.
- * @return reverse_iterator pointing just past the end of the reversed
- * direct children sequence.
- */
         reverse_iterator rend();
-
- /**
- * Const access to the end of the reverse direct children sequence.
- * @return const_reverse_iterator pointing just past the end of the
- * reversed direct children sequence.
- */
         const_reverse_iterator rend() const;
 
- ///////////////////////////////////////////////////////////////////////////
- // Data access
-
- /**
- * The size of the direct children sequnce.
- * @return Number of direct children of the property tree.
- */
- size_type size() const;
-
- size_type max_size() const;
-
- /**
- * Determine whether the children sequence is empty.
- * @note empty() should be prefered over <tt>size() == 0</tt>
- * @retval true There are no direct children.
- * @retval false There is at least one direct child.
- */
- bool empty() const;
-
- /**
- * Returns a reference to the data of a property tree.
- * @return Reference to the stored data which can be used to
- * modify the data.
- */
- data_type &data();
-
- /**
- * Returns a const reference to the data of a property tree.
- * @return Const reference to the stored data.
- */
- const data_type &data() const;
-
- /**
- * Returns a reference to the first element in the direct
- * children sequence.
- * @pre !(this->empty())
- * @return Reference to the first element in the direct
- * children sequence.
- */
         value_type &front();
-
- /**
- * Returns a const reference to the first element in the direct
- * children sequence.
- * @pre !(this->empty())
- * @return Const reference to the first element in the direct
- * children sequence.
- */
         const value_type &front() const;
-
- /**
- * Returns a reference to the last element in the direct
- * children sequence.
- * @pre !(this->empty())
- * @return Reference to the last element in the direct
- * children sequence.
- */
         value_type &back();
-
- /**
- * Returns a const reference to the last element in the direct
- * children sequence.
- * @pre !(this->empty())
- * @return Const reference to the last element in the direct
- * children sequence.
- */
         const value_type &back() const;
 
- ///////////////////////////////////////////////////////////////////////////
- // Operators
-
- /**
- * Replaces current contents of this property tree with another's
- * contents.
- * @param rhs The property tree to assign to this property tree.
- */
- self_type &operator =(const self_type &rhs);
-
- /**
- * Check for equality of property trees.
- * @retval true If both property trees contain the same data values
- * and equivalent children sequences, recursively.
- * @retval false Otherwise.
- */
- bool operator ==(const self_type &rhs) const;
-
- /**
- * Check for inequality of property trees.
- * @return !(*this == rhs)
- */
- bool operator !=(const self_type &rhs) const;
-
- ///////////////////////////////////////////////////////////////////////
- // Container operations
-
- /**
- * Finds direct child stored at specified key.
- *
- * If there is more than one child with the same key, the first one is
- * returned. Time complexity is <tt>O(log n)</tt>. Keys equivalence is
- * tested with a predicate supplied as basic_ptree template parameter.
- * If childe is not found, returns end(). Both const and non-const
- * versions are provided. To find non-direct children use get_child
- * function.
- *
- * @param key The key to search in the direct children sequence.
- * @return iterator pointing to the found sequence element, or end()
- * if no such element exists.
- */
- iterator find(const key_type &key);
-
- /**
- * Finds direct child stored at specified key.
- *
- * If there is more than one child with the same key, the first one is
- * returned. Time complexity is <tt>O(log n)</tt>. Keys equivalence is
- * tested with a predicate supplied as basic_ptree template parameter.
- * If child is not found, returns end(). Both const and non-const
- * versions are provided. To find non-direct children use get_child
- * function.
- *
- * @param key The key to search in the direct children sequence.
- * @return const_iterator pointing to the found sequence element,
- * or end() if no such element exists.
- */
- const_iterator find(const key_type &key) const;
-
- /**
- * Count the number of direct children with the given key.
- *
- * Keys equivalence is tested with a predicate supplied as basic_ptree
- * template parameter.
- * @param key Key to count.
- * @return Number of direct children with given key.
- */
- size_type count(const key_type &key) const;
-
- /**
- * Recursively deletes all children of the property tree and clears the
- * data from the property tree.
- */
- void clear();
-
- /**
- * Inserts a new direct child into the property tree.
- *
- * @param where Iterator pointing at the position where new element will
- * be inserted. Passing begin() will insert at the front of
- * the list. Passing end() will insert at the back. Any
- * other valid iterator will insert in the appropriate
- * place in the middle.
- * @param value value to be inserted.
- * @return iterator pointing to newly inserted element of the sequence.
+ /** Insert a copy of the given tree with its key just before the given
+ * position in this node. This operation invalidates no iterators.
+ * @return An iterator to the newly created child.
          */
         iterator insert(iterator where, const value_type &value);
 
- /**
- * Inserts a range of direct children into the property tree.
- *
- * Time complexity is <tt>O(m log n)</tt>, where @c m is number of
- * inserted children, @c n is number of existing children.
- *
- * @param where Iterator pointing at the position where new elements
- * will be inserted. Passing begin() will insert at the
- * front of the list. Passing end() will insert at the
- * back. Any other valid iterator will insert in the
- * appropriate place in the middle.
- * @param first Iterator designating the first element of range to be
- * inserted.
- * @param last Iterator referring to just past the end of the range to
- * be inserted.
+ /** Range insert. Equivalent to:
+ * @code
+ * for(; first != last; ++first) insert(where, *first);
+ * @endcode
          */
         template<class It> void insert(iterator where, It first, It last);
 
- /**
- * Erases a direct child from the property tree.
- *
- * @param where Iterator pointing at the child to be erased from the
- * property tree.
- * @return Iterator pointing to the element after the erased element of
- * the sequence, or end() if the element erased was the last in
- * the sequence.
+ /** Erase the child pointed at by the iterator. This operation
+ * invalidates the given iterator, as well as its equivalent
+ * assoc_iterator.
+ * @return A valid iterator pointing to the element after the erased.
          */
         iterator erase(iterator where);
 
- /**
- * Erases direct children from the property tree matching the given key.
- *
- * @param key Key designating child or children to erase.
- * @return Number of children that were erased.
+ /** Range erase. Equivalent to:
+ * @code
+ * while(first != last;) first = erase(first);
+ * @endcode
          */
- size_type erase(const key_type &key);
+ iterator erase(iterator first, iterator last);
 
- /**
- * Erases a range of direct children from the property tree.
- *
- * @param first Iterator designating the first element of range to be
- * erased.
- * @param last Iterator referring to just past the end of the range to
- * be erased.
- */
- template<class It> iterator erase(It first, It last);
-
- /**
- * Inserts a new direct child at the front of the sequence.
- *
- * Equivalent to insert(begin(), value).
- * @param value Value to be inserted.
- * @return Iterator pointing to newly inserted element of the sequence.
- */
+ /** Equivalent to insert(begin(), value). */
         iterator push_front(const value_type &value);
 
- /**
- * Inserts a new direct child at the back of the sequence.
- *
- * Equivalent to insert(end(), value)
- * @param value Value to be inserted.
- * @return Iterator pointing to newly inserted element of the sequence.
- */
+ /** Equivalent to insert(end(), value). */
         iterator push_back(const value_type &value);
 
- /**
- * Erases the first direct child in the sequence.
- *
- * Equivalent to erase(begin()).
- * @pre !(this->empty())
- */
+ /** Equivalent to erase(begin()). */
         void pop_front();
 
- /**
- * Erases the last direct child in the sequence.
- *
- * Equivalent to erase(boost::prior(end())).
- * @pre !(this->empty())
- */
+ /** Equivalent to erase(boost::prior(end())). */
         void pop_back();
 
- /**
- * Swaps contents of this property tree with the contents of another.
- *
- * Time complexity is <tt>O(1)</tt>.
- * @param rhs Property tree with which to swap.
- */
- void swap(self_type &rhs);
-
         /** Reverses the order of direct children in the property tree. */
         void reverse();
 
- /**
- * Sorts direct children of the property tree in ascending order.
- * @param tr The binary predicate used to sort child values of type
- * @c #value_type.
- * @post For each adjacent child of the sequence, @c v1 followed by
- * @c v2, @c tr(v1,v2) evaluates to true.
- */
- template<class SortTr> void sort(SortTr tr);
-
- ///////////////////////////////////////////////////////////////////////
- // ptree operations
-
- /**
- * Get a reference to the child property tree at the given path.
- *
- * Traverses the tree using the given path and retrieves a child
- * property tree stored there. This function will retrieve indirect
- * children if the path contains at least one separator.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @throw ptree_bad_path if child property tree cannot be located.
- * @return A reference to the child property tree at the given path
- * relative to this property tree.
- */
- self_type &get_child(const path_type &path);
-
- /**
- * Get a const reference to the child property tree at the given path.
- *
- * Traverses the tree using the given path and retrieves a child
- * property tree stored there. This function will retrieve indirect
- * children if the path contains at least one separator.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @throw ptree_bad_path if child property tree cannot be located.
- * @return A const reference to the child property tree at the given
- * path relative to this property tree.
+ /** Sorts the direct children of this node according to the predicate.
+ * The predicate is passed the whole pair of key and child.
          */
- const self_type &get_child(const path_type &path) const;
+ template<class Compare> void sort(Compare comp);
 
- /**
- * Get a reference to the child property tree at the given path or a
- * default if none found.
- *
- * Traverses the tree using the given path and retrieves a child
- * property tree stored there. This function will retrieve indirect
- * children if the path contains at least one separator. If child isn't
- * found then the @p default_value will be returned.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @param default_value The value to be returned if no child is found
- * at @c path.
- * @return A reference to the child property tree at the given path
- * relative to this property tree or the @c default_value if
- * that child isn't found
- */
- self_type &get_child(const path_type &path, self_type &default_value);
+ /** Sorts the direct children of this node according to key order. */
+ void sort();
 
- /**
- * Get a const reference to the child property tree at the given path
- * or a default if none found.
- *
- * Traverses the tree using the given path and retrieves a child
- * property tree stored there. This function will retrieve indirect
- * children if the path contains at least one separator. If child isn't
- * found then the @c default_value will be returned.
- * @note One use of default value is to return a reference to empty
- * property tree if the required one is not found. In many cases,
- * the subsequent code using the return value can be then made
- * simpler. @see boost::property_tree::empty_ptree.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @param default_value The value to be returned if no child is found
- * at @c path.
- * @return A const reference to the child property tree at the given
- * path relative to this property tree or the @c default_value
- * if that child isn't found.
- */
- const self_type &get_child(const path_type &path,
- const self_type &default_value) const;
-
- /**
- * Get a reference to the child property tree at the given path if
- * it exists.
- *
- * Traverses the tree using the given path and retrieves a child
- * property tree stored there. This function will retrieve indirect
- * children if the path contains at least one separator.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @return If the child is found, the function returns a boost::optional
- * initialized with a reference to it. Otherwise it returns
- * a null boost::optional.
- */
- optional<self_type &> get_child_optional(const path_type &path);
-
- /**
- * Get a const reference to the child property tree at the given path
- * if it exists.
- *
- * Traverses the tree using the given path and retrieves a child
- * property tree stored there. This function will retrieve indirect
- * children if the path contains at least one separator.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @return If the child is found, the function returns a boost::optional
- * initialized with a reference to it. Otherwise it returns
- * a null boost::optional.
- */
- optional<const self_type &>
- get_child_optional(const path_type &path) const;
-
- /**
- * Traverses the tree using given path, and inserts a new property tree
- * or replaces existing one. If any of the intermediate keys specified
- * by path does not exist, it is inserted, with empty data and no
- * children, at the back of existing sequence.
- *
- * For example, if @c path is "key1.key2.key3", the function will find
- * a child designated by "key1.key2" path. This child will be checked
- * for presence of "key3" subkey. If it exists, it will be replaced with
- * the one specified by value parameter. If it does not exist, "key3"
- * will be added at the back of existing sequence (if any). If either
- * "key1" or "key1.key2" do not exist, the function will insert them as
- * well.
- *
- * This function is a complement to @c #get_child.
- * If @c put_child(path,value) was called, @c get_child(path) will
- * return a reference to element inserted/replaced by put_child.
- *
- * @param path Location to place value. A sequence of keys with zero
- * or more separator characters.
- * @param value Property tree to be inserted as a child of this
- * property tree.
- * @param do_not_replace If set to true, causes function to always
- * insert a new key, even if there already exists
- * key with the same name.
- * @return Reference to the inserted property tree.
- */
- self_type &put_child(const path_type &path, const self_type &value,
- bool do_not_replace = false);
-
- /**
- * Extracts value stored in property tree data and translates it to
- * Type using the given translator.
- * @throw ptree_bad_data If data cannot be translated to an instance of
- * @c Type using the given translator_type.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c Type using
- * <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
- * @return The extracted value as an instance of @c Type.
- */
- template<class Type> Type get_value(
- const translator_type &x = translator_type()) const;
+ // Equality
 
- /**
- * Extracts value stored in property tree data and translates it to
- * Type using the given translator. If extraction does not succeed
- * then return the given default value.
- * @param default_value The value to be returned if the the given
- * translator cannot extract the data as an
- * instance of @c Type.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c Type using
- * <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
- * @return The extracted value as an instance of @c Type if extraction
- * succeeds. Otherwise it returns the @c default_value.
+ /** Two property trees are the same if they have the same data, the keys
+ * and order of their children are the same, and the children compare
+ * equal, recursively.
          */
- template<class Type> Type get_value(const Type &default_value,
- const translator_type &x = translator_type()) const;
-
- /**
- * Extracts value stored in property tree data and translates it to
- * @c std::basic_string<CharType> using the given translator. If
- * extraction does not succeed then return the given default string.
- * @param default_value The string to be returned if the the given
- * translator cannot extract the data as an
- * instance of @c Type.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c std::basic_string<CharType> using
- * <tt>bool translator_type::get_value(self_type const&,
- * std::basic_string<CharType>&)</tt>.
- * @return The extracted value as an instance of
- * @c std::basic_string<CharType> if extraction succeeds.
- * Otherwise it returns the @c default_value.
- */
- template<class CharType> std::basic_string<CharType> get_value(
- const CharType *default_value,
- const translator_type &x = translator_type()) const;
+ bool operator ==(const self_type &rhs) const;
+ bool operator !=(const self_type &rhs) const;
 
- /**
- * Extracts value stored in property tree data and translates it to
- * Type using the given translator.
- * @param default_value The value to be returned if the the given
- * translator cannot extract the data as an
- * instance of @c Type.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c Type using
- * <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
- * @return The extracted value as an instance of @c Type if extraction
- * succeeds. Otherwise it returns an empty
- * @c boost::optional\<Type\>.
- */
- template<class Type> optional<Type> get_value_optional(
- const translator_type &x = translator_type()) const;
+ // Associative view
 
- /**
- * Get the property tree value at the given path.
- *
- * Traverses the tree using the given path and retrieves the value
- * stored there. This function will retrieve values of indirect children
- * if the path contains at least one separator. The value will be
- * converted to an instance of @c Type using the given translator.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c Type using
- * <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
- * @throw ptree_bad_path if child property tree cannot be located using
- * the given path.
- * @return The child property tree's value at the given path relative
- * to this property tree.
+ /** Returns the not-found iterator. Equivalent to end() in a real
+ * associative container.
          */
- template<class Type> Type get(const path_type &path,
- const translator_type &x = translator_type()) const;
-
- /**
- * Get the property tree value at the given path or a default if none
- * found.
- *
- * Traverses the tree using the given path and retrieves the value
- * stored there This function will retrieve values of indirect children
- * if the path contains at least one separator. The value will be
- * converted to an instance of @c Type using the given translator. If
- * child isn't found then the @c default_value will be returned.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @param default_value The value to be returned if no child is found
- * at @c path or translation fails.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c Type using
- * <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
- * @return The child property tree's value at the given path relative to
- * this property tree or the @c default_value if that child is
- * not found.
- */
- template<class Type> Type get(const path_type &path,
- const Type &default_value,
- const translator_type &x =
- translator_type()) const;
-
- /**
- * Get the property tree value as @c std::basic_string<CharType> at the
- * given path or a default if none found.
- *
- * Traverses the tree using the given path and retrieves the value
- * stored there This function will retrieve values of indirect children
- * if the path contains at least one separator. The value will be
- * converted to an instance of @c std::basic_string<CharType> using the
- * given translator. If child isn't found then the @c default_value
- * will be returned.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @param default_value The string to be returned if no child is found
- * at @c path or translation fails.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c std::basic_string<CharType> using
- * <tt>bool translator_type::get_value(self_type const&,
- * std::basic_string<CharType>&)</tt>.
- * @return The child property tree's value as
- * @c std::basic_string<CharType> at the given path relative to
- * this property tree or the @c default_value if that child is
- * not found or translation fails.
- */
- template<class CharType> std::basic_string<CharType> get(
- const path_type &path,
- const CharType *default_value,
- const translator_type &x = translator_type()) const;
-
- /**
- * Get the property tree value at the given path or an uninitialized
- * @c boost::optional<Type> if none found.
- *
- * Traverses the tree using the given path and retrieves the value
- * stored there. This function will retrieve values of indirect children
- * if the path contains at least one separator. The value will be
- * converted to an instance of @c Type using the given translator. If
- * child isn't found then an unitialized @c boost::optional<Type>
- * will be returned.
- * @param path A sequence of keys with zero or more separator
- * characters. Can indicate indirect children if path
- * contains at least one separator character.
- * @param x Translator to use to extract and convert the contained
- * #data_type to @c Type using
- * <tt>bool translator_type::get_value(self_type const&, Type&)</tt>.
- * @return The child property tree's value at the given path relative to
- * this property tree or an unitialized @c boost::optional<Type>
- * if that child is not found or translation fails.
+ assoc_iterator not_found();
+ /** Returns the not-found iterator. Equivalent to end() in a real
+ * associative container.
          */
- template<class Type> optional<Type> get_optional(const path_type &path,
- const translator_type &x = translator_type()) const;
+ const_assoc_iterator not_found() const;
 
- /**
- * Store the given value as the data of this property tree.
- *
- * Translates @c value from @c Type to @c #data_type using the given
- * translator, and stores the result as the data value of this property
- * tree.
- * @throw ptree_bad_data If the given value cannot be translated to
- * @c #data_type.
- * @param value The parameter to store as the data of this property
- * tree.
- * @param x Translator to use to convert @c value to an instance of
- * @c #data_type using
- * <tt>bool translator_type::put_value(self_type&, Type const&)</tt>.
+ /** Find a child with the given key, or not_found() if there is none.
+ * There is no guarantee about which child is returned if multiple have
+ * the same key.
          */
- template<class Type> void put_value(const Type &value,
- const translator_type &x = translator_type());
+ assoc_iterator find(const key_type &key);
 
- /**
- * Traverses the tree using given path, and inserts a new value or
- * replaces existing one. If any of the intermediate keys specified by
- * path does not exist, it is inserted, with empty data and no children,
- * at the back of existing sequence.
- *
- * For example, if @c path is "key1.key2.key3", the function will find
- * a child designated by "key1.key2" path. This child will be checked
- * for presence of "key3" subkey. If it exists, it will be replaced with
- * the one specified by value parameter. If it does not exist, "key3"
- * will be added at the back of existing sequence (if any). If either
- * "key1" or "key1.key2" do not exist, the function will insert them as
- * well.
- *
- * This function is a complement to @c #get. If @c put(path,value) was
- * called, @c get(path) will return the value inserted by @c #put.
- *
- * @param path Location to place value. A sequence of keys with zero
- * or more separator characters.
- * @param value value to be inserted as the data of a child of this
- * property tree.
- * @param do_not_replace If set to true, causes function to always
- * insert a new key, even if there already exists
- * key with the same name.
- * @param x Translator to use to convert @c value to an instance of
- * @c #data_type using
- * <tt>bool translator_type::put_value(self_type&,Type const&)</tt>.
- * @return Reference to the property tree where the value was inserted.
- * It is either a newly inserted property tree or an existing
- * one if it was there prior to this call.
- */
- template<class Type> self_type &put(const path_type &path,
- const Type &value,
- bool do_not_replace = false,
- const translator_type &x =
- translator_type());
-
- private:
- data_type m_data;
- container_type m_container;
-
- ///////////////////////////////////////////////////////////////////////
- // Debugging
-
-#ifdef BOOST_PROPERTY_TREE_DEBUG
- private:
- // Mutex for syncing instances counter
- static boost::detail::lightweight_mutex debug_mutex;
- // Total number of instances of this ptree class
- static size_type debug_instances_count;
- public:
- static size_type debug_get_instances_count();
-#endif
-
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // basic_path class template
-
- /** Class template used to represent a path containing a sequence of Key
- * instances.
- */
- template<class Key>
- class basic_path
- {
-#if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
- public:
-#endif
- /**
- * Simpler way to refer to the Key::value_type type.
- * Do not use in client code; exposed only for documentation purposes.
+ /** Find a child with the given key, or not_found() if there is none.
+ * There is no guarantee about which child is returned if multiple have
+ * the same key.
          */
- typedef typename Key::value_type char_type;
+ const_assoc_iterator find(const key_type &key) const;
 
- public:
-
- ///////////////////////////////////////////////////////////////////////
- // Construction & destruction
+ /** Find the range of children that have the given key. */
+ std::pair<assoc_iterator, assoc_iterator>
+ equal_range(const key_type &key);
 
- /** Constructs an empty basic_path<Key> instance */
- basic_path();
-
- /**
- * Constructs an path using the given path using the given separator to
- * split it.
- * @param path The path to which to initialize the constructed instance.
- * @param separator The separator to use to split the @c path parameter.
- */
- basic_path(const Key &path, char_type separator = char_type('.'));
+ /** Find the range of children that have the given key. */
+ std::pair<const_assoc_iterator, const_assoc_iterator>
+ equal_range(const key_type &key) const;
 
- /**
- * Constructs an path using the given path using the given separator to
- * split it.
- * @param path The path to which to initialize the constructed instance.
- * This path instance must be terminated with
- * char_type('\\0');
- * @param separator The separator to use to split the @c path parameter.
- */
- basic_path(const char_type *path, char_type separator = char_type('.'));
+ /** Count the number of direct children with the given key. */
+ size_type count(const key_type &key) const;
 
- ///////////////////////////////////////////////////////////////////////
- // Path manipulation
+ /** Erase all direct children with the given key. */
+ void erase(const key_type &key);
 
- /**
- * Append the given path to this instance.
- * @param rhs The path to append.
- * @return A reference to this path instance after appending @c rhs.
+ /** Get the iterator that points to the same element as the argument.
+ * @note A valid assoc_iterator range (a, b) does not imply that
+ * (to_iterator(a), to_iterator(b)) is a valid range.
          */
- basic_path<Key> &operator /=(const basic_path<Key> &rhs);
+ iterator to_iterator(assoc_iterator it);
 
- /**
- * Convert this path instance to a @c std::string representation.
- * @return A string representation of this path.
+ /** Get the iterator that points to the same element as the argument.
+ * @note A valid const_assoc_iterator range (a, b) does not imply that
+ * (to_iterator(a), to_iterator(b)) is a valid range.
          */
- std::string to_string() const;
+ const_iterator to_iterator(const_assoc_iterator it);
 
- ///////////////////////////////////////////////////////////////////////
- // Operations
-
- /**
- * Extract the child subtree of the given property tree at the location
- * indicated by this path instance.
- * @param root The property tree from which to extract the child
- * subtree.
- * @return Pointer to the child subtree of the input property tree
- * indicated by the location given by this path instance. If no
- * child exists at the indicated location then NULL is returned.
- */
- template<class D, class C, class A, class X>
- basic_ptree<Key, D, C, A, basic_path<Key>, X> *get_child(
- basic_ptree<Key, D, C, A, basic_path<Key>, X> &root) const;
+ // Property tree view
 
- /**
- * Extract the child subtree of the given property tree at the location
- * indicated by this path instance.
- * @param root The property tree from which to extract the child
- * subtree.
- * @return Pointer to the constant child subtree of the input property
- * tree indicated by the location given by this path instance.
- * If no child exists at the indicated location then NULL is
- * returned.
- */
- template<class D, class C, class A, class X>
- const basic_ptree<Key, D, C, A, basic_path<Key>, X> *get_child(
- const basic_ptree<Key, D, C, A, basic_path<Key>, X> &root) const;
-
- /**
- * Insert or replace in the given property tree at the location
- * indicated by this path instance the second given property tree as a
- * child.
- * @param root The property tree in which to insert or replace the
- * child.
- * @param child The property tree to insert within the tree given by
- * that @c root parameter.
- * @param do_not_replace If set to true, causes function to always
- * insert a new key, even if there already exists
- * key with the same name. Otherwise an existing
- * key is replaced.
- * @return Pointer to the child property tree inserted at the location
- * given by this path instance. If this path is empty then
- * return NULL.
- */
- template<class D, class C, class A, class X>
- basic_ptree<Key, D, C, A, basic_path<Key>, X> *put_child(
- basic_ptree<Key, D, C, A, basic_path<Key>, X> &root,
- const basic_ptree<Key, D, C, A, basic_path<Key>, X> &child,
- bool do_not_replace) const;
-
- private:
-
- std::vector<Key> m_path;
-
- ///////////////////////////////////////////////////////////////////////
- // Internal
-
- template<class RanIt> void parse(RanIt begin, RanIt end,
- char_type separator);
-
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // translator class
-
- class translator
- {
- public:
- /** Default construct a translator instance. */
- translator();
+ /** Reference to the actual data in this node. */
+ data_type &data();
 
- /**
- * Construct a translator instance setting the internal locale state
- * using the given input locale.
- * @param loc The locale to use in this instance.
- */
- translator(const std::locale &loc);
+ /** Reference to the actual data in this node. */
+ const data_type &data() const;
 
- /**
- * Extract data value from the given property tree and convert it to an
- * instance of type @c T.
- * @param pt Property tree from which to retrieve the data value.
- * @param[out] value The variable in which to store the retrieved data
- * value.
- * @return @c true if the data value was sucessfully converted and
- * retrieved. Otherwise return @c false.
- */
- template<class Ptree, class T> bool get_value(const Ptree &pt, T &value)
- const;
+ /** Clear this tree completely, of both data and children. */
+ void clear();
 
- /**
- * Insert the given value as the data member in the given property tree
- * after converting it to instance of type @c Ptree::data_type.
- * @param pt Property tree in which to insert the given value as data.
- * @param value The value to store as data in the given property tree.
- * @return @c true If the data value was sucessfully converted and
- * retrieved. Otherwise return @c false.
+ /** Get the child at the given path, or throw @c ptree_bad_path.
+ * @note Depending on the path, the result at each level may not be
+ * completely determinate, i.e. if the same key appears multiple
+ * times, which child is chosen is not specified. This can lead
+ * to the path not being resolved even though there is a
+ * descendant with this path. Example:
+ * @code
+ * a -> b -> c
+ * -> b
+ * @endcode
+ * The path "a.b.c" will succeed if the resolution of "b" chooses
+ * the first such node, but fail if it chooses the second.
          */
- template<class Ptree, class T> bool put_value(Ptree &pt, const T &value)
- const;
-
- private:
+ self_type &get_child(const path_type &path);
 
- std::locale m_locale;
+ /** Get the child at the given path, or throw @c ptree_bad_path. */
+ const self_type &get_child(const path_type &path) const;
 
- };
+ /** Get the child at the given path, or return @p default_value. */
+ self_type &get_child(const path_type &path, self_type &default_value);
 
- ///////////////////////////////////////////////////////////////////////////
- // exceptions
+ /** Get the child at the given path, or return @p default_value. */
+ const self_type &get_child(const path_type &path,
+ const self_type &default_value) const;
 
- /// Base class for all property tree errors. Derives from
- /// @c std::runtime_error. Call member function @c what to get human
- /// readable message associated with the error.
- class ptree_error: public std::runtime_error
- {
- public:
- /// Instantiate a ptree_error instance with the given message.
- /// @param what The message to associate with this error.
- ptree_error(const std::string &what);
+ /** Get the child at the given path, or return boost::null. */
+ optional<self_type &> get_child_optional(const path_type &path);
 
- ~ptree_error() throw();
- };
+ /** Get the child at the given path, or return boost::null. */
+ optional<const self_type &>
+ get_child_optional(const path_type &path) const;
 
+ /** Set the node at the given path to the given value. Create any
+ * missing parents. If the node at the path already exists, replace it.
+ * @return A reference to the inserted subtree.
+ * @note Because of the way paths work, it is not generally guaranteed
+ * that a node newly created can be accessed using the same path.
+ * @note If the path could refer to multiple nodes, it is unspecified
+ * which one gets replaced.
+ */
+ self_type &put_child(const path_type &path, const self_type &value);
+
+ /** Add the node at the given path. Create any missing parents. If there
+ * already is a node at the path, add another one with the same key.
+ * @return A reference to the inserted subtree.
+ * @note Because of the way paths work, it is not generally guaranteed
+ * that a node newly created can be accessed using the same path.
+ */
+ self_type &add_child(const path_type &path, const self_type &value);
+
+ /** Take the value of this node and attempt to translate it to a
+ * @c Type object using the supplied translator.
+ * @throw ptree_bad_data if the conversion fails.
+ */
+ template<class Type, class Translator>
+ Type get_value(Translator tr =
+ typename translator_between<data_type, Type>::type()) const;
+
+ /** Take the value of this node and attempt to translate it to a
+ * @c Type object using the supplied translator. Return @p default_value
+ * if this fails.
+ */
+ template<class Type, class Translator>
+ Type get_value(const Type &default_value,
+ Translator tr =
+ typename translator_between<data_type, Type>::type()) const;
+
+ /** Take the value of this node and attempt to translate it to a
+ * @c Type object using the supplied translator. Return boost::null if
+ * this fails.
+ */
+ template<class Type, class Translator>
+ optional<Type> get_value_optional(Translator tr =
+ typename translator_between<data_type, Type>::type()) const;
+
+ /** Replace the value at this node with the given value, translated
+ * to the tree's data type using the supplied translator.
+ * @throw ptree_bad_data if the conversion fails.
+ */
+ template<class Type, class Translator>
+ void put_value(const Type &value,
+ Translator tr =
+ typename translator_between<data_type, Type>::type());
+
+ /** Shorthand for get_child(path).get_value(tr). */
+ template<class Type, class Translator>
+ Type get(const path_type &path,
+ Translator tr =
+ typename translator_between<data_type, Type>::type()
+ ) const;
+
+ /** Shorthand for get_child(path, empty_ptree())
+ * .get_value(default_value, tr).
+ * That is, return the translated value if possible, and the default
+ * value if the node doesn't exist or conversion fails.
+ */
+ template<class Type, class Translator>
+ Type get(const path_type &path,
+ const Type &default_value,
+ Translator tr =
+ typename translator_between<data_type, Type>::type()
+ ) const;
+
+ /** Shorthand for:
+ * @code
+ * if(optional\<self_type&\> node = get_child_optional(path))
+ * return node->get_value_optional(tr);
+ * return boost::null;
+ * @endcode
+ */
+ template<class Type, class Translator>
+ Type get_optional(const path_type &path,
+ Translator tr =
+ typename translator_between<data_type, Type>::type()
+ ) const;
+
+ /** Set the value of the node at the given path to the supplied value,
+ * translated to the tree's data type. If the node doesn't exist, it is
+ * created, including all its missing parents.
+ * @return The node that had its value changed.
+ * @throw ptree_bad_data if the conversion fails.
+ */
+ template<class Type, class Translator>
+ self_type &put(const path_type &path,
+ const Type &value,
+ Translator tr =
+ typename translator_between<data_type, Type>::type()
+ );
+
+ /** If the node identified by the path does not exist, create it,
+ * including all its missing parents.
+ * If the node already exists, add a sibling with the same key.
+ * Set the newly created node's value to the given paremeter,
+ * translated with the supplied translator.
+ */
+ template<class Type, class Translator>
+ self_type &add(const path_type &path,
+ const Type &value,
+ Translator tr =
+ typename translator_between<data_type, Type>::type()
+ );
 
- /// Error indicating that translation from given value to the property tree
- /// data_type (or vice versa) failed. Derives from ptree_error.
- class ptree_bad_data: public ptree_error
- {
- public:
- /// Instantiate a ptree_bad_data instance with the given message and
- /// data.
- /// @param what The message to associate with this error.
- /// @param data The value associated with this error that was the source
- /// of the translation failure.
- template<class T> ptree_bad_data(const std::string &what,
- const T &data);
-
- ~ptree_bad_data() throw();
-
- /// Retrieve the data associated with this error. This is the source
- /// value that failed to be translated.
- template<class T> T data();
     private:
- boost::any m_data;
- };
-
-
- /// Error indicating that specified path does not exist. Derives from
- /// ptree_error.
- class ptree_bad_path: public ptree_error
- {
- public:
- /// Instantiate a ptree_bad_path with the given message and path data.
- /// @param what The message to associate with this error.
- /// @param path The path that could not be found in the property_tree.
- template<class T> ptree_bad_path(const std::string &what,
- const T &path);
-
- ~ptree_bad_path() throw();
+ // Hold the data of this node
+ data_type m_data;
+ // Hold the children
+ base_container m_children;
 
- /// Retrieve the invalid path.
- template<class T> T path();
- private:
- boost::any m_path;
+ // Convenience
+ by_name_index& assoc() { return m_children.get<by_name>(); }
+ const by_name_index& assoc() const {
+ return m_children.get<by_name>();
+ }
+
+ // Getter tree-walk. Not const-safe! Gets the node the path refers to,
+ // or null. Destroys p's value.
+ self_type* walk_path(path_type& p) const;
+
+ // Modifer tree-walk. Gets the parent of the node referred to by the
+ // path, creating nodes as necessary. p is the path to the remaining
+ // child.
+ self_type& force_path(path_type& p);
     };
 
 } }
 
 // Include implementations
 #include <boost/property_tree/detail/ptree_implementation.hpp>
-// FIXME: There's a very nasty order dependency between exceptions_impl and
-// the other two headers on compilers that do really compliant ADL, like
-// GCC 4.3.
-#include <boost/property_tree/detail/path_implementation.hpp>
-#include <boost/property_tree/detail/translator_implementation.hpp>
-#include <boost/property_tree/detail/exceptions_implementation.hpp>
 
 #endif

Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp (original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp 2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -23,15 +23,49 @@
     ///////////////////////////////////////////////////////////////////////////
     // Classes
 
- template<class Key> class basic_path;
- class translator;
- //template<class C, class K, class P, class D, class X> class basic_ptree;
     template <class Key, class Data,
               class KeyCompare = std::less<Key>,
- class Allocator = std::allocator<Data>,
- class Path = basic_path<Key>,
- class Translate = translator>
- class basic_ptree;
+ class Allocator = std::allocator<Data>>
+ class basic_ptree;
+
+ struct id_translator;
+
+ template <typename String, typename Translator>
+ class string_path;
+
+ // We'll want to do this with concepts in C++0x.
+#if 0
+ concept PropertyTreePath<Path> {
+ // The key type for which this path works.
+ typedef key_type;
+ // Return the key and index that the first segment of the path name.
+ // Split the head off the state.
+ std::pair<key_type, std::size_t> Path::reduce();
+
+ // Return true if the path is empty.
+ bool Path::empty();
+
+ // Return true if the path contains a single element.
+ bool Path::single();
+ }
+ concept PropertyTreeKey<Key> {
+ PropertyTreePath path;
+ requires SameType<Key, PropertyTreePath<path>::key_type>;
+ }
+#endif
+ /// If you want to use a custom key type, specialize this struct for it
+ /// and give it a 'type' typedef that specifies your path type. The path
+ /// type must conform to the Path concept described in the documentation.
+ /// This is already specialized for std::basic_string.
+ template <typename Key>
+ struct path_of;
+
+ /// Specialize this struct to specify a default translator between the data
+ /// in a tree whose data_type is TreeData, and the external data_type
+ /// specified in a get_value, get, put_value or put operation.
+ /// This is already specialized for TreeData being std::basic_string.
+ template <typename TreeData, typename External>
+ struct translator_between;
 
     class ptree_error;
     class ptree_bad_data;
@@ -41,20 +75,20 @@
     // Typedefs
 
     /** Implements a path using a std::string as the key. */
- typedef basic_path<std::string> path;
+ typedef string_path<std::string, id_translator> path;
 
     /** Implements a path using a std::wstring as the key. */
- typedef basic_path<std::wstring> wpath;
+ typedef string_path<std::wstring, id_translator> wpath;
 
     /**
- * A property tree that uses a path type based upon std::string.
- * Comparisons of keys are performed in a case-sensitive manner.
+ * A property tree with std::string for key and data, and default
+ * comparison.
      */
     typedef basic_ptree<std::string, std::string> ptree;
 
     /**
- * A property tree that uses a path type based upon std::string.
- * Comparisons of keys are performed in a case-insensitive manner.
+ * A property tree with std::string for key and data, and case-insensitive
+ * comparison.
      */
     typedef basic_ptree<std::string, std::string,
                         detail::less_nocase<std::string> >
@@ -62,15 +96,15 @@
 
 #ifndef BOOST_NO_CWCHAR
     /**
- * A property tree that uses a wide-character path type based upon std::wstring.
- * Comparisons of keys are performed in a case-sensitive manner.
+ * A property tree with std::wstring for key and data, and default
+ * comparison.
      * @note The type only exists if the platform supports @c wchar_t.
      */
     typedef basic_ptree<std::wstring, std::wstring> wptree;
 
     /**
- * A property tree that uses a wide-character path type based upon std::wstring.
- * Comparisons of keys are performed in a case-insensitive manner.
+ * A property tree with std::wstring for key and data, and case-insensitive
+ * comparison.
      * @note The type only exists if the platform supports @c wchar_t.
      */
     typedef basic_ptree<std::wstring, std::wstring,
@@ -83,12 +117,10 @@
 
     /**
      * Swap two property tree instances.
- * @param pt1 Reference to first property tree involved in swap.
- * @param pt2 Reference to second property tree involved in swap.
      */
- template<class K, class D, class C, class A, class P, class X>
- void swap(basic_ptree<K, D, C, A, P, X> &pt1,
- basic_ptree<K, D, C, A, P, X> &pt2);
+ template<class K, class D, class C, class A>
+ void swap(basic_ptree<K, D, C, A> &pt1,
+ basic_ptree<K, D, C, A> &pt2);
 
     /**
      * Reference to empty property tree. Can be used as a default value of
@@ -96,11 +128,11 @@
      */
     template<class Ptree> const Ptree &empty_ptree();
 
- /** Join two path objects. */
- path operator /(const path &p1, const path &p2);
-
- /** Join two wide-path objects. */
- wpath operator /(const wpath &p1, const wpath &p2);
+ /** Join two string_path objects. */
+ template <typename String, typename Translator>
+ string_path<String, Translator> operator /(
+ const string_path<String, Translator> &p1,
+ const string_path<String, Translator> &p2);
 
 } }
 

Modified: branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt
==============================================================================
--- branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt (original)
+++ branches/sredl_2009_05_proptree_update/libs/property_tree/breaking_changes.txt 2009-05-18 14:28:59 EDT (Mon, 18 May 2009)
@@ -1,5 +1,27 @@
 List all breaking changes done to the interface during the update here.
 
-- Template parameters.
-Template parameters have been reordered, and an allocator parameter has been
-added.
+- Template parameters
+Template parameters have been thoroughly changed.
+Impact: If you were using a custom instantiation of basic_ptree, you have to
+ change your code.
+
+- put*
+The put and put_child functions of basic_ptree had add and add_child split from
+them, by splitting the functionality of the third parameter.
+Impact: If you were using the third parameter of these functions, you have to
+ change your code.
+
+- Custom paths
+Custom paths have been thoroughly changed.
+Impact: If you were using custom paths, you have to change your code. If you
+ referred to the basic_path template by name, you have to change your code.
+
+- Translators
+Translators have been thoroughly changed.
+Impact: If you were using translators at all, you probably have to change your
+ code.
+
+- find
+find() returns an assoc_iterator.
+Impact: If you use find, you may have to change your code.
+Rationale: equal_range() also returns assoc_iterators.


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