ptree.hpp 20 KB

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