Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:47:22

0001 // ----------------------------------------------------------------------------
0002 // Copyright (C) 2002-2006 Marcin Kalicinski
0003 // Copyright (C) 2009 Sebastian Redl
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. 
0006 // (See accompanying file LICENSE_1_0.txt or copy at 
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // For more information, see www.boost.org
0010 // ----------------------------------------------------------------------------
0011 
0012 #ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
0013 #define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
0014 
0015 #include <boost/property_tree/ptree_fwd.hpp>
0016 #include <boost/property_tree/string_path.hpp>
0017 #include <boost/property_tree/stream_translator.hpp>
0018 #include <boost/property_tree/exceptions.hpp>
0019 #include <boost/property_tree/detail/ptree_utils.hpp>
0020 
0021 #include <boost/multi_index_container.hpp>
0022 #include <boost/multi_index/indexed_by.hpp>
0023 #include <boost/multi_index/sequenced_index.hpp>
0024 #include <boost/multi_index/ordered_index.hpp>
0025 #include <boost/multi_index/member.hpp>
0026 #include <boost/core/enable_if.hpp>
0027 #include <boost/throw_exception.hpp>
0028 #include <boost/optional/optional.hpp>
0029 #include <utility>                  // for std::pair
0030 
0031 namespace boost { namespace property_tree
0032 {
0033 
0034     /**
0035      * Property tree main structure. A property tree is a hierarchical data
0036      * structure which has one element of type @p Data in each node, as well
0037      * as an ordered sequence of sub-nodes, which are additionally identified
0038      * by a non-unique key of type @p Key.
0039      *
0040      * Key equivalency is defined by @p KeyCompare, a predicate defining a
0041      * strict weak ordering.
0042      *
0043      * Property tree defines a Container-like interface to the (key-node) pairs
0044      * of its direct sub-nodes. The iterators are bidirectional. The sequence
0045      * of nodes is held in insertion order, not key order.
0046      */
0047     template<class Key, class Data, class KeyCompare>
0048     class basic_ptree
0049     {
0050 #if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED)
0051     public:
0052 #endif
0053         // Internal types
0054         /**
0055          * Simpler way to refer to this basic_ptree\<C,K,P,A\> type.
0056          * Note that this is private, and made public only for doxygen.
0057          */
0058         typedef basic_ptree<Key, Data, KeyCompare> self_type;
0059 
0060     public:
0061         // Basic types
0062         typedef Key                                  key_type;
0063         typedef Data                                 data_type;
0064         typedef KeyCompare                           key_compare;
0065 
0066         // Container view types
0067         typedef std::pair<const Key, self_type>      value_type;
0068         typedef std::size_t                          size_type;
0069 
0070         // The problem with the iterators is that I can't make them complete
0071         // until the container is complete. Sucks. Especially for the reverses.
0072         class iterator;
0073         class const_iterator;
0074         class reverse_iterator;
0075         class const_reverse_iterator;
0076 
0077         // Associative view types
0078         class assoc_iterator;
0079         class const_assoc_iterator;
0080 
0081         // Property tree view types
0082         typedef typename path_of<Key>::type          path_type;
0083 
0084 
0085         // The big five
0086 
0087         /** Creates a node with no children and default-constructed data. */
0088         basic_ptree();
0089         /** Creates a node with no children and a copy of the given data. */
0090         explicit basic_ptree(const data_type &data);
0091         basic_ptree(const self_type &rhs);
0092         ~basic_ptree();
0093         /** Basic guarantee only. */
0094         self_type &operator =(const self_type &rhs);
0095 
0096         /** Swap with other tree. Only constant-time and nothrow if the
0097          * data type's swap is.
0098          */
0099         void swap(self_type &rhs);
0100 
0101         // Container view functions
0102 
0103         /** The number of direct children of this node. */
0104         size_type size() const;
0105         size_type max_size() const;
0106         /** Whether there are any direct children. */
0107         bool empty() const;
0108 
0109         iterator begin();
0110         const_iterator begin() const;
0111         iterator end();
0112         const_iterator end() const;
0113         reverse_iterator rbegin();
0114         const_reverse_iterator rbegin() const;
0115         reverse_iterator rend();
0116         const_reverse_iterator rend() const;
0117 
0118         value_type &front();
0119         const value_type &front() const;
0120         value_type &back();
0121         const value_type &back() const;
0122 
0123         /** Insert a copy of the given tree with its key just before the given
0124          * position in this node. This operation invalidates no iterators.
0125          * @return An iterator to the newly created child.
0126          */
0127         iterator insert(iterator where, const value_type &value);
0128 
0129         /** Range insert. Equivalent to:
0130          * @code
0131          * for(; first != last; ++first) insert(where, *first);
0132          * @endcode
0133          */
0134         template<class It> void insert(iterator where, It first, It last);
0135 
0136         /** Erase the child pointed at by the iterator. This operation
0137          * invalidates the given iterator, as well as its equivalent
0138          * assoc_iterator.
0139          * @return A valid iterator pointing to the element after the erased.
0140          */
0141         iterator erase(iterator where);
0142 
0143         /** Range erase. Equivalent to:
0144          * @code
0145          * while(first != last;) first = erase(first);
0146          * @endcode
0147          */
0148         iterator erase(iterator first, iterator last);
0149 
0150         /** Equivalent to insert(begin(), value). */
0151         iterator push_front(const value_type &value);
0152 
0153         /** Equivalent to insert(end(), value). */
0154         iterator push_back(const value_type &value);
0155 
0156         /** Equivalent to erase(begin()). */
0157         void pop_front();
0158 
0159         /** Equivalent to erase(boost::prior(end())). */
0160         void pop_back();
0161 
0162         /** Reverses the order of direct children in the property tree. */
0163         void reverse();
0164 
0165         /** Sorts the direct children of this node according to the predicate.
0166          * The predicate is passed the whole pair of key and child.
0167          */
0168         template<class Compare> void sort(Compare comp);
0169 
0170         /** Sorts the direct children of this node according to key order. */
0171         void sort();
0172 
0173         // Equality
0174 
0175         /** Two property trees are the same if they have the same data, the keys
0176          * and order of their children are the same, and the children compare
0177          * equal, recursively.
0178          */
0179         bool operator ==(const self_type &rhs) const;
0180         bool operator !=(const self_type &rhs) const;
0181 
0182         // Associative view
0183 
0184         /** Returns an iterator to the first child, in key order. */
0185         assoc_iterator ordered_begin();
0186         /** Returns an iterator to the first child, in key order. */
0187         const_assoc_iterator ordered_begin() const;
0188 
0189         /** Returns the not-found iterator. Equivalent to end() in a real
0190          * associative container.
0191          */
0192         assoc_iterator not_found();
0193         /** Returns the not-found iterator. Equivalent to end() in a real
0194          * associative container.
0195          */
0196         const_assoc_iterator not_found() const;
0197 
0198         /** Find a child with the given key, or not_found() if there is none.
0199          * There is no guarantee about which child is returned if multiple have
0200          * the same key.
0201          */
0202         assoc_iterator find(const key_type &key);
0203 
0204         /** Find a child with the given key, or not_found() if there is none.
0205          * There is no guarantee about which child is returned if multiple have
0206          * the same key.
0207          */
0208         const_assoc_iterator find(const key_type &key) const;
0209 
0210         /** Find the range of children that have the given key. */
0211         std::pair<assoc_iterator, assoc_iterator>
0212             equal_range(const key_type &key);
0213 
0214         /** Find the range of children that have the given key. */
0215         std::pair<const_assoc_iterator, const_assoc_iterator>
0216             equal_range(const key_type &key) const;
0217 
0218         /** Count the number of direct children with the given key. */
0219         size_type count(const key_type &key) const;
0220 
0221         /** Erase all direct children with the given key and return the count.
0222          */
0223         size_type erase(const key_type &key);
0224 
0225         /** Get the iterator that points to the same element as the argument.
0226          * @note A valid assoc_iterator range (a, b) does not imply that
0227          *       (to_iterator(a), to_iterator(b)) is a valid range.
0228          */
0229         iterator to_iterator(assoc_iterator it);
0230 
0231         /** Get the iterator that points to the same element as the argument.
0232          * @note A valid const_assoc_iterator range (a, b) does not imply that
0233          *       (to_iterator(a), to_iterator(b)) is a valid range.
0234          */
0235         const_iterator to_iterator(const_assoc_iterator it) const;
0236 
0237         // Property tree view
0238 
0239         /** Reference to the actual data in this node. */
0240         data_type &data();
0241 
0242         /** Reference to the actual data in this node. */
0243         const data_type &data() const;
0244 
0245         /** Clear this tree completely, of both data and children. */
0246         void clear();
0247 
0248         /** Get the child at the given path, or throw @c ptree_bad_path.
0249          * @note Depending on the path, the result at each level may not be
0250          *       completely deterministic, i.e. if the same key appears multiple
0251          *       times, which child is chosen is not specified. This can lead
0252          *       to the path not being resolved even though there is a
0253          *       descendant with this path. Example:
0254          * @code
0255          *   a -> b -> c
0256          *     -> b
0257          * @endcode
0258          *       The path "a.b.c" will succeed if the resolution of "b" chooses
0259          *       the first such node, but fail if it chooses the second.
0260          */
0261         self_type &get_child(const path_type &path);
0262 
0263         /** Get the child at the given path, or throw @c ptree_bad_path. */
0264         const self_type &get_child(const path_type &path) const;
0265 
0266         /** Get the child at the given path, or return @p default_value. */
0267         self_type &get_child(const path_type &path, self_type &default_value);
0268 
0269         /** Get the child at the given path, or return @p default_value. */
0270         const self_type &get_child(const path_type &path,
0271                                    const self_type &default_value) const;
0272 
0273         /** Prevents calls to get_child with temporary default values */
0274         void get_child(const path_type &path,
0275                        const self_type &&default_value) const = delete;
0276 
0277         /** Get the child at the given path, or return boost::null. */
0278         optional<self_type &> get_child_optional(const path_type &path);
0279 
0280         /** Get the child at the given path, or return boost::null. */
0281         optional<const self_type &>
0282           get_child_optional(const path_type &path) const;
0283 
0284         /** Set the node at the given path to the given value. Create any
0285          * missing parents. If the node at the path already exists, replace it.
0286          * @return A reference to the inserted subtree.
0287          * @note Because of the way paths work, it is not generally guaranteed
0288          *       that a node newly created can be accessed using the same path.
0289          * @note If the path could refer to multiple nodes, it is unspecified
0290          *       which one gets replaced.
0291          */
0292         self_type &put_child(const path_type &path, const self_type &value);
0293 
0294         /** Add the node at the given path. Create any missing parents. If there
0295          * already is a node at the path, add another one with the same key.
0296          * @param path Path to the child. The last fragment must not have an
0297          *             index.
0298          * @return A reference to the inserted subtree.
0299          * @note Because of the way paths work, it is not generally guaranteed
0300          *       that a node newly created can be accessed using the same path.
0301          */
0302         self_type &add_child(const path_type &path, const self_type &value);
0303 
0304         /** Take the value of this node and attempt to translate it to a
0305          * @c Type object using the supplied translator.
0306          * @throw ptree_bad_data if the conversion fails.
0307          */
0308         template<class Type, class Translator>
0309         typename boost::enable_if<detail::is_translator<Translator>, Type>::type
0310         get_value(Translator tr) const;
0311 
0312         /** Take the value of this node and attempt to translate it to a
0313          * @c Type object using the default translator.
0314          * @throw ptree_bad_data if the conversion fails.
0315          */
0316         template<class Type>
0317         Type get_value() const;
0318 
0319         /** Take the value of this node and attempt to translate it to a
0320          * @c Type object using the supplied translator. Return @p default_value
0321          * if this fails.
0322          */
0323         template<class Type, class Translator>
0324         Type get_value(const Type &default_value, Translator tr) const;
0325 
0326         /** Make get_value do the right thing for string literals. */
0327         template <class Ch, class Translator>
0328         typename boost::enable_if<
0329             detail::is_character<Ch>,
0330             std::basic_string<Ch>
0331         >::type
0332         get_value(const Ch *default_value, Translator tr) const;
0333 
0334         /** Take the value of this node and attempt to translate it to a
0335          * @c Type object using the default translator. Return @p default_value
0336          * if this fails.
0337          */
0338         template<class Type>
0339         typename boost::disable_if<detail::is_translator<Type>, Type>::type
0340         get_value(const Type &default_value) const;
0341 
0342         /** Make get_value do the right thing for string literals. */
0343         template <class Ch>
0344         typename boost::enable_if<
0345             detail::is_character<Ch>,
0346             std::basic_string<Ch>
0347         >::type
0348         get_value(const Ch *default_value) const;
0349 
0350         /** Take the value of this node and attempt to translate it to a
0351          * @c Type object using the supplied translator. Return boost::null if
0352          * this fails.
0353          */
0354         template<class Type, class Translator>
0355         optional<Type> get_value_optional(Translator tr) const;
0356 
0357         /** Take the value of this node and attempt to translate it to a
0358          * @c Type object using the default translator. Return boost::null if
0359          * this fails.
0360          */
0361         template<class Type>
0362         optional<Type> get_value_optional() const;
0363 
0364         /** Replace the value at this node with the given value, translated
0365          * to the tree's data type using the supplied translator.
0366          * @throw ptree_bad_data if the conversion fails.
0367         */
0368         template<class Type, class Translator>
0369         void put_value(const Type &value, Translator tr);
0370 
0371         /** Replace the value at this node with the given value, translated
0372          * to the tree's data type using the default translator.
0373          * @throw ptree_bad_data if the conversion fails.
0374         */
0375         template<class Type>
0376         void put_value(const Type &value);
0377 
0378         /** Shorthand for get_child(path).get_value(tr). */
0379         template<class Type, class Translator>
0380         typename boost::enable_if<detail::is_translator<Translator>, Type>::type
0381         get(const path_type &path, Translator tr) const;
0382 
0383         /** Shorthand for get_child(path).get_value\<Type\>(). */
0384         template<class Type>
0385         Type get(const path_type &path) const;
0386 
0387         /** Shorthand for get_child(path, empty_ptree())
0388          *                    .get_value(default_value, tr).
0389          * That is, return the translated value if possible, and the default
0390          * value if the node doesn't exist or conversion fails.
0391          */
0392         template<class Type, class Translator>
0393         Type get(const path_type &path,
0394                  const Type &default_value,
0395                  Translator tr) const;
0396 
0397         /** Make get do the right thing for string literals. */
0398         template <class Ch, class Translator>
0399         typename boost::enable_if<
0400             detail::is_character<Ch>,
0401             std::basic_string<Ch>
0402         >::type
0403         get(const path_type &path, const Ch *default_value, Translator tr)const;
0404 
0405         /** Shorthand for get_child(path, empty_ptree())
0406          *                    .get_value(default_value).
0407          * That is, return the translated value if possible, and the default
0408          * value if the node doesn't exist or conversion fails.
0409          */
0410         template<class Type>
0411         typename boost::disable_if<detail::is_translator<Type>, Type>::type
0412         get(const path_type &path, const Type &default_value) const;
0413 
0414         /** Make get do the right thing for string literals. */
0415         template <class Ch>
0416         typename boost::enable_if<
0417             detail::is_character<Ch>,
0418             std::basic_string<Ch>
0419         >::type
0420         get(const path_type &path, const Ch *default_value) const;
0421 
0422         /** Shorthand for:
0423          * @code
0424          * if(optional\<self_type&\> node = get_child_optional(path))
0425          *   return node->get_value_optional(tr);
0426          * return boost::null;
0427          * @endcode
0428          * That is, return the value if it exists and can be converted, or nil.
0429         */
0430         template<class Type, class Translator>
0431         optional<Type> get_optional(const path_type &path, Translator tr) const;
0432 
0433         /** Shorthand for:
0434          * @code
0435          * if(optional\<const self_type&\> node = get_child_optional(path))
0436          *   return node->get_value_optional();
0437          * return boost::null;
0438          * @endcode
0439          * That is, return the value if it exists and can be converted, or nil.
0440         */
0441         template<class Type>
0442         optional<Type> get_optional(const path_type &path) const;
0443 
0444         /** Set the value of the node at the given path to the supplied value,
0445          * translated to the tree's data type. If the node doesn't exist, it is
0446          * created, including all its missing parents.
0447          * @return The node that had its value changed.
0448          * @throw ptree_bad_data if the conversion fails.
0449         */
0450         template<class Type, class Translator>
0451         self_type &put(const path_type &path, const Type &value, Translator tr);
0452 
0453         /** Set the value of the node at the given path to the supplied value,
0454          * translated to the tree's data type. If the node doesn't exist, it is
0455          * created, including all its missing parents.
0456          * @return The node that had its value changed.
0457          * @throw ptree_bad_data if the conversion fails.
0458         */
0459         template<class Type>
0460         self_type &put(const path_type &path, const Type &value);
0461 
0462         /** If the node identified by the path does not exist, create it,
0463          * including all its missing parents.
0464          * If the node already exists, add a sibling with the same key.
0465          * Set the newly created node's value to the given paremeter,
0466          * translated with the supplied translator.
0467          * @param path Path to the child. The last fragment must not have an
0468          *             index.
0469          * @param value The value to add.
0470          * @param tr The translator to use.
0471          * @return The node that was added.
0472          * @throw ptree_bad_data if the conversion fails.
0473         */
0474         template<class Type, class Translator>
0475         self_type &add(const path_type &path,
0476                        const Type &value,
0477                        Translator tr);
0478 
0479         /** If the node identified by the path does not exist, create it,
0480          * including all its missing parents.
0481          * If the node already exists, add a sibling with the same key.
0482          * Set the newly created node's value to the given paremeter,
0483          * translated with the supplied translator.
0484          * @param path Path to the child. The last fragment must not have an
0485          *             index.
0486          * @param value The value to add.
0487          * @return The node that was added.
0488          * @throw ptree_bad_data if the conversion fails.
0489         */
0490         template<class Type>
0491         self_type &add(const path_type &path, const Type &value);
0492 
0493     private:
0494         // Hold the data of this node
0495         data_type m_data;
0496         // Hold the children - this is a void* because we can't complete the
0497         // container type within the class.
0498         void* m_children;
0499 
0500         // Getter tree-walk. Not const-safe! Gets the node the path refers to,
0501         // or null. Destroys p's value.
0502         self_type* walk_path(path_type& p) const;
0503 
0504         // Modifer tree-walk. Gets the parent of the node referred to by the
0505         // path, creating nodes as necessary. p is the path to the remaining
0506         // child.
0507         self_type& force_path(path_type& p);
0508 
0509         // This struct contains typedefs for the concrete types.
0510         struct subs;
0511         friend struct subs;
0512         friend class iterator;
0513         friend class const_iterator;
0514         friend class reverse_iterator;
0515         friend class const_reverse_iterator;
0516     };
0517 
0518 }}
0519 
0520 #include <boost/property_tree/detail/ptree_implementation.hpp>
0521 
0522 #endif