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/core/enable_if.hpp>
27#include <boost/throw_exception.hpp>
28#include <boost/optional/optional.hpp>
29#include <utility> // for std::pair
30
31namespace 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 /** Prevents calls to get_child with temporary default values */
274 void get_child(const path_type &path,
275 const self_type &&default_value) const = delete;
276
277 /** Get the child at the given path, or return boost::null. */
278 optional<self_type &> get_child_optional(const path_type &path);
279
280 /** Get the child at the given path, or return boost::null. */
281 optional<const self_type &>
282 get_child_optional(const path_type &path) const;
283
284 /** Set the node at the given path to the given value. Create any
285 * missing parents. If the node at the path already exists, replace it.
286 * @return A reference to the inserted subtree.
287 * @note Because of the way paths work, it is not generally guaranteed
288 * that a node newly created can be accessed using the same path.
289 * @note If the path could refer to multiple nodes, it is unspecified
290 * which one gets replaced.
291 */
292 self_type &put_child(const path_type &path, const self_type &value);
293
294 /** Add the node at the given path. Create any missing parents. If there
295 * already is a node at the path, add another one with the same key.
296 * @param path Path to the child. The last fragment must not have an
297 * index.
298 * @return A reference to the inserted subtree.
299 * @note Because of the way paths work, it is not generally guaranteed
300 * that a node newly created can be accessed using the same path.
301 */
302 self_type &add_child(const path_type &path, const self_type &value);
303
304 /** Take the value of this node and attempt to translate it to a
305 * @c Type object using the supplied translator.
306 * @throw ptree_bad_data if the conversion fails.
307 */
308 template<class Type, class Translator>
309 typename boost::enable_if<detail::is_translator<Translator>, Type>::type
310 get_value(Translator tr) const;
311
312 /** Take the value of this node and attempt to translate it to a
313 * @c Type object using the default translator.
314 * @throw ptree_bad_data if the conversion fails.
315 */
316 template<class Type>
317 Type get_value() const;
318
319 /** Take the value of this node and attempt to translate it to a
320 * @c Type object using the supplied translator. Return @p default_value
321 * if this fails.
322 */
323 template<class Type, class Translator>
324 Type get_value(const Type &default_value, Translator tr) const;
325
326 /** Make get_value do the right thing for string literals. */
327 template <class Ch, class Translator>
328 typename boost::enable_if<
329 detail::is_character<Ch>,
330 std::basic_string<Ch>
331 >::type
332 get_value(const Ch *default_value, Translator tr) const;
333
334 /** Take the value of this node and attempt to translate it to a
335 * @c Type object using the default translator. Return @p default_value
336 * if this fails.
337 */
338 template<class Type>
339 typename boost::disable_if<detail::is_translator<Type>, Type>::type
340 get_value(const Type &default_value) const;
341
342 /** Make get_value do the right thing for string literals. */
343 template <class Ch>
344 typename boost::enable_if<
345 detail::is_character<Ch>,
346 std::basic_string<Ch>
347 >::type
348 get_value(const Ch *default_value) const;
349
350 /** Take the value of this node and attempt to translate it to a
351 * @c Type object using the supplied translator. Return boost::null if
352 * this fails.
353 */
354 template<class Type, class Translator>
355 optional<Type> get_value_optional(Translator tr) const;
356
357 /** Take the value of this node and attempt to translate it to a
358 * @c Type object using the default translator. Return boost::null if
359 * this fails.
360 */
361 template<class Type>
362 optional<Type> get_value_optional() const;
363
364 /** Replace the value at this node with the given value, translated
365 * to the tree's data type using the supplied translator.
366 * @throw ptree_bad_data if the conversion fails.
367 */
368 template<class Type, class Translator>
369 void put_value(const Type &value, Translator tr);
370
371 /** Replace the value at this node with the given value, translated
372 * to the tree's data type using the default translator.
373 * @throw ptree_bad_data if the conversion fails.
374 */
375 template<class Type>
376 void put_value(const Type &value);
377
378 /** Shorthand for get_child(path).get_value(tr). */
379 template<class Type, class Translator>
380 typename boost::enable_if<detail::is_translator<Translator>, Type>::type
381 get(const path_type &path, Translator tr) const;
382
383 /** Shorthand for get_child(path).get_value\<Type\>(). */
384 template<class Type>
385 Type get(const path_type &path) const;
386
387 /** Shorthand for get_child(path, empty_ptree())
388 * .get_value(default_value, tr).
389 * That is, return the translated value if possible, and the default
390 * value if the node doesn't exist or conversion fails.
391 */
392 template<class Type, class Translator>
393 Type get(const path_type &path,
394 const Type &default_value,
395 Translator tr) const;
396
397 /** Make get do the right thing for string literals. */
398 template <class Ch, class Translator>
399 typename boost::enable_if<
400 detail::is_character<Ch>,
401 std::basic_string<Ch>
402 >::type
403 get(const path_type &path, const Ch *default_value, Translator tr)const;
404
405 /** Shorthand for get_child(path, empty_ptree())
406 * .get_value(default_value).
407 * That is, return the translated value if possible, and the default
408 * value if the node doesn't exist or conversion fails.
409 */
410 template<class Type>
411 typename boost::disable_if<detail::is_translator<Type>, Type>::type
412 get(const path_type &path, const Type &default_value) const;
413
414 /** Make get do the right thing for string literals. */
415 template <class Ch>
416 typename boost::enable_if<
417 detail::is_character<Ch>,
418 std::basic_string<Ch>
419 >::type
420 get(const path_type &path, const Ch *default_value) const;
421
422 /** Shorthand for:
423 * @code
424 * if(optional\<self_type&\> node = get_child_optional(path))
425 * return node->get_value_optional(tr);
426 * return boost::null;
427 * @endcode
428 * That is, return the value if it exists and can be converted, or nil.
429 */
430 template<class Type, class Translator>
431 optional<Type> get_optional(const path_type &path, Translator tr) const;
432
433 /** Shorthand for:
434 * @code
435 * if(optional\<const self_type&\> node = get_child_optional(path))
436 * return node->get_value_optional();
437 * return boost::null;
438 * @endcode
439 * That is, return the value if it exists and can be converted, or nil.
440 */
441 template<class Type>
442 optional<Type> get_optional(const path_type &path) const;
443
444 /** Set the value of the node at the given path to the supplied value,
445 * translated to the tree's data type. If the node doesn't exist, it is
446 * created, including all its missing parents.
447 * @return The node that had its value changed.
448 * @throw ptree_bad_data if the conversion fails.
449 */
450 template<class Type, class Translator>
451 self_type &put(const path_type &path, const Type &value, Translator tr);
452
453 /** Set the value of the node at the given path to the supplied value,
454 * translated to the tree's data type. If the node doesn't exist, it is
455 * created, including all its missing parents.
456 * @return The node that had its value changed.
457 * @throw ptree_bad_data if the conversion fails.
458 */
459 template<class Type>
460 self_type &put(const path_type &path, const Type &value);
461
462 /** If the node identified by the path does not exist, create it,
463 * including all its missing parents.
464 * If the node already exists, add a sibling with the same key.
465 * Set the newly created node's value to the given paremeter,
466 * translated with the supplied translator.
467 * @param path Path to the child. The last fragment must not have an
468 * index.
469 * @param value The value to add.
470 * @param tr The translator to use.
471 * @return The node that was added.
472 * @throw ptree_bad_data if the conversion fails.
473 */
474 template<class Type, class Translator>
475 self_type &add(const path_type &path,
476 const Type &value,
477 Translator tr);
478
479 /** If the node identified by the path does not exist, create it,
480 * including all its missing parents.
481 * If the node already exists, add a sibling with the same key.
482 * Set the newly created node's value to the given paremeter,
483 * translated with the supplied translator.
484 * @param path Path to the child. The last fragment must not have an
485 * index.
486 * @param value The value to add.
487 * @return The node that was added.
488 * @throw ptree_bad_data if the conversion fails.
489 */
490 template<class Type>
491 self_type &add(const path_type &path, const Type &value);
492
493 private:
494 // Hold the data of this node
495 data_type m_data;
496 // Hold the children - this is a void* because we can't complete the
497 // container type within the class.
498 void* m_children;
499
500 // Getter tree-walk. Not const-safe! Gets the node the path refers to,
501 // or null. Destroys p's value.
502 self_type* walk_path(path_type& p) const;
503
504 // Modifer tree-walk. Gets the parent of the node referred to by the
505 // path, creating nodes as necessary. p is the path to the remaining
506 // child.
507 self_type& force_path(path_type& p);
508
509 // This struct contains typedefs for the concrete types.
510 struct subs;
511 friend struct subs;
512 friend class iterator;
513 friend class const_iterator;
514 friend class reverse_iterator;
515 friend class const_reverse_iterator;
516 };
517
518}}
519
520#include <boost/property_tree/detail/ptree_implementation.hpp>
521
522#endif
523

source code of boost/libs/property_tree/include/boost/property_tree/ptree.hpp