![]() |
|
|||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |