1 // ---------------------------------------------------------------------------- 2 // Copyright (C) 2002-2006 Marcin Kalicinski 3 // Copyright (C) 2009 Sebastian Redl 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // For more information, see www.boost.org 10 // ---------------------------------------------------------------------------- 11 12 #ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED 13 #define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED 14 15 #include <boost/property_tree/ptree_fwd.hpp> 16 #include <boost/property_tree/string_path.hpp> 17 #include <boost/property_tree/stream_translator.hpp> 18 #include <boost/property_tree/exceptions.hpp> 19 #include <boost/property_tree/detail/ptree_utils.hpp> 20 21 #include <boost/multi_index_container.hpp> 22 #include <boost/multi_index/indexed_by.hpp> 23 #include <boost/multi_index/sequenced_index.hpp> 24 #include <boost/multi_index/ordered_index.hpp> 25 #include <boost/multi_index/member.hpp> 26 #include <boost/utility/enable_if.hpp> 27 #include <boost/throw_exception.hpp> 28 #include <boost/optional.hpp> 29 #include <utility> // for std::pair 30 31 namespace boost { namespace property_tree 32 { 33 34 /** 35 * Property tree main structure. A property tree is a hierarchical data 36 * structure which has one element of type @p Data in each node, as well 37 * as an ordered sequence of sub-nodes, which are additionally identified 38 * by a non-unique key of type @p Key. 39 * 40 * Key equivalency is defined by @p KeyCompare, a predicate defining a 41 * strict weak ordering. 42 * 43 * Property tree defines a Container-like interface to the (key-node) pairs 44 * of its direct sub-nodes. The iterators are bidirectional. The sequence 45 * of nodes is held in insertion order, not key order. 46 */ 47 template<class Key, class Data, class KeyCompare> 48 class basic_ptree 49 { 50 #if defined(BOOST_PROPERTY_TREE_DOXYGEN_INVOKED) 51 public: 52 #endif 53 // Internal types 54 /** 55 * Simpler way to refer to this basic_ptree\<C,K,P,A\> type. 56 * Note that this is private, and made public only for doxygen. 57 */ 58 typedef basic_ptree<Key, Data, KeyCompare> self_type; 59 60 public: 61 // Basic types 62 typedef Key key_type; 63 typedef Data data_type; 64 typedef KeyCompare key_compare; 65 66 // Container view types 67 typedef std::pair<const Key, self_type> value_type; 68 typedef std::size_t size_type; 69 70 // The problem with the iterators is that I can't make them complete 71 // until the container is complete. Sucks. Especially for the reverses. 72 class iterator; 73 class const_iterator; 74 class reverse_iterator; 75 class const_reverse_iterator; 76 77 // Associative view types 78 class assoc_iterator; 79 class const_assoc_iterator; 80 81 // Property tree view types 82 typedef typename path_of<Key>::type path_type; 83 84 85 // The big five 86 87 /** Creates a node with no children and default-constructed data. */ 88 basic_ptree(); 89 /** Creates a node with no children and a copy of the given data. */ 90 explicit basic_ptree(const data_type &data); 91 basic_ptree(const self_type &rhs); 92 ~basic_ptree(); 93 /** Basic guarantee only. */ 94 self_type &operator =(const self_type &rhs); 95 96 /** Swap with other tree. Only constant-time and nothrow if the 97 * data type's swap is. 98 */ 99 void swap(self_type &rhs); 100 101 // Container view functions 102 103 /** The number of direct children of this node. */ 104 size_type size() const; 105 size_type max_size() const; 106 /** Whether there are any direct children. */ 107 bool empty() const; 108 109 iterator begin(); 110 const_iterator begin() const; 111 iterator end(); 112 const_iterator end() const; 113 reverse_iterator rbegin(); 114 const_reverse_iterator rbegin() const; 115 reverse_iterator rend(); 116 const_reverse_iterator rend() const; 117 118 value_type &front(); 119 const value_type &front() const; 120 value_type &back(); 121 const value_type &back() const; 122 123 /** Insert a copy of the given tree with its key just before the given 124 * position in this node. This operation invalidates no iterators. 125 * @return An iterator to the newly created child. 126 */ 127 iterator insert(iterator where, const value_type &value); 128 129 /** Range insert. Equivalent to: 130 * @code 131 * for(; first != last; ++first) insert(where, *first); 132 * @endcode 133 */ 134 template<class It> void insert(iterator where, It first, It last); 135 136 /** Erase the child pointed at by the iterator. This operation 137 * invalidates the given iterator, as well as its equivalent 138 * assoc_iterator. 139 * @return A valid iterator pointing to the element after the erased. 140 */ 141 iterator erase(iterator where); 142 143 /** Range erase. Equivalent to: 144 * @code 145 * while(first != last;) first = erase(first); 146 * @endcode 147 */ 148 iterator erase(iterator first, iterator last); 149 150 /** Equivalent to insert(begin(), value). */ 151 iterator push_front(const value_type &value); 152 153 /** Equivalent to insert(end(), value). */ 154 iterator push_back(const value_type &value); 155 156 /** Equivalent to erase(begin()). */ 157 void pop_front(); 158 159 /** Equivalent to erase(boost::prior(end())). */ 160 void pop_back(); 161 162 /** Reverses the order of direct children in the property tree. */ 163 void reverse(); 164 165 /** Sorts the direct children of this node according to the predicate. 166 * The predicate is passed the whole pair of key and child. 167 */ 168 template<class Compare> void sort(Compare comp); 169 170 /** Sorts the direct children of this node according to key order. */ 171 void sort(); 172 173 // Equality 174 175 /** Two property trees are the same if they have the same data, the keys 176 * and order of their children are the same, and the children compare 177 * equal, recursively. 178 */ 179 bool operator ==(const self_type &rhs) const; 180 bool operator !=(const self_type &rhs) const; 181 182 // Associative view 183 184 /** Returns an iterator to the first child, in key order. */ 185 assoc_iterator ordered_begin(); 186 /** Returns an iterator to the first child, in key order. */ 187 const_assoc_iterator ordered_begin() const; 188 189 /** Returns the not-found iterator. Equivalent to end() in a real 190 * associative container. 191 */ 192 assoc_iterator not_found(); 193 /** Returns the not-found iterator. Equivalent to end() in a real 194 * associative container. 195 */ 196 const_assoc_iterator not_found() const; 197 198 /** Find a child with the given key, or not_found() if there is none. 199 * There is no guarantee about which child is returned if multiple have 200 * the same key. 201 */ 202 assoc_iterator find(const key_type &key); 203 204 /** Find a child with the given key, or not_found() if there is none. 205 * There is no guarantee about which child is returned if multiple have 206 * the same key. 207 */ 208 const_assoc_iterator find(const key_type &key) const; 209 210 /** Find the range of children that have the given key. */ 211 std::pair<assoc_iterator, assoc_iterator> 212 equal_range(const key_type &key); 213 214 /** Find the range of children that have the given key. */ 215 std::pair<const_assoc_iterator, const_assoc_iterator> 216 equal_range(const key_type &key) const; 217 218 /** Count the number of direct children with the given key. */ 219 size_type count(const key_type &key) const; 220 221 /** Erase all direct children with the given key and return the count. 222 */ 223 size_type erase(const key_type &key); 224 225 /** Get the iterator that points to the same element as the argument. 226 * @note A valid assoc_iterator range (a, b) does not imply that 227 * (to_iterator(a), to_iterator(b)) is a valid range. 228 */ 229 iterator to_iterator(assoc_iterator it); 230 231 /** Get the iterator that points to the same element as the argument. 232 * @note A valid const_assoc_iterator range (a, b) does not imply that 233 * (to_iterator(a), to_iterator(b)) is a valid range. 234 */ 235 const_iterator to_iterator(const_assoc_iterator it) const; 236 237 // Property tree view 238 239 /** Reference to the actual data in this node. */ 240 data_type &data(); 241 242 /** Reference to the actual data in this node. */ 243 const data_type &data() const; 244 245 /** Clear this tree completely, of both data and children. */ 246 void clear(); 247 248 /** Get the child at the given path, or throw @c ptree_bad_path. 249 * @note Depending on the path, the result at each level may not be 250 * completely deterministic, i.e. if the same key appears multiple 251 * times, which child is chosen is not specified. This can lead 252 * to the path not being resolved even though there is a 253 * descendant with this path. Example: 254 * @code 255 * a -> b -> c 256 * -> b 257 * @endcode 258 * The path "a.b.c" will succeed if the resolution of "b" chooses 259 * the first such node, but fail if it chooses the second. 260 */ 261 self_type &get_child(const path_type &path); 262 263 /** Get the child at the given path, or throw @c ptree_bad_path. */ 264 const self_type &get_child(const path_type &path) const; 265 266 /** Get the child at the given path, or return @p default_value. */ 267 self_type &get_child(const path_type &path, self_type &default_value); 268 269 /** Get the child at the given path, or return @p default_value. */ 270 const self_type &get_child(const path_type &path, 271 const self_type &default_value) const; 272 273 /** Get the child at the given path, or return boost::null. */ 274 optional<self_type &> get_child_optional(const path_type &path); 275 276 /** Get the child at the given path, or return boost::null. */ 277 optional<const self_type &> 278 get_child_optional(const path_type &path) const; 279 280 /** Set the node at the given path to the given value. Create any 281 * missing parents. If the node at the path already exists, replace it. 282 * @return A reference to the inserted subtree. 283 * @note Because of the way paths work, it is not generally guaranteed 284 * that a node newly created can be accessed using the same path. 285 * @note If the path could refer to multiple nodes, it is unspecified 286 * which one gets replaced. 287 */ 288 self_type &put_child(const path_type &path, const self_type &value); 289 290 /** Add the node at the given path. Create any missing parents. If there 291 * already is a node at the path, add another one with the same key. 292 * @param path Path to the child. The last fragment must not have an 293 * index. 294 * @return A reference to the inserted subtree. 295 * @note Because of the way paths work, it is not generally guaranteed 296 * that a node newly created can be accessed using the same path. 297 */ 298 self_type &add_child(const path_type &path, const self_type &value); 299 300 /** Take the value of this node and attempt to translate it to a 301 * @c Type object using the supplied translator. 302 * @throw ptree_bad_data if the conversion fails. 303 */ 304 template<class Type, class Translator> 305 typename boost::enable_if<detail::is_translator<Translator>, Type>::type 306 get_value(Translator tr) const; 307 308 /** Take the value of this node and attempt to translate it to a 309 * @c Type object using the default translator. 310 * @throw ptree_bad_data if the conversion fails. 311 */ 312 template<class Type> 313 Type get_value() const; 314 315 /** Take the value of this node and attempt to translate it to a 316 * @c Type object using the supplied translator. Return @p default_value 317 * if this fails. 318 */ 319 template<class Type, class Translator> 320 Type get_value(const Type &default_value, Translator tr) const; 321 322 /** Make get_value do the right thing for string literals. */ 323 template <class Ch, class Translator> 324 typename boost::enable_if< 325 detail::is_character<Ch>, 326 std::basic_string<Ch> 327 >::type 328 get_value(const Ch *default_value, Translator tr) const; 329 330 /** Take the value of this node and attempt to translate it to a 331 * @c Type object using the default translator. Return @p default_value 332 * if this fails. 333 */ 334 template<class Type> 335 typename boost::disable_if<detail::is_translator<Type>, Type>::type 336 get_value(const Type &default_value) const; 337 338 /** Make get_value do the right thing for string literals. */ 339 template <class Ch> 340 typename boost::enable_if< 341 detail::is_character<Ch>, 342 std::basic_string<Ch> 343 >::type 344 get_value(const Ch *default_value) const; 345 346 /** Take the value of this node and attempt to translate it to a 347 * @c Type object using the supplied translator. Return boost::null if 348 * this fails. 349 */ 350 template<class Type, class Translator> 351 optional<Type> get_value_optional(Translator tr) const; 352 353 /** Take the value of this node and attempt to translate it to a 354 * @c Type object using the default translator. Return boost::null if 355 * this fails. 356 */ 357 template<class Type> 358 optional<Type> get_value_optional() const; 359 360 /** Replace the value at this node with the given value, translated 361 * to the tree's data type using the supplied translator. 362 * @throw ptree_bad_data if the conversion fails. 363 */ 364 template<class Type, class Translator> 365 void put_value(const Type &value, Translator tr); 366 367 /** Replace the value at this node with the given value, translated 368 * to the tree's data type using the default translator. 369 * @throw ptree_bad_data if the conversion fails. 370 */ 371 template<class Type> 372 void put_value(const Type &value); 373 374 /** Shorthand for get_child(path).get_value(tr). */ 375 template<class Type, class Translator> 376 typename boost::enable_if<detail::is_translator<Translator>, Type>::type 377 get(const path_type &path, Translator tr) const; 378 379 /** Shorthand for get_child(path).get_value\<Type\>(). */ 380 template<class Type> 381 Type get(const path_type &path) const; 382 383 /** Shorthand for get_child(path, empty_ptree()) 384 * .get_value(default_value, tr). 385 * That is, return the translated value if possible, and the default 386 * value if the node doesn't exist or conversion fails. 387 */ 388 template<class Type, class Translator> 389 Type get(const path_type &path, 390 const Type &default_value, 391 Translator tr) const; 392 393 /** Make get do the right thing for string literals. */ 394 template <class Ch, class Translator> 395 typename boost::enable_if< 396 detail::is_character<Ch>, 397 std::basic_string<Ch> 398 >::type 399 get(const path_type &path, const Ch *default_value, Translator tr)const; 400 401 /** Shorthand for get_child(path, empty_ptree()) 402 * .get_value(default_value). 403 * That is, return the translated value if possible, and the default 404 * value if the node doesn't exist or conversion fails. 405 */ 406 template<class Type> 407 typename boost::disable_if<detail::is_translator<Type>, Type>::type 408 get(const path_type &path, const Type &default_value) const; 409 410 /** Make get do the right thing for string literals. */ 411 template <class Ch> 412 typename boost::enable_if< 413 detail::is_character<Ch>, 414 std::basic_string<Ch> 415 >::type 416 get(const path_type &path, const Ch *default_value) const; 417 418 /** Shorthand for: 419 * @code 420 * if(optional\<self_type&\> node = get_child_optional(path)) 421 * return node->get_value_optional(tr); 422 * return boost::null; 423 * @endcode 424 * That is, return the value if it exists and can be converted, or nil. 425 */ 426 template<class Type, class Translator> 427 optional<Type> get_optional(const path_type &path, Translator tr) const; 428 429 /** Shorthand for: 430 * @code 431 * if(optional\<const self_type&\> node = get_child_optional(path)) 432 * return node->get_value_optional(); 433 * return boost::null; 434 * @endcode 435 * That is, return the value if it exists and can be converted, or nil. 436 */ 437 template<class Type> 438 optional<Type> get_optional(const path_type &path) const; 439 440 /** Set the value of the node at the given path to the supplied value, 441 * translated to the tree's data type. If the node doesn't exist, it is 442 * created, including all its missing parents. 443 * @return The node that had its value changed. 444 * @throw ptree_bad_data if the conversion fails. 445 */ 446 template<class Type, class Translator> 447 self_type &put(const path_type &path, const Type &value, Translator tr); 448 449 /** Set the value of the node at the given path to the supplied value, 450 * translated to the tree's data type. If the node doesn't exist, it is 451 * created, including all its missing parents. 452 * @return The node that had its value changed. 453 * @throw ptree_bad_data if the conversion fails. 454 */ 455 template<class Type> 456 self_type &put(const path_type &path, const Type &value); 457 458 /** If the node identified by the path does not exist, create it, 459 * including all its missing parents. 460 * If the node already exists, add a sibling with the same key. 461 * Set the newly created node's value to the given paremeter, 462 * translated with the supplied translator. 463 * @param path Path to the child. The last fragment must not have an 464 * index. 465 * @param value The value to add. 466 * @param tr The translator to use. 467 * @return The node that was added. 468 * @throw ptree_bad_data if the conversion fails. 469 */ 470 template<class Type, class Translator> 471 self_type &add(const path_type &path, 472 const Type &value, 473 Translator tr); 474 475 /** If the node identified by the path does not exist, create it, 476 * including all its missing parents. 477 * If the node already exists, add a sibling with the same key. 478 * Set the newly created node's value to the given paremeter, 479 * translated with the supplied translator. 480 * @param path Path to the child. The last fragment must not have an 481 * index. 482 * @param value The value to add. 483 * @return The node that was added. 484 * @throw ptree_bad_data if the conversion fails. 485 */ 486 template<class Type> 487 self_type &add(const path_type &path, const Type &value); 488 489 private: 490 // Hold the data of this node 491 data_type m_data; 492 // Hold the children - this is a void* because we can't complete the 493 // container type within the class. 494 void* m_children; 495 496 // Getter tree-walk. Not const-safe! Gets the node the path refers to, 497 // or null. Destroys p's value. 498 self_type* walk_path(path_type& p) const; 499 500 // Modifer tree-walk. Gets the parent of the node referred to by the 501 // path, creating nodes as necessary. p is the path to the remaining 502 // child. 503 self_type& force_path(path_type& p); 504 505 // This struct contains typedefs for the concrete types. 506 struct subs; 507 friend struct subs; 508 friend class iterator; 509 friend class const_iterator; 510 friend class reverse_iterator; 511 friend class const_reverse_iterator; 512 }; 513 514 }} 515 516 #include <boost/property_tree/detail/ptree_implementation.hpp> 517 518 #endif 519