Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53111 - in branches/sredl_2009_05_proptree_update/boost/property_tree: . detail
From: sebastian.redl_at_[hidden]
Date: 2009-05-19 12:29:57


Author: cornedbee
Date: 2009-05-19 12:29:55 EDT (Tue, 19 May 2009)
New Revision: 53111
URL: http://svn.boost.org/trac/boost/changeset/53111

Log:
Core ptree complete, but probably full of typos.
Text files modified:
   branches/sredl_2009_05_proptree_update/boost/property_tree/detail/ptree_implementation.hpp | 397 +++++++++++++++++++++++----------------
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp | 116 ++++++++--
   branches/sredl_2009_05_proptree_update/boost/property_tree/ptree_fwd.hpp | 6
   3 files changed, 322 insertions(+), 197 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-19 12:29:55 EDT (Tue, 19 May 2009)
@@ -15,13 +15,13 @@
 
     // Big four
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     basic_ptree<K, D, C, A>::basic_ptree(allocator_type)
     {
         // FIXME: use allocator
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     basic_ptree<K, D, C, A>::basic_ptree(const data_type &data,
                                          allocator_type)
         : m_data(rhs)
@@ -29,7 +29,7 @@
         // FIXME: use allocator
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     basic_ptree<K, D, C, A>::basic_ptree(const basic_ptree<K, D, C, A> &rhs)
     {
         m_data = rhs.m_data;
@@ -49,7 +49,7 @@
         return *this;
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     void basic_ptree<K, D, C, A>::swap(basic_ptree<K, D, C, A> &rhs)
     {
         m_data.swap(rhs.m_data);
@@ -58,111 +58,111 @@
 
     // Container view
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::size_type
         basic_ptree<K, D, C, A>::size() const
     {
         return m_children.size();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::size_type
         basic_ptree<K, D, C, A>::max_size() const
     {
         return m_children.max_size();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     bool basic_ptree<K, D, C, A>::empty() const
     {
         return m_children.empty();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::begin()
     {
         return m_children.begin();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_iterator
         basic_ptree<K, D, C, A>::begin() const
     {
         return m_children.begin();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::end()
     {
         return m_children.end();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_iterator
         basic_ptree<K, D, C, A>::end() const
     {
         return m_children.end();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::reverse_iterator
         basic_ptree<K, D, C, A>::rbegin()
     {
         return m_children.rbegin();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_reverse_iterator
         basic_ptree<K, D, C, A>::rbegin() const
     {
         return m_children.rbegin();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::reverse_iterator
         basic_ptree<K, D, C, A>::rend()
     {
         return m_children.rend();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_reverse_iterator
         basic_ptree<K, D, C, A>::rend() const
     {
         return m_children.rend();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::value_type &
         basic_ptree<K, D, C, A>::front()
     {
         return m_children.front();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     const typename basic_ptree<K, D, C, A>::value_type &
         basic_ptree<K, D, C, A>::front() const
     {
         return m_children.front();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::value_type &
         basic_ptree<K, D, C, A>::back()
     {
         return m_children.back();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     const typename basic_ptree<K, D, C, A>::value_type &
         basic_ptree<K, D, C, A>::back() const
     {
         return m_children.back();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
     basic_ptree<K, D, C, A>::insert(iterator where, const value_type &value)
     {
@@ -170,65 +170,65 @@
     }
 
     template<class K, class D, class C, class A>
- template<class It>
+ template<class It> inline
     void basic_ptree<K, D, C, A>::insert(iterator where, It first, It last)
     {
         m_children.insert(where, first, last);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::erase(iterator where)
     {
         return m_children.erase(where);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::erase(iterator first, iterator last)
     {
         return m_children.erase(first, last);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::push_front(const value_type &value)
     {
         return m_children.push_front(value).first;
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::push_back(const value_type &value)
     {
         return m_children.push_back(value).first;
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     void basic_ptree<K, D, C, A>::pop_front()
     {
         m_children.pop_front();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     void basic_ptree<K, D, C, A>::pop_back()
     {
         m_children.pop_back();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     void basic_ptree<K, D, C, A>::reverse()
     {
         m_children.reverse();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     void basic_ptree<K, D, C, A>::sort()
     {
         m_children.sort();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     template<class Compare>
     void basic_ptree<K, D, C, A>::sort(Compare comp)
     {
@@ -237,7 +237,7 @@
 
     // Equality
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     bool basic_ptree<K, D, C, A>::operator ==(
                                   const basic_ptree<K, D, C, A> &rhs) const
     {
@@ -246,7 +246,7 @@
             m_children == rhs.m_children;
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     bool basic_ptree<K, D, C, A>::operator !=(
                                   const basic_ptree<K, D, C, A> &rhs) const
     {
@@ -255,33 +255,33 @@
 
     // Associative view
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::assoc_iterator not_found()
     {
         return assoc().end();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_assoc_iterator not_found() const
     {
         return assoc().end();
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::assoc_iterator
         basic_ptree<K, D, C, A>::find(const key_type &key)
     {
         return assoc().find(key);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_assoc_iterator
         basic_ptree<K, D, C, A>::find(const key_type &key) const
     {
         return assoc().find(key);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     std::pair<
         typename basic_ptree<K, D, C, A>::assoc_iterator,
         typename basic_ptree<K, D, C, A>::assoc_iterator
@@ -290,7 +290,7 @@
         return assoc().equal_range(key);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     std::pair<
         typename basic_ptree<K, D, C, A>::const_assoc_iterator,
         typename basic_ptree<K, D, C, A>::const_assoc_iterator
@@ -299,28 +299,28 @@
         return assoc().equal_range(key);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::size_type
         basic_ptree<K, D, C, A>::count(const key_type &key) const
     {
         return assoc().count(key);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::size_type
         basic_ptree<K, D, C, A>::erase(const key_type &key)
     {
         return assoc().erase(key);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::iterator
         basic_ptree<K, D, C, A>::to_iterator(assoc_iterator ai)
     {
         return m_children.project<0>(ai);
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::const_iterator
         basic_ptree<K, D, C, A>::to_iterator(const_assoc_iterator ai) const
     {
@@ -329,21 +329,21 @@
 
         // Property tree view
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     typename basic_ptree<K, D, C, A>::data_type &
         basic_ptree<K, D, C, A>::data()
     {
         return m_data;
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     const typename basic_ptree<K, D, C, A>::data_type &
         basic_ptree<K, D, C, A>::data() const
     {
         return m_data;
     }
 
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     void basic_ptree<K, D, C, A>::clear()
     {
         m_data = data_type();
@@ -362,16 +362,14 @@
         return *n;
     }
 
- // Get child ptree
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     const basic_ptree<K, D, C, A> &
         basic_ptree<K, D, C, A>::get_child(const path_type &path) const
     {
         return const_cast<self_type*>(this)->get_child(path);
     }
 
- // Get child ptree
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     basic_ptree<K, D, C, A> &
         basic_ptree<K, D, C, A>::get_child(const path_type &path,
                                            self_type &default_value)
@@ -381,8 +379,7 @@
         return n ? *n : default_value;
     }
 
- // Get child ptree
- template<class K, class D, class C, class A>
+ template<class K, class D, class C, class A> inline
     const basic_ptree<K, D, C, A> &
         basic_ptree<K, D, C, A>::get_child(const path_type &path,
                                            const self_type &default_value) const
@@ -392,7 +389,6 @@
     }
 
 
- // Get child ptree
     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)
@@ -405,7 +401,6 @@
         return *n;
     }
 
- // Get child ptree
     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
@@ -418,7 +413,6 @@
         return *n;
     }
 
- // Put child ptree
     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,
@@ -441,174 +435,255 @@
         while(n > 0) {
             parent->push_back(self_type());
         }
- // We've finally reached the position for the new child
- parent->push_back(value);
+ // We've finally reached the position for the new child. If it exists,
+ // replace it.
+ if(range.first != range.second) {
+ return *range.first = value;
+ } else {
+ return parent->push_back(value_type(fragment.first, value));
+ }
     }
 
- // Get value from data of ptree
     template<class K, class D, class C, class A>
- template<class Type>
- Type basic_ptree<K, D, C, A>::get_value(const translator_type &x) const
+ basic_ptree<K, D, C, A> &
+ basic_ptree<K, D, C, A>::add_child(const path_type &path,
+ const self_type &value)
     {
- 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 \"") +
- typeid(Type).name() + "\" failed", data()));
+ path_type p(path);
+ self_type &parent = force_path(p);
+ // Got the parent.
+ std::pair<key_type, std::size_t> fragment = p.reduce();
+ assert(fragment.second == 0 &&
+ "Cannot specify an index for the last fragment of the path");
+ return parent->push_back(value_type(fragment.first, value));
     }
 
- // Get value from data of ptree
     template<class K, class D, class C, class A>
- template<class Type>
+ template<class Type, class Translator>
+ Type basic_ptree<K, D, C, A>::get_value(Translator tr) const
+ {
+ if(boost::optional<Type> o = get_value_optional(tr)) {
+ return *o;
+ }
+ BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
+ std::string("conversion of data to type \"") +
+ typeid(Type).name() + "\" failed", data()));
+ }
+
+ template<class K, class D, class C, class A>
+ template<class Type> inline
+ Type basic_ptree<K, D, C, A>::get_value() const
+ {
+ return get_value(typename translator_between<data_type, Type>::type());
+ }
+
+ template<class K, class D, class C, class A>
+ template<class Type, class Translator> inline
     Type basic_ptree<K, D, C, A>::get_value(const Type &default_value,
- const translator_type &x) const
+ Translator tr) 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
- return default_value;
+ return get_value_optional(tr).get_value_or(default_value);
     }
 
- // Get value from data of ptree
     template<class K, class D, class C, class A>
- template<class CharType>
- std::basic_string<CharType>
- basic_ptree<K, D, C, A>::get_value(const CharType *default_value,
- const translator_type &x) const
+ template<class Type> inline
+ Type basic_ptree<K, D, C, A>::get_value(const Type &default_value) const
     {
- return get_value(std::basic_string<CharType>(default_value), x);
+ return get_value(default_value,
+ typename translator_between<data_type, Type>::type());
     }
 
- // Get value from data of ptree
     template<class K, class D, class C, class A>
- template<class Type>
- optional<Type>
- basic_ptree<K, D, C, A>::get_value_optional(const translator_type &x) const
+ template<class Type, class Translator> inline
+ optional<Type> basic_ptree<K, D, C, A>::get_value_optional(
+ Translator tr) 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 optional<Type>(value);
- else
- return optional<Type>();
+ return tr.get_value(data());
     }
 
- // Get value from data of child ptree
     template<class K, class D, class C, class A>
- template<class Type>
+ template<class Type> inline
+ optional<Type> basic_ptree<K, D, C, A>::get_value_optional() const
+ {
+ return get_value_optional(
+ typename translator_between<data_type, Type>::type());
+ }
+
+ template<class K, class D, class C, class A>
+ template<class Type, class Translator> inline
     Type basic_ptree<K, D, C, A>::get(const path_type &path,
- const translator_type &x) const
+ Translator tr) const
     {
- return get_child(path).get_value<Type>(x);
+ return get_child(path).get_value<Type>(tr);
     }
 
- // Get value from data of child ptree
     template<class K, class D, class C, class A>
- template<class Type>
+ template<class Type> inline
+ Type basic_ptree<K, D, C, A>::get(const path_type &path) const
+ {
+ return get_child(path).get_value<Type>();
+ }
+
+ template<class K, class D, class C, class A>
+ template<class Type, class Translator> inline
     Type basic_ptree<K, D, C, A>::get(const path_type &path,
- const Type &default_value,
- const translator_type &x) const
+ const Type &default_value,
+ Translator tr) const
     {
- if (optional<Type> result = get_optional<Type>(path, x))
- return *result;
- else
- return default_value;
+ return get_optional<Type>(path, tr).get_value_or(default_value);
     }
 
- // Get value from data of child ptree
     template<class K, class D, class C, class A>
- template<class CharType>
- std::basic_string<CharType>
- basic_ptree<K, D, C, A>::get(const path_type &path,
- const CharType *default_value,
- const translator_type &x) const
+ template<class Type, class Translator> inline
+ Type basic_ptree<K, D, C, A>::get(const path_type &path,
+ const Type &default_value) const
     {
- return get(path, std::basic_string<CharType>(default_value), x);
+ return get_optional<Type>(path).get_value_or(default_value);
     }
 
- // Get value from data of child ptree
     template<class K, class D, class C, class A>
- template<class Type>
- optional<Type>
- basic_ptree<K, D, C, A>::get_optional(const path_type &path,
- const translator_type &x) const
+ template<class Type, class Translator>
+ optional<Type> basic_ptree<K, D, C, A>::get_optional(const path_type &path,
+ Translator tr) const
     {
- if (optional<const basic_ptree<K, D, C, A> &> child = get_child_optional(path))
- return child.get().get_value_optional<Type>(x);
+ if (optional<const self_type&> child = get_child_optional(path))
+ return child.get().get_value_optional<Type>(tr);
         else
             return optional<Type>();
     }
 
- // Put value in data of ptree
     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)
+ optional<Type> basic_ptree<K, D, C, A>::get_optional(
+ const path_type &path) const
     {
- if (!x.put_value(*this, value))
- BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of type \"") + typeid(Type).name() +
- "\" into data failed", boost::any()));
+ if (optional<const self_type&> child = get_child_optional(path))
+ return child.get().get_value_optional<Type>();
+ else
+ return optional<Type>();
     }
 
- // Put value in data of child ptree
     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)
+ template<class Type, class Translator>
+ void basic_ptree<K, D, C, A>::put_value(const Type &value, Translator tr)
     {
- optional<self_type &> child;
- if (!do_not_replace && (child = get_child_optional(path)))
- {
- child.get().put_value(value, x);
- return *child;
- }
- else
- {
- self_type &child2 = put_child(path, empty_ptree<self_type>(), do_not_replace);
- child2.put_value(value, x);
- return child2;
+ if(optional<data_type> o = tr.put_value(value)) {
+ data() = *o;
+ } else {
+ BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
+ std::string("conversion of type \"") + typeid(Type).name() +
+ "\" to data failed", boost::any()));
         }
     }
 
- ////////////////////////////////////////////////////////////////////////////
- // Debugging
+ template<class K, class D, class C, class A>
+ template<class Type> inline
+ void basic_ptree<K, D, C, A>::put_value(const Type &value)
+ {
+ put_value(value, typename translator_between<data_type, Type>::type());
+ }
 
-#ifdef BOOST_PROPERTY_TREE_DEBUG
+ template<class K, class D, class C, class A>
+ template<class Type, typename Translator>
+ basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::put(
+ const path_type &path, const Type &value, Translator tr)
+ {
+ if(optional<self_type &> child = get_child_optional(path)) {
+ child.get().put_value(value, tr);
+ return *child;
+ } else {
+ self_type &child2 = put_child(path, self_type());
+ child2.put_value(value, tr);
+ return child2;
+ }
+ }
 
     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()
+ template<class Type> inline
+ basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::put(
+ const path_type &path, const Type &value)
     {
- empty_ptree<basic_ptree<K, D, C, A> >(); // Make sure empty ptree exists
- return debug_instances_count - 1; // Do not count empty ptree
+ return put(path, value,
+ typename translator_between<data_type, Type>::type());
     }
 
     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 Type, typename Translator> inline
+ basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::add(
+ const path_type &path, const Type &value, Translator tr)
+ {
+ self_type &child = put_child(path, self_type());
+ child.put_value(value, tr);
+ return child;
+ }
 
     template<class K, class D, class C, class A>
- boost::detail::lightweight_mutex
- basic_ptree<K, D, C, A>::debug_mutex;
+ template<class Type> inline
+ basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::add(
+ const path_type &path, const Type &value)
+ {
+ return add(path, value,
+ typename translator_between<data_type, Type>::type());
+ }
 
-#endif
 
- ///////////////////////////////////////////////////////////////////////////
- // Free functions
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A> *
+ basic_ptree<K, D, C, A>::walk_path(path_type &p) const
+ {
+ if(p.empty()) {
+ // I'm the child we're looking for.
+ return this;
+ }
+ // Recurse down the tree to find the path.
+ std::pair<key_type, std::size_t> fragment = p.reduce();
+ std::pair<const_assoc_iterator, const_assoc_iterator> range =
+ equal_range(fragment.first);
+ std::size_t n = fragment.second;
+ // If the path specifies an index, walk the range.
+ while(n > 0 && range.first != range.second) {
+ --n;
+ ++range.first;
+ }
+ if(range.first == range.second) {
+ // No such child.
+ return 0;
+ }
+ // Not done yet, recurse.
+ return range.first->walk_path(p);
+ }
 
- template<class Ptree>
- inline const Ptree &empty_ptree()
+ template<class K, class D, class C, class A>
+ basic_ptree<K, D, C, A> & basic_ptree<K, D, C, A>::force_path(path_type &p)
     {
- static Ptree pt;
- return pt;
+ assert(!p.empty() && "Empty path not allowed for put_child.");
+ if(p.single()) {
+ // I'm the parent we're looking for.
+ return *this;
+ }
+ std::pair<key_type, std::size_t> fragment = p.reduce();
+ std::pair<const_assoc_iterator, const_assoc_iterator> range =
+ equal_range(fragment.first);
+ std::size_t n = fragment.second;
+ // If the path specifies an index, walk the range.
+ while(n > 0 && range.first != range.second) {
+ --n;
+ ++range.first;
+ }
+ // If there's still something of the index left, add default-constructed
+ // elements.
+ while(n > 0) {
+ push_back(self_type());
+ }
+ // Now if we've found an existing child, go down that path. Else
+ // create a new one.
+ self_type& child = range.first == range.second ?
+ push_back(self_type()) : *range.first;
+ return child.force_path(p);
     }
 
+ // Free functions
+
     template<class K, class D, class C, class A>
     inline void swap(basic_ptree<K, D, C, A> &pt1, basic_ptree<K, D, C, A> &pt2)
     {
@@ -617,10 +692,4 @@
 
 } }
 
-// Undefine debug macros
-#ifdef BOOST_PROPERTY_TREE_DEBUG
-# undef BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT
-# undef BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT
-#endif
-
 #endif

Modified: branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp
==============================================================================
--- branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp (original)
+++ branches/sredl_2009_05_proptree_update/boost/property_tree/ptree.hpp 2009-05-19 12:29:55 EDT (Tue, 19 May 2009)
@@ -307,6 +307,8 @@
 
         /** 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.
+ * @param path Path to the child. The last fragment must not have an
+ * index.
          * @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.
@@ -322,37 +324,61 @@
             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 default translator.
+ * @throw ptree_bad_data if the conversion fails.
+ */
+ template<class Type>
+ Type get_value() 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;
+ Type get_value(const Type &default_value, Translator tr) const;
+
+ /** Take the value of this node and attempt to translate it to a
+ * @c Type object using the default translator. Return @p default_value
+ * if this fails.
+ */
+ template<class Type>
+ Type get_value(const Type &default_value) const;
 
         /** 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;
+ optional<Type> get_value_optional(Translator tr) const;
+
+ /** Take the value of this node and attempt to translate it to a
+ * @c Type object using the default translator. Return boost::null if
+ * this fails.
+ */
+ template<class Type>
+ optional<Type> get_value_optional() 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());
+ void put_value(const Type &value, Translator tr);
+
+ /** Replace the value at this node with the given value, translated
+ * to the tree's data type using the default translator.
+ * @throw ptree_bad_data if the conversion fails.
+ */
+ template<class Type>
+ void put_value(const Type &value);
 
         /** 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;
+ Type get(const path_type &path, Translator tr) const;
+
+ /** Shorthand for get_child(path).get_value\<Type\>(). */
+ template<class Type>
+ Type get(const path_type &path) const;
 
         /** Shorthand for get_child(path, empty_ptree())
          * .get_value(default_value, tr).
@@ -362,9 +388,15 @@
         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;
+ Translator tr) const;
+
+ /** Shorthand for get_child(path, empty_ptree())
+ * .get_value(default_value).
+ * That is, return the translated value if possible, and the default
+ * value if the node doesn't exist or conversion fails.
+ */
+ template<class Type>
+ Type get(const path_type &path, const Type &default_value) const;
 
         /** Shorthand for:
          * @code
@@ -374,10 +406,17 @@
          * @endcode
         */
         template<class Type, class Translator>
- Type get_optional(const path_type &path,
- Translator tr =
- typename translator_between<data_type, Type>::type()
- ) const;
+ Type get_optional(const path_type &path, Translator tr) const;
+
+ /** Shorthand for:
+ * @code
+ * if(optional\<const self_type&\> node = get_child_optional(path))
+ * return node->get_value_optional();
+ * return boost::null;
+ * @endcode
+ */
+ template<class Type>
+ Type get_optional(const path_type &path) const;
 
         /** Set the value of the node at the given path to the supplied value,
          * translated to the tree's data type. If the node doesn't exist, it is
@@ -386,24 +425,47 @@
          * @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()
- );
+ self_type &put(const path_type &path, const Type &value, Translator tr);
+
+ /** 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>
+ self_type &put(const path_type &path, const Type &value);
 
         /** 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.
+ * @param path Path to the child. The last fragment must not have an
+ * index.
+ * @param value The value to add.
+ * @param tr The translator to use.
+ * @return The node that was added.
+ * @throw ptree_bad_data if the conversion fails.
         */
         template<class Type, class Translator>
         self_type &add(const path_type &path,
                        const Type &value,
- Translator tr =
- typename translator_between<data_type, Type>::type()
- );
+ Translator tr);
+
+ /** 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.
+ * @param path Path to the child. The last fragment must not have an
+ * index.
+ * @param value The value to add.
+ * @return The node that was added.
+ * @throw ptree_bad_data if the conversion fails.
+ */
+ template<class Type>
+ self_type &add(const path_type &path, const Type &value);
 
     private:
         // Hold the data of this node

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-19 12:29:55 EDT (Tue, 19 May 2009)
@@ -122,12 +122,6 @@
     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
- * get_child. See empty_ptree_trick.cpp for example of usage.
- */
- template<class Ptree> const Ptree &empty_ptree();
-
     /** Join two string_path objects. */
     template <typename String, typename Translator>
     string_path<String, Translator> operator /(


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