annotate DEPENDENCIES/generic/include/boost/property_tree/ptree.hpp @ 125:34e428693f5d vext

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