519 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			519 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// ----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// Copyright (C) 2002-2006 Marcin Kalicinski
							 | 
						||
| 
								 | 
							
								// Copyright (C) 2009 Sebastian Redl
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Distributed under the Boost Software License, Version 1.0. 
							 | 
						||
| 
								 | 
							
								// (See accompanying file LICENSE_1_0.txt or copy at 
							 | 
						||
| 
								 | 
							
								// http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// For more information, see www.boost.org
							 | 
						||
| 
								 | 
							
								// ----------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
							 | 
						||
| 
								 | 
							
								#define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/property_tree/ptree_fwd.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/property_tree/string_path.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/property_tree/stream_translator.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/property_tree/exceptions.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/property_tree/detail/ptree_utils.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/multi_index_container.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/multi_index/indexed_by.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/multi_index/sequenced_index.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/multi_index/ordered_index.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/multi_index/member.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/utility/enable_if.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/throw_exception.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/optional.hpp>
							 | 
						||
| 
								 | 
							
								#include <utility>                  // for std::pair
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace 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.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * 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 basic_ptree
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								#if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        // Internal types
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * 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> self_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								        // Basic types
							 | 
						||
| 
								 | 
							
								        typedef Key                                  key_type;
							 | 
						||
| 
								 | 
							
								        typedef Data                                 data_type;
							 | 
						||
| 
								 | 
							
								        typedef KeyCompare                           key_compare;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Container view types
							 | 
						||
| 
								 | 
							
								        typedef std::pair<const Key, self_type>      value_type;
							 | 
						||
| 
								 | 
							
								        typedef std::size_t                          size_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // The problem with the iterators is that I can't make them complete
							 | 
						||
| 
								 | 
							
								        // until the container is complete. Sucks. Especially for the reverses.
							 | 
						||
| 
								 | 
							
								        class iterator;
							 | 
						||
| 
								 | 
							
								        class const_iterator;
							 | 
						||
| 
								 | 
							
								        class reverse_iterator;
							 | 
						||
| 
								 | 
							
								        class const_reverse_iterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Associative view types
							 | 
						||
| 
								 | 
							
								        class assoc_iterator;
							 | 
						||
| 
								 | 
							
								        class const_assoc_iterator;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Property tree view types
							 | 
						||
| 
								 | 
							
								        typedef typename path_of<Key>::type          path_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // The big five
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Creates a node with no children and default-constructed data. */
							 | 
						||
| 
								 | 
							
								        basic_ptree();
							 | 
						||
| 
								 | 
							
								        /** Creates a node with no children and a copy of the given data. */
							 | 
						||
| 
								 | 
							
								        explicit basic_ptree(const data_type &data);
							 | 
						||
| 
								 | 
							
								        basic_ptree(const self_type &rhs);
							 | 
						||
| 
								 | 
							
								        ~basic_ptree();
							 | 
						||
| 
								 | 
							
								        /** Basic guarantee only. */
							 | 
						||
| 
								 | 
							
								        self_type &operator =(const self_type &rhs);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Swap with other tree. Only constant-time and nothrow if the
							 | 
						||
| 
								 | 
							
								         * data type's swap is.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        void swap(self_type &rhs);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Container view functions
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        iterator begin();
							 | 
						||
| 
								 | 
							
								        const_iterator begin() const;
							 | 
						||
| 
								 | 
							
								        iterator end();
							 | 
						||
| 
								 | 
							
								        const_iterator end() const;
							 | 
						||
| 
								 | 
							
								        reverse_iterator rbegin();
							 | 
						||
| 
								 | 
							
								        const_reverse_iterator rbegin() const;
							 | 
						||
| 
								 | 
							
								        reverse_iterator rend();
							 | 
						||
| 
								 | 
							
								        const_reverse_iterator rend() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        value_type &front();
							 | 
						||
| 
								 | 
							
								        const value_type &front() const;
							 | 
						||
| 
								 | 
							
								        value_type &back();
							 | 
						||
| 
								 | 
							
								        const value_type &back() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Range insert. Equivalent to:
							 | 
						||
| 
								 | 
							
								         * @code
							 | 
						||
| 
								 | 
							
								         * for(; first != last; ++first) insert(where, *first);
							 | 
						||
| 
								 | 
							
								         * @endcode
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        template<class It> void insert(iterator where, It first, It last);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Range erase. Equivalent to:
							 | 
						||
| 
								 | 
							
								         * @code
							 | 
						||
| 
								 | 
							
								         * while(first != last;) first = erase(first);
							 | 
						||
| 
								 | 
							
								         * @endcode
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        iterator erase(iterator first, iterator last);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Equivalent to insert(begin(), value). */
							 | 
						||
