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
|