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 | |
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 | /** 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 | |