| 
								 | 
							
								        iterator push_front(const value_type &value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Equivalent to insert(end(), value). */
							 | 
						||
| 
								 | 
							
								        iterator push_back(const value_type &value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Equivalent to erase(begin()). */
							 | 
						||
| 
								 | 
							
								        void pop_front();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Equivalent to erase(boost::prior(end())). */
							 | 
						||
| 
								 | 
							
								        void pop_back();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Reverses the order of direct children in the property tree. */
							 | 
						||
| 
								 | 
							
								        void reverse();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Sorts the direct children of this node according to the predicate.
							 | 
						||
| 
								 | 
							
								         * The predicate is passed the whole pair of key and child.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        template<class Compare> void sort(Compare comp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Sorts the direct children of this node according to key order. */
							 | 
						||
| 
								 | 
							
								        void sort();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Equality
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        bool operator ==(const self_type &rhs) const;
							 | 
						||
| 
								 | 
							
								        bool operator !=(const self_type &rhs) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Associative view
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Returns an iterator to the first child, in key order. */
							 | 
						||
| 
								 | 
							
								        assoc_iterator ordered_begin();
							 | 
						||
| 
								 | 
							
								        /** Returns an iterator to the first child, in key order. */
							 | 
						||
| 
								 | 
							
								        const_assoc_iterator ordered_begin() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Returns the not-found iterator. Equivalent to end() in a real
							 | 
						||
| 
								 | 
							
								         * associative container.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        assoc_iterator not_found();
							 | 
						||
| 
								 | 
							
								        /** Returns the not-found iterator. Equivalent to end() in a real
							 | 
						||
| 
								 | 
							
								         * associative container.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        const_assoc_iterator not_found() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        assoc_iterator find(const key_type &key);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        const_assoc_iterator find(const key_type &key) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Find the range of children that have the given key. */
							 | 
						||
| 
								 | 
							
								        std::pair<assoc_iterator, assoc_iterator>
							 | 
						||
| 
								 | 
							
								            equal_range(const key_type &key);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Count the number of direct children with the given key. */
							 | 
						||
| 
								 | 
							
								        size_type count(const key_type &key) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Erase all direct children with the given key and return the count.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        size_type erase(const key_type &key);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Get the iterator that points to the same element as the argument.
							 | 
						||
| 
								 | 
							
								         * @note A valid assoc_iterator range (a, b) does not imply that
							 | 
						||
| 
								 | 
							
								         *       (to_iterator(a), to_iterator(b)) is a valid range.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        iterator to_iterator(assoc_iterator it);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        const_iterator to_iterator(const_assoc_iterator it) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Property tree view
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Reference to the actual data in this node. */
							 | 
						||
| 
								 | 
							
								        data_type &data();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Reference to the actual data in this node. */
							 | 
						||
| 
								 | 
							
								        const data_type &data() const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Clear this tree completely, of both data and children. */
							 | 
						||
| 
								 | 
							
								        void clear();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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 deterministic, 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.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        self_type &get_child(const path_type &path);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Get the child at the given path, or return boost::null. */
							 | 
						||
| 
								 | 
							
								        optional<self_type &> get_child_optional(const path_type &path);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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.
							 | 
						||
| 
								 | 
							
								         * @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.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        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>
							 | 
						||
| 
								 | 
							
								        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
							 | 
						||
| 
								 | 
							
								        get_value(Translator tr) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Take the value of this node and attempt to translate it to a
							 | 
						||
| 
								 | 
							
								         * @c Type object using the default translator.
							 | 
						||
| 
								 | 
							
								         * @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) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Make get_value do the right thing for string literals. */
							 | 
						||
| 
								 | 
							
								        template <class Ch, class Translator>
							 | 
						||
| 
								 | 
							
								        typename boost::enable_if<
							 | 
						||
| 
								 | 
							
								            detail::is_character<Ch>,
							 | 
						||
| 
								 | 
							
								            std::basic_string<Ch>
							 | 
						||
| 
								 | 
							
								        >::type
							 | 
						||
| 
								 | 
							
								        get_value(const Ch *default_value, Translator tr) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Take the value of this node and attempt to translate it to a
							 | 
						||
| 
								 | 
							
								         * @c Type object using the default translator. Return @p default_value
							 | 
						||
| 
								 | 
							
								         * if this fails.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        template<class Type>
							 | 
						||
| 
								 | 
							
								        typename boost::disable_if<detail::is_translator<Type>, Type>::type
							 | 
						||
| 
								 | 
							
								        get_value(const Type &default_value) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Make get_value do the right thing for string literals. */
							 | 
						||
| 
								 | 
							
								        template <class Ch>
							 | 
						||
| 
								 | 
							
								        typename boost::enable_if<
							 | 
						||
| 
								 | 
							
								            detail::is_character<Ch>,
							 | 
						||
| 
								 | 
							
								            std::basic_string<Ch>
							 | 
						||
| 
								 | 
							
								        >::type
							 | 
						||
| 
								 | 
							
								        get_value(const Ch *default_value) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Take the value of this node and attempt to translate it to a
							 | 
						||
| 
								 | 
							
								         * @c Type object using the supplied translator. Return boost::null if
							 | 
						||
| 
								 | 
							
								         * this fails.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        template<class Type, class Translator>
							 | 
						||
| 
								 | 
							
								        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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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>
							 | 
						||
| 
								 | 
							
								        typename boost::enable_if<detail::is_translator<Translator>, Type>::type
							 | 
						||
| 
								 | 
							
								        get(const path_type &path, Translator tr) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Shorthand for get_child(path).get_value\<Type\>(). */
							 | 
						||
| 
								 | 
							
								        template<class Type>
							 | 
						||
| 
								 | 
							
								        Type get(const path_type &path) 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) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Make get do the right thing for string literals. */
							 | 
						||
| 
								 | 
							
								        template <class Ch, class Translator>
							 | 
						||
| 
								 | 
							
								        typename boost::enable_if<
							 | 
						||
| 
								 | 
							
								            detail::is_character<Ch>,
							 | 
						||
| 
								 | 
							
								            std::basic_string<Ch>
							 | 
						||
| 
								 | 
							
								        >::type
							 | 
						||
| 
								 | 
							
								        get(const path_type &path, const Ch *default_value, Translator tr)const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Shorthand for get_child(path, empty_ptree())
							 | 
						||
| 
								 | 
							
								         *                    .get_value(default_value).
							 | 
						||
| 
								 | 
							
								         * That is, return the translated value if possible, and the default
							 | 
						||
| 
								 | 
							
								         * value if the node doesn't exist or conversion fails.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        template<class Type>
							 | 
						||
| 
								 | 
							
								        typename boost::disable_if<detail::is_translator<Type>, Type>::type
							 | 
						||
| 
								 | 
							
								        get(const path_type &path, const Type &default_value) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Make get do the right thing for string literals. */
							 | 
						||
| 
								 | 
							
								        template <class Ch>
							 | 
						||
| 
								 | 
							
								        typename boost::enable_if<
							 | 
						||
| 
								 | 
							
								            detail::is_character<Ch>,
							 | 
						||
| 
								 | 
							
								            std::basic_string<Ch>
							 | 
						||
| 
								 | 
							
								        >::type
							 | 
						||
| 
								 | 
							
								        get(const path_type &path, const Ch *default_value) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Shorthand for:
							 | 
						||
| 
								 | 
							
								         * @code
							 | 
						||
| 
								 | 
							
								         * if(optional\<self_type&\> node = get_child_optional(path))
							 | 
						||
| 
								 | 
							
								         *   return node->get_value_optional(tr);
							 | 
						||
| 
								 | 
							
								         * return boost::null;
							 | 
						||
| 
								 | 
							
								         * @endcode
							 | 
						||
| 
								 | 
							
								         * That is, return the value if it exists and can be converted, or nil.
							 | 
						||
| 
								 | 
							
								        */
							 | 
						||
| 
								 | 
							
								        template<class Type, class Translator>
							 | 
						||
| 
								 | 
							
								        optional<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
							 | 
						||
| 
								 | 
							
								         * That is, return the value if it exists and can be converted, or nil.
							 | 
						||
| 
								 | 
							
								        */
							 | 
						||
| 
								 | 
							
								        template<class Type>
							 | 
						||
| 
								 | 
							
								        optional<Type> get_optional(const path_type &path) const;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Set the value of the node at the given path to the supplied value,
							 | 
						||
| 
								 | 
							
								         * translated to the tree's data type. If the node doesn't exist, it is
							 | 
						||
| 
								 | 
							
								         * 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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** 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
							 | 
						||
| 
								 | 
							
								        data_type m_data;
							 | 
						||
| 
								 | 
							
								        // Hold the children - this is a void* because we can't complete the
							 | 
						||
| 
								 | 
							
								        // container type within the class.
							 | 
						||
| 
								 | 
							
								        void* m_children;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Getter tree-walk. Not const-safe! Gets the node the path refers to,
							 | 
						||
| 
								 | 
							
								        // or null. Destroys p's value.
							 | 
						||
| 
								 | 
							
								        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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This struct contains typedefs for the concrete types.
							 | 
						||
| 
								 | 
							
								        struct subs;
							 | 
						||
| 
								 | 
							
								        friend struct subs;
							 | 
						||
| 
								 | 
							
								        friend class iterator;
							 | 
						||
| 
								 | 
							
								        friend class const_iterator;
							 | 
						||
| 
								 | 
							
								        friend class reverse_iterator;
							 | 
						||
| 
								 | 
							
								        friend class const_reverse_iterator;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/property_tree/detail/ptree_implementation.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |