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