ptree.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  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/core/enable_if.hpp>
  24. #include <boost/throw_exception.hpp>
  25. #include <boost/optional/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. /** Prevents calls to get_child with temporary default values */
  223. void get_child(const path_type &path,
  224. const self_type &&default_value) const = delete;
  225. /** Get the child at the given path, or return boost::null. */
  226. optional<self_type &> get_child_optional(const path_type &path);
  227. /** Get the child at the given path, or return boost::null. */
  228. optional<const self_type &>
  229. get_child_optional(const path_type &path) const;
  230. /** Set the node at the given path to the given value. Create any
  231. * missing parents. If the node at the path already exists, replace it.
  232. * @return A reference to the inserted subtree.
  233. * @note Because of the way paths work, it is not generally guaranteed
  234. * that a node newly created can be accessed using the same path.
  235. * @note If the path could refer to multiple nodes, it is unspecified
  236. * which one gets replaced.
  237. */
  238. self_type &put_child(const path_type &path, const self_type &value);
  239. /** Add the node at the given path. Create any missing parents. If there
  240. * already is a node at the path, add another one with the same key.
  241. * @param path Path to the child. The last fragment must not have an
  242. * index.
  243. * @return A reference to the inserted subtree.
  244. * @note Because of the way paths work, it is not generally guaranteed
  245. * that a node newly created can be accessed using the same path.
  246. */
  247. self_type &add_child(const path_type &path, const self_type &value);
  248. /** Take the value of this node and attempt to translate it to a
  249. * @c Type object using the supplied translator.
  250. * @throw ptree_bad_data if the conversion fails.
  251. */
  252. template<class Type, class Translator>
  253. typename boost::enable_if<detail::is_translator<Translator>, Type>::type
  254. get_value(Translator tr) const;
  255. /** Take the value of this node and attempt to translate it to a
  256. * @c Type object using the default translator.
  257. * @throw ptree_bad_data if the conversion fails.
  258. */
  259. template<class Type>
  260. Type get_value() const;
  261. /** Take the value of this node and attempt to translate it to a
  262. * @c Type object using the supplied translator. Return @p default_value
  263. * if this fails.
  264. */
  265. template<class Type, class Translator>
  266. Type get_value(const Type &default_value, Translator tr) const;
  267. /** Make get_value do the right thing for string literals. */
  268. template <class Ch, class Translator>
  269. typename boost::enable_if<
  270. detail::is_character<Ch>,
  271. std::basic_string<Ch>
  272. >::type
  273. get_value(const Ch *default_value, Translator tr) const;
  274. /** Take the value of this node and attempt to translate it to a
  275. * @c Type object using the default translator. Return @p default_value
  276. * if this fails.
  277. */
  278. template<class Type>
  279. typename boost::disable_if<detail::is_translator<Type>, Type>::type
  280. get_value(const Type &default_value) const;
  281. /** Make get_value do the right thing for string literals. */
  282. template <class Ch>
  283. typename boost::enable_if<
  284. detail::is_character<Ch>,
  285. std::basic_string<Ch>
  286. >::type
  287. get_value(const Ch *default_value) const;
  288. /** Take the value of this node and attempt to translate it to a
  289. * @c Type object using the supplied translator. Return boost::null if
  290. * this fails.
  291. */
  292. template<class Type, class Translator>
  293. optional<Type> get_value_optional(Translator tr) const;
  294. /** Take the value of this node and attempt to translate it to a
  295. * @c Type object using the default translator. Return boost::null if
  296. * this fails.
  297. */
  298. template<class Type>
  299. optional<Type> get_value_optional() const;
  300. /** Replace the value at this node with the given value, translated
  301. * to the tree's data type using the supplied translator.
  302. * @throw ptree_bad_data if the conversion fails.
  303. */
  304. template<class Type, class Translator>
  305. void put_value(const Type &value, Translator tr);
  306. /** Replace the value at this node with the given value, translated
  307. * to the tree's data type using the default translator.
  308. * @throw ptree_bad_data if the conversion fails.
  309. */
  310. template<class Type>
  311. void put_value(const Type &value);
  312. /** Shorthand for get_child(path).get_value(tr). */
  313. template<class Type, class Translator>
  314. typename boost::enable_if<detail::is_translator<Translator>, Type>::type
  315. get(const path_type &path, Translator tr) const;
  316. /** Shorthand for get_child(path).get_value\<Type\>(). */
  317. template<class Type>
  318. Type get(const path_type &path) const;
  319. /** Shorthand for get_child(path, empty_ptree())
  320. * .get_value(default_value, tr).
  321. * That is, return the translated value if possible, and the default
  322. * value if the node doesn't exist or conversion fails.
  323. */
  324. template<class Type, class Translator>
  325. Type get(const path_type &path,
  326. const Type &default_value,
  327. Translator tr) const;
  328. /** Make get do the right thing for string literals. */
  329. template <class Ch, class Translator>
  330. typename boost::enable_if<
  331. detail::is_character<Ch>,
  332. std::basic_string<Ch>
  333. >::type
  334. get(const path_type &path, const Ch *default_value, Translator tr)const;
  335. /** Shorthand for get_child(path, empty_ptree())
  336. * .get_value(default_value).
  337. * That is, return the translated value if possible, and the default
  338. * value if the node doesn't exist or conversion fails.
  339. */
  340. template<class Type>
  341. typename boost::disable_if<detail::is_translator<Type>, Type>::type
  342. get(const path_type &path, const Type &default_value) const;
  343. /** Make get do the right thing for string literals. */
  344. template <class Ch>
  345. typename boost::enable_if<
  346. detail::is_character<Ch>,
  347. std::basic_string<Ch>
  348. >::type
  349. get(const path_type &path, const Ch *default_value) const;
  350. /** Shorthand for:
  351. * @code
  352. * if(optional\<self_type&\> node = get_child_optional(path))
  353. * return node->get_value_optional(tr);
  354. * return boost::null;
  355. * @endcode
  356. * That is, return the value if it exists and can be converted, or nil.
  357. */
  358. template<class Type, class Translator>
  359. optional<Type> get_optional(const path_type &path, Translator tr) const;
  360. /** Shorthand for:
  361. * @code
  362. * if(optional\<const self_type&\> node = get_child_optional(path))
  363. * return node->get_value_optional();
  364. * return boost::null;
  365. * @endcode
  366. * That is, return the value if it exists and can be converted, or nil.
  367. */
  368. template<class Type>
  369. optional<Type> get_optional(const path_type &path) const;
  370. /** Set the value of the node at the given path to the supplied value,
  371. * translated to the tree's data type. If the node doesn't exist, it is
  372. * created, including all its missing parents.
  373. * @return The node that had its value changed.
  374. * @throw ptree_bad_data if the conversion fails.
  375. */
  376. template<class Type, class Translator>
  377. self_type &put(const path_type &path, const Type &value, Translator tr);
  378. /** Set the value of the node at the given path to the supplied value,
  379. * translated to the tree's data type. If the node doesn't exist, it is
  380. * created, including all its missing parents.
  381. * @return The node that had its value changed.
  382. * @throw ptree_bad_data if the conversion fails.
  383. */
  384. template<class Type>
  385. self_type &put(const path_type &path, const Type &value);
  386. /** If the node identified by the path does not exist, create it,
  387. * including all its missing parents.
  388. * If the node already exists, add a sibling with the same key.
  389. * Set the newly created node's value to the given paremeter,
  390. * translated with the supplied translator.
  391. * @param path Path to the child. The last fragment must not have an
  392. * index.
  393. * @param value The value to add.
  394. * @param tr The translator to use.
  395. * @return The node that was added.
  396. * @throw ptree_bad_data if the conversion fails.
  397. */
  398. template<class Type, class Translator>
  399. self_type &add(const path_type &path,
  400. const Type &value,
  401. Translator tr);
  402. /** If the node identified by the path does not exist, create it,
  403. * including all its missing parents.
  404. * If the node already exists, add a sibling with the same key.
  405. * Set the newly created node's value to the given paremeter,
  406. * translated with the supplied translator.
  407. * @param path Path to the child. The last fragment must not have an
  408. * index.
  409. * @param value The value to add.
  410. * @return The node that was added.
  411. * @throw ptree_bad_data if the conversion fails.
  412. */
  413. template<class Type>
  414. self_type &add(const path_type &path, const Type &value);
  415. private:
  416. // Hold the data of this node
  417. data_type m_data;
  418. // Hold the children - this is a void* because we can't complete the
  419. // container type within the class.
  420. void* m_children;
  421. // Getter tree-walk. Not const-safe! Gets the node the path refers to,
  422. // or null. Destroys p's value.
  423. self_type* walk_path(path_type& p) const;
  424. // Modifer tree-walk. Gets the parent of the node referred to by the
  425. // path, creating nodes as necessary. p is the path to the remaining
  426. // child.
  427. self_type& force_path(path_type& p);
  428. // This struct contains typedefs for the concrete types.
  429. struct subs;
  430. friend struct subs;
  431. friend class iterator;
  432. friend class const_iterator;
  433. friend class reverse_iterator;
  434. friend class const_reverse_iterator;
  435. };
  436. }}
  437. #include <boost/property_tree/detail/ptree_implementation.hpp>
  438. #endif