File indexing completed on 2025-06-30 08:29:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
0012 #define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
0013
0014 #include <boost/property_tree/ptree.hpp>
0015 #include <boost/iterator/iterator_adaptor.hpp>
0016 #include <boost/iterator/reverse_iterator.hpp>
0017 #include <boost/assert.hpp>
0018 #include <boost/core/invoke_swap.hpp>
0019 #include <boost/core/type_name.hpp>
0020 #include <memory>
0021
0022 #if (defined(BOOST_MSVC) && \
0023 (_MSC_FULL_VER >= 160000000 && _MSC_FULL_VER < 170000000)) || \
0024 (defined(BOOST_INTEL_WIN) && \
0025 defined(BOOST_DINKUMWARE_STDLIB))
0026 #define BOOST_PROPERTY_TREE_PAIR_BUG
0027 #endif
0028
0029 namespace boost { namespace property_tree
0030 {
0031 template <class K, class D, class C>
0032 struct basic_ptree<K, D, C>::subs
0033 {
0034 struct by_name {};
0035
0036 #if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
0037
0038
0039 BOOST_STATIC_CONSTANT(unsigned,
0040 first_offset = offsetof(value_type, first));
0041 #endif
0042 typedef multi_index_container<value_type,
0043 multi_index::indexed_by<
0044 multi_index::sequenced<>,
0045 multi_index::ordered_non_unique<multi_index::tag<by_name>,
0046 #if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
0047 multi_index::member_offset<value_type, const key_type,
0048 first_offset>,
0049 #else
0050 multi_index::member<value_type, const key_type,
0051 &value_type::first>,
0052 #endif
0053 key_compare
0054 >
0055 >
0056 > base_container;
0057
0058
0059 typedef typename base_container::template index<by_name>::type
0060 by_name_index;
0061
0062
0063 static base_container& ch(self_type *s) {
0064 return *static_cast<base_container*>(s->m_children);
0065 }
0066 static const base_container& ch(const self_type *s) {
0067 return *static_cast<const base_container*>(s->m_children);
0068 }
0069 static by_name_index& assoc(self_type *s) {
0070 return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
0071 }
0072 static const by_name_index& assoc(const self_type *s) {
0073 return ch(s).BOOST_NESTED_TEMPLATE get<by_name>();
0074 }
0075 };
0076 template <class K, class D, class C>
0077 class basic_ptree<K, D, C>::iterator : public boost::iterator_adaptor<
0078 iterator, typename subs::base_container::iterator, value_type>
0079 {
0080 friend class boost::iterator_core_access;
0081 typedef boost::iterator_adaptor<
0082 iterator, typename subs::base_container::iterator, value_type>
0083 baset;
0084 public:
0085 typedef typename baset::reference reference;
0086 iterator() {}
0087 explicit iterator(typename iterator::base_type b)
0088 : iterator::iterator_adaptor_(b)
0089 {}
0090 reference dereference() const
0091 {
0092
0093
0094
0095
0096 return const_cast<reference>(*this->base_reference());
0097 }
0098 };
0099 template <class K, class D, class C>
0100 class basic_ptree<K, D, C>::const_iterator : public boost::iterator_adaptor<
0101 const_iterator, typename subs::base_container::const_iterator>
0102 {
0103 public:
0104 const_iterator() {}
0105 explicit const_iterator(typename const_iterator::base_type b)
0106 : const_iterator::iterator_adaptor_(b)
0107 {}
0108 const_iterator(iterator b)
0109 : const_iterator::iterator_adaptor_(b.base())
0110 {}
0111 };
0112 template <class K, class D, class C>
0113 class basic_ptree<K, D, C>::reverse_iterator
0114 : public boost::reverse_iterator<iterator>
0115 {
0116 public:
0117 reverse_iterator() {}
0118 explicit reverse_iterator(iterator b)
0119 : boost::reverse_iterator<iterator>(b)
0120 {}
0121 };
0122 template <class K, class D, class C>
0123 class basic_ptree<K, D, C>::const_reverse_iterator
0124 : public boost::reverse_iterator<const_iterator>
0125 {
0126 public:
0127 const_reverse_iterator() {}
0128 explicit const_reverse_iterator(const_iterator b)
0129 : boost::reverse_iterator<const_iterator>(b)
0130 {}
0131 const_reverse_iterator(
0132 typename basic_ptree<K, D, C>::reverse_iterator b)
0133 : boost::reverse_iterator<const_iterator>(b)
0134 {}
0135 };
0136 template <class K, class D, class C>
0137 class basic_ptree<K, D, C>::assoc_iterator
0138 : public boost::iterator_adaptor<assoc_iterator,
0139 typename subs::by_name_index::iterator,
0140 value_type>
0141 {
0142 friend class boost::iterator_core_access;
0143 typedef boost::iterator_adaptor<assoc_iterator,
0144 typename subs::by_name_index::iterator,
0145 value_type>
0146 baset;
0147 public:
0148 typedef typename baset::reference reference;
0149 assoc_iterator() {}
0150 explicit assoc_iterator(typename assoc_iterator::base_type b)
0151 : assoc_iterator::iterator_adaptor_(b)
0152 {}
0153 reference dereference() const
0154 {
0155 return const_cast<reference>(*this->base_reference());
0156 }
0157 };
0158 template <class K, class D, class C>
0159 class basic_ptree<K, D, C>::const_assoc_iterator
0160 : public boost::iterator_adaptor<const_assoc_iterator,
0161 typename subs::by_name_index::const_iterator>
0162 {
0163 public:
0164 const_assoc_iterator() {}
0165 explicit const_assoc_iterator(
0166 typename const_assoc_iterator::base_type b)
0167 : const_assoc_iterator::iterator_adaptor_(b)
0168 {}
0169 const_assoc_iterator(assoc_iterator b)
0170 : const_assoc_iterator::iterator_adaptor_(b.base())
0171 {}
0172 };
0173
0174
0175
0176
0177
0178
0179
0180 template<class K, class D, class C> inline
0181 basic_ptree<K, D, C>::basic_ptree()
0182 : m_children(new typename subs::base_container)
0183 {
0184 }
0185
0186 template<class K, class D, class C> inline
0187 basic_ptree<K, D, C>::basic_ptree(const data_type &d)
0188 : m_data(d), m_children(new typename subs::base_container)
0189 {
0190 }
0191
0192 template<class K, class D, class C> inline
0193 basic_ptree<K, D, C>::basic_ptree(const basic_ptree<K, D, C> &rhs)
0194 : m_data(rhs.m_data),
0195 m_children(new typename subs::base_container(subs::ch(&rhs)))
0196 {
0197 }
0198
0199 template<class K, class D, class C>
0200 basic_ptree<K, D, C> &
0201 basic_ptree<K, D, C>::operator =(const basic_ptree<K, D, C> &rhs)
0202 {
0203 self_type(rhs).swap(*this);
0204 return *this;
0205 }
0206
0207 template<class K, class D, class C>
0208 basic_ptree<K, D, C>::~basic_ptree()
0209 {
0210 delete &subs::ch(this);
0211 }
0212
0213 template<class K, class D, class C> inline
0214 void basic_ptree<K, D, C>::swap(basic_ptree<K, D, C> &rhs)
0215 {
0216 boost::core::invoke_swap(m_data, rhs.m_data);
0217
0218 std::swap(m_children, rhs.m_children);
0219 }
0220
0221
0222
0223 template<class K, class D, class C> inline
0224 typename basic_ptree<K, D, C>::size_type
0225 basic_ptree<K, D, C>::size() const
0226 {
0227 return subs::ch(this).size();
0228 }
0229
0230 template<class K, class D, class C> inline
0231 typename basic_ptree<K, D, C>::size_type
0232 basic_ptree<K, D, C>::max_size() const
0233 {
0234 return subs::ch(this).max_size();
0235 }
0236
0237 template<class K, class D, class C> inline
0238 bool basic_ptree<K, D, C>::empty() const
0239 {
0240 return subs::ch(this).empty();
0241 }
0242
0243 template<class K, class D, class C> inline
0244 typename basic_ptree<K, D, C>::iterator
0245 basic_ptree<K, D, C>::begin()
0246 {
0247 return iterator(subs::ch(this).begin());
0248 }
0249
0250 template<class K, class D, class C> inline
0251 typename basic_ptree<K, D, C>::const_iterator
0252 basic_ptree<K, D, C>::begin() const
0253 {
0254 return const_iterator(subs::ch(this).begin());
0255 }
0256
0257 template<class K, class D, class C> inline
0258 typename basic_ptree<K, D, C>::iterator
0259 basic_ptree<K, D, C>::end()
0260 {
0261 return iterator(subs::ch(this).end());
0262 }
0263
0264 template<class K, class D, class C> inline
0265 typename basic_ptree<K, D, C>::const_iterator
0266 basic_ptree<K, D, C>::end() const
0267 {
0268 return const_iterator(subs::ch(this).end());
0269 }
0270
0271 template<class K, class D, class C> inline
0272 typename basic_ptree<K, D, C>::reverse_iterator
0273 basic_ptree<K, D, C>::rbegin()
0274 {
0275 return reverse_iterator(this->end());
0276 }
0277
0278 template<class K, class D, class C> inline
0279 typename basic_ptree<K, D, C>::const_reverse_iterator
0280 basic_ptree<K, D, C>::rbegin() const
0281 {
0282 return const_reverse_iterator(this->end());
0283 }
0284
0285 template<class K, class D, class C> inline
0286 typename basic_ptree<K, D, C>::reverse_iterator
0287 basic_ptree<K, D, C>::rend()
0288 {
0289 return reverse_iterator(this->begin());
0290 }
0291
0292 template<class K, class D, class C> inline
0293 typename basic_ptree<K, D, C>::const_reverse_iterator
0294 basic_ptree<K, D, C>::rend() const
0295 {
0296 return const_reverse_iterator(this->begin());
0297 }
0298
0299 template<class K, class D, class C> inline
0300 typename basic_ptree<K, D, C>::value_type &
0301 basic_ptree<K, D, C>::front()
0302 {
0303 return const_cast<value_type&>(subs::ch(this).front());
0304 }
0305
0306 template<class K, class D, class C> inline
0307 const typename basic_ptree<K, D, C>::value_type &
0308 basic_ptree<K, D, C>::front() const
0309 {
0310 return subs::ch(this).front();
0311 }
0312
0313 template<class K, class D, class C> inline
0314 typename basic_ptree<K, D, C>::value_type &
0315 basic_ptree<K, D, C>::back()
0316 {
0317 return const_cast<value_type&>(subs::ch(this).back());
0318 }
0319
0320 template<class K, class D, class C> inline
0321 const typename basic_ptree<K, D, C>::value_type &
0322 basic_ptree<K, D, C>::back() const
0323 {
0324 return subs::ch(this).back();
0325 }
0326
0327 template<class K, class D, class C> inline
0328 typename basic_ptree<K, D, C>::iterator
0329 basic_ptree<K, D, C>::insert(iterator where, const value_type &value)
0330 {
0331 return iterator(subs::ch(this).insert(where.base(), value).first);
0332 }
0333
0334 template<class K, class D, class C>
0335 template<class It> inline
0336 void basic_ptree<K, D, C>::insert(iterator where, It first, It last)
0337 {
0338 subs::ch(this).insert(where.base(), first, last);
0339 }
0340
0341 template<class K, class D, class C> inline
0342 typename basic_ptree<K, D, C>::iterator
0343 basic_ptree<K, D, C>::erase(iterator where)
0344 {
0345 return iterator(subs::ch(this).erase(where.base()));
0346 }
0347
0348 template<class K, class D, class C> inline
0349 typename basic_ptree<K, D, C>::iterator
0350 basic_ptree<K, D, C>::erase(iterator first, iterator last)
0351 {
0352 return iterator(subs::ch(this).erase(first.base(), last.base()));
0353 }
0354
0355 template<class K, class D, class C> inline
0356 typename basic_ptree<K, D, C>::iterator
0357 basic_ptree<K, D, C>::push_front(const value_type &value)
0358 {
0359 return iterator(subs::ch(this).push_front(value).first);
0360 }
0361
0362 template<class K, class D, class C> inline
0363 typename basic_ptree<K, D, C>::iterator
0364 basic_ptree<K, D, C>::push_back(const value_type &value)
0365 {
0366 return iterator(subs::ch(this).push_back(value).first);
0367 }
0368
0369 template<class K, class D, class C> inline
0370 void basic_ptree<K, D, C>::pop_front()
0371 {
0372 subs::ch(this).pop_front();
0373 }
0374
0375 template<class K, class D, class C> inline
0376 void basic_ptree<K, D, C>::pop_back()
0377 {
0378 subs::ch(this).pop_back();
0379 }
0380
0381 template<class K, class D, class C> inline
0382 void basic_ptree<K, D, C>::reverse()
0383 {
0384 subs::ch(this).reverse();
0385 }
0386
0387 namespace impl
0388 {
0389 struct by_first
0390 {
0391 template <typename P>
0392 bool operator ()(const P& lhs, const P& rhs) const {
0393 return lhs.first < rhs.first;
0394 }
0395 };
0396
0397 template <typename C>
0398 struct equal_pred
0399 {
0400 template <typename P>
0401 bool operator ()(const P& lhs, const P& rhs) const {
0402 C c;
0403 return !c(lhs.first, rhs.first) &&
0404 !c(rhs.first, lhs.first) &&
0405 lhs.second == rhs.second;
0406 }
0407 };
0408
0409 template <typename C, typename MI>
0410 bool equal_children(const MI& ch1, const MI& ch2) {
0411
0412 return std::equal(ch1.begin(), ch1.end(),
0413 ch2.begin(), equal_pred<C>());
0414 }
0415 }
0416
0417 template<class K, class D, class C> inline
0418 void basic_ptree<K, D, C>::sort()
0419 {
0420 sort(impl::by_first());
0421 }
0422
0423 template<class K, class D, class C>
0424 template<class Compare> inline
0425 void basic_ptree<K, D, C>::sort(Compare comp)
0426 {
0427 subs::ch(this).sort(comp);
0428 }
0429
0430
0431
0432 template<class K, class D, class C> inline
0433 bool basic_ptree<K, D, C>::operator ==(
0434 const basic_ptree<K, D, C> &rhs) const
0435 {
0436
0437 return size() == rhs.size() && data() == rhs.data() &&
0438 impl::equal_children<C>(subs::ch(this), subs::ch(&rhs));
0439 }
0440
0441 template<class K, class D, class C> inline
0442 bool basic_ptree<K, D, C>::operator !=(
0443 const basic_ptree<K, D, C> &rhs) const
0444 {
0445 return !(*this == rhs);
0446 }
0447
0448
0449
0450 template<class K, class D, class C> inline
0451 typename basic_ptree<K, D, C>::assoc_iterator
0452 basic_ptree<K, D, C>::ordered_begin()
0453 {
0454 return assoc_iterator(subs::assoc(this).begin());
0455 }
0456
0457 template<class K, class D, class C> inline
0458 typename basic_ptree<K, D, C>::const_assoc_iterator
0459 basic_ptree<K, D, C>::ordered_begin() const
0460 {
0461 return const_assoc_iterator(subs::assoc(this).begin());
0462 }
0463
0464 template<class K, class D, class C> inline
0465 typename basic_ptree<K, D, C>::assoc_iterator
0466 basic_ptree<K, D, C>::not_found()
0467 {
0468 return assoc_iterator(subs::assoc(this).end());
0469 }
0470
0471 template<class K, class D, class C> inline
0472 typename basic_ptree<K, D, C>::const_assoc_iterator
0473 basic_ptree<K, D, C>::not_found() const
0474 {
0475 return const_assoc_iterator(subs::assoc(this).end());
0476 }
0477
0478 template<class K, class D, class C> inline
0479 typename basic_ptree<K, D, C>::assoc_iterator
0480 basic_ptree<K, D, C>::find(const key_type &key)
0481 {
0482 return assoc_iterator(subs::assoc(this).find(key));
0483 }
0484
0485 template<class K, class D, class C> inline
0486 typename basic_ptree<K, D, C>::const_assoc_iterator
0487 basic_ptree<K, D, C>::find(const key_type &key) const
0488 {
0489 return const_assoc_iterator(subs::assoc(this).find(key));
0490 }
0491
0492 template<class K, class D, class C> inline
0493 std::pair<
0494 typename basic_ptree<K, D, C>::assoc_iterator,
0495 typename basic_ptree<K, D, C>::assoc_iterator
0496 > basic_ptree<K, D, C>::equal_range(const key_type &key)
0497 {
0498 std::pair<typename subs::by_name_index::iterator,
0499 typename subs::by_name_index::iterator> r(
0500 subs::assoc(this).equal_range(key));
0501 return std::pair<assoc_iterator, assoc_iterator>(
0502 assoc_iterator(r.first), assoc_iterator(r.second));
0503 }
0504
0505 template<class K, class D, class C> inline
0506 std::pair<
0507 typename basic_ptree<K, D, C>::const_assoc_iterator,
0508 typename basic_ptree<K, D, C>::const_assoc_iterator
0509 > basic_ptree<K, D, C>::equal_range(const key_type &key) const
0510 {
0511 std::pair<typename subs::by_name_index::const_iterator,
0512 typename subs::by_name_index::const_iterator> r(
0513 subs::assoc(this).equal_range(key));
0514 return std::pair<const_assoc_iterator, const_assoc_iterator>(
0515 const_assoc_iterator(r.first), const_assoc_iterator(r.second));
0516 }
0517
0518 template<class K, class D, class C> inline
0519 typename basic_ptree<K, D, C>::size_type
0520 basic_ptree<K, D, C>::count(const key_type &key) const
0521 {
0522 return subs::assoc(this).count(key);
0523 }
0524
0525 template<class K, class D, class C> inline
0526 typename basic_ptree<K, D, C>::size_type
0527 basic_ptree<K, D, C>::erase(const key_type &key)
0528 {
0529 return subs::assoc(this).erase(key);
0530 }
0531
0532 template<class K, class D, class C> inline
0533 typename basic_ptree<K, D, C>::iterator
0534 basic_ptree<K, D, C>::to_iterator(assoc_iterator ai)
0535 {
0536 return iterator(subs::ch(this).
0537 BOOST_NESTED_TEMPLATE project<0>(ai.base()));
0538 }
0539
0540 template<class K, class D, class C> inline
0541 typename basic_ptree<K, D, C>::const_iterator
0542 basic_ptree<K, D, C>::to_iterator(const_assoc_iterator ai) const
0543 {
0544 return const_iterator(subs::ch(this).
0545 BOOST_NESTED_TEMPLATE project<0>(ai.base()));
0546 }
0547
0548
0549
0550 template<class K, class D, class C> inline
0551 typename basic_ptree<K, D, C>::data_type &
0552 basic_ptree<K, D, C>::data()
0553 {
0554 return m_data;
0555 }
0556
0557 template<class K, class D, class C> inline
0558 const typename basic_ptree<K, D, C>::data_type &
0559 basic_ptree<K, D, C>::data() const
0560 {
0561 return m_data;
0562 }
0563
0564 template<class K, class D, class C> inline
0565 void basic_ptree<K, D, C>::clear()
0566 {
0567 m_data = data_type();
0568 subs::ch(this).clear();
0569 }
0570
0571 template<class K, class D, class C>
0572 basic_ptree<K, D, C> &
0573 basic_ptree<K, D, C>::get_child(const path_type &path)
0574 {
0575 path_type p(path);
0576 self_type *n = walk_path(p);
0577 if (!n) {
0578 BOOST_PROPERTY_TREE_THROW(ptree_bad_path("No such node", path));
0579 }
0580 return *n;
0581 }
0582
0583 template<class K, class D, class C> inline
0584 const basic_ptree<K, D, C> &
0585 basic_ptree<K, D, C>::get_child(const path_type &path) const
0586 {
0587 return const_cast<self_type*>(this)->get_child(path);
0588 }
0589
0590 template<class K, class D, class C> inline
0591 basic_ptree<K, D, C> &
0592 basic_ptree<K, D, C>::get_child(const path_type &path,
0593 self_type &default_value)
0594 {
0595 path_type p(path);
0596 self_type *n = walk_path(p);
0597 return n ? *n : default_value;
0598 }
0599
0600 template<class K, class D, class C> inline
0601 const basic_ptree<K, D, C> &
0602 basic_ptree<K, D, C>::get_child(const path_type &path,
0603 const self_type &default_value) const
0604 {
0605 return const_cast<self_type*>(this)->get_child(path,
0606 const_cast<self_type&>(default_value));
0607 }
0608
0609
0610 template<class K, class D, class C>
0611 optional<basic_ptree<K, D, C> &>
0612 basic_ptree<K, D, C>::get_child_optional(const path_type &path)
0613 {
0614 path_type p(path);
0615 self_type *n = walk_path(p);
0616 if (!n) {
0617 return optional<self_type&>();
0618 }
0619 return *n;
0620 }
0621
0622 template<class K, class D, class C>
0623 optional<const basic_ptree<K, D, C> &>
0624 basic_ptree<K, D, C>::get_child_optional(const path_type &path) const
0625 {
0626 path_type p(path);
0627 self_type *n = walk_path(p);
0628 if (!n) {
0629 return optional<const self_type&>();
0630 }
0631 return *n;
0632 }
0633
0634 template<class K, class D, class C>
0635 basic_ptree<K, D, C> &
0636 basic_ptree<K, D, C>::put_child(const path_type &path,
0637 const self_type &value)
0638 {
0639 path_type p(path);
0640 self_type &parent = force_path(p);
0641
0642 key_type fragment = p.reduce();
0643 assoc_iterator el = parent.find(fragment);
0644
0645 if(el != parent.not_found()) {
0646 return el->second = value;
0647 } else {
0648 return parent.push_back(value_type(fragment, value))->second;
0649 }
0650 }
0651
0652 template<class K, class D, class C>
0653 basic_ptree<K, D, C> &
0654 basic_ptree<K, D, C>::add_child(const path_type &path,
0655 const self_type &value)
0656 {
0657 path_type p(path);
0658 self_type &parent = force_path(p);
0659
0660 key_type fragment = p.reduce();
0661 return parent.push_back(value_type(fragment, value))->second;
0662 }
0663
0664 template<class K, class D, class C>
0665 template<class Type, class Translator>
0666 typename boost::enable_if<detail::is_translator<Translator>, Type>::type
0667 basic_ptree<K, D, C>::get_value(Translator tr) const
0668 {
0669 if(boost::optional<Type> o = get_value_optional<Type>(tr)) {
0670 return *o;
0671 }
0672 BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
0673 std::string("conversion of data to type \"") +
0674 boost::core::type_name<Type>() + "\" failed", data()));
0675 }
0676
0677 template<class K, class D, class C>
0678 template<class Type> inline
0679 Type basic_ptree<K, D, C>::get_value() const
0680 {
0681 return get_value<Type>(
0682 typename translator_between<data_type, Type>::type());
0683 }
0684
0685 template<class K, class D, class C>
0686 template<class Type, class Translator> inline
0687 Type basic_ptree<K, D, C>::get_value(const Type &default_value,
0688 Translator tr) const
0689 {
0690 return get_value_optional<Type>(tr).get_value_or(default_value);
0691 }
0692
0693 template<class K, class D, class C>
0694 template <class Ch, class Translator>
0695 typename boost::enable_if<
0696 detail::is_character<Ch>,
0697 std::basic_string<Ch>
0698 >::type
0699 basic_ptree<K, D, C>::get_value(const Ch *default_value, Translator tr)const
0700 {
0701 return get_value<std::basic_string<Ch>, Translator>(default_value, tr);
0702 }
0703
0704 template<class K, class D, class C>
0705 template<class Type> inline
0706 typename boost::disable_if<detail::is_translator<Type>, Type>::type
0707 basic_ptree<K, D, C>::get_value(const Type &default_value) const
0708 {
0709 return get_value(default_value,
0710 typename translator_between<data_type, Type>::type());
0711 }
0712
0713 template<class K, class D, class C>
0714 template <class Ch>
0715 typename boost::enable_if<
0716 detail::is_character<Ch>,
0717 std::basic_string<Ch>
0718 >::type
0719 basic_ptree<K, D, C>::get_value(const Ch *default_value) const
0720 {
0721 return get_value< std::basic_string<Ch> >(default_value);
0722 }
0723
0724 template<class K, class D, class C>
0725 template<class Type, class Translator> inline
0726 optional<Type> basic_ptree<K, D, C>::get_value_optional(
0727 Translator tr) const
0728 {
0729 return tr.get_value(data());
0730 }
0731
0732 template<class K, class D, class C>
0733 template<class Type> inline
0734 optional<Type> basic_ptree<K, D, C>::get_value_optional() const
0735 {
0736 return get_value_optional<Type>(
0737 typename translator_between<data_type, Type>::type());
0738 }
0739
0740 template<class K, class D, class C>
0741 template<class Type, class Translator> inline
0742 typename boost::enable_if<detail::is_translator<Translator>, Type>::type
0743 basic_ptree<K, D, C>::get(const path_type &path,
0744 Translator tr) const
0745 {
0746 return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>(tr);
0747 }
0748
0749 template<class K, class D, class C>
0750 template<class Type> inline
0751 Type basic_ptree<K, D, C>::get(const path_type &path) const
0752 {
0753 return get_child(path).BOOST_NESTED_TEMPLATE get_value<Type>();
0754 }
0755
0756 template<class K, class D, class C>
0757 template<class Type, class Translator> inline
0758 Type basic_ptree<K, D, C>::get(const path_type &path,
0759 const Type &default_value,
0760 Translator tr) const
0761 {
0762 return get_optional<Type>(path, tr).get_value_or(default_value);
0763 }
0764
0765 template<class K, class D, class C>
0766 template <class Ch, class Translator>
0767 typename boost::enable_if<
0768 detail::is_character<Ch>,
0769 std::basic_string<Ch>
0770 >::type
0771 basic_ptree<K, D, C>::get(
0772 const path_type &path, const Ch *default_value, Translator tr) const
0773 {
0774 return get<std::basic_string<Ch>, Translator>(path, default_value, tr);
0775 }
0776
0777 template<class K, class D, class C>
0778 template<class Type> inline
0779 typename boost::disable_if<detail::is_translator<Type>, Type>::type
0780 basic_ptree<K, D, C>::get(const path_type &path,
0781 const Type &default_value) const
0782 {
0783 return get_optional<Type>(path).get_value_or(default_value);
0784 }
0785
0786 template<class K, class D, class C>
0787 template <class Ch>
0788 typename boost::enable_if<
0789 detail::is_character<Ch>,
0790 std::basic_string<Ch>
0791 >::type
0792 basic_ptree<K, D, C>::get(
0793 const path_type &path, const Ch *default_value) const
0794 {
0795 return get< std::basic_string<Ch> >(path, default_value);
0796 }
0797
0798 template<class K, class D, class C>
0799 template<class Type, class Translator>
0800 optional<Type> basic_ptree<K, D, C>::get_optional(const path_type &path,
0801 Translator tr) const
0802 {
0803 if (optional<const self_type&> child = get_child_optional(path))
0804 return child.get().
0805 BOOST_NESTED_TEMPLATE get_value_optional<Type>(tr);
0806 else
0807 return optional<Type>();
0808 }
0809
0810 template<class K, class D, class C>
0811 template<class Type>
0812 optional<Type> basic_ptree<K, D, C>::get_optional(
0813 const path_type &path) const
0814 {
0815 if (optional<const self_type&> child = get_child_optional(path))
0816 return child.get().BOOST_NESTED_TEMPLATE get_value_optional<Type>();
0817 else
0818 return optional<Type>();
0819 }
0820
0821 template<class K, class D, class C>
0822 template<class Type, class Translator>
0823 void basic_ptree<K, D, C>::put_value(const Type &value, Translator tr)
0824 {
0825 if(optional<data_type> o = tr.put_value(value)) {
0826 data() = *o;
0827 } else {
0828 BOOST_PROPERTY_TREE_THROW(ptree_bad_data(
0829 std::string("conversion of type \"") + boost::core::type_name<Type>() +
0830 "\" to data failed", boost::any()));
0831 }
0832 }
0833
0834 template<class K, class D, class C>
0835 template<class Type> inline
0836 void basic_ptree<K, D, C>::put_value(const Type &value)
0837 {
0838 put_value(value, typename translator_between<data_type, Type>::type());
0839 }
0840
0841 template<class K, class D, class C>
0842 template<class Type, typename Translator>
0843 basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
0844 const path_type &path, const Type &value, Translator tr)
0845 {
0846 if(optional<self_type &> child = get_child_optional(path)) {
0847 child.get().put_value(value, tr);
0848 return *child;
0849 } else {
0850 self_type &child2 = put_child(path, self_type());
0851 child2.put_value(value, tr);
0852 return child2;
0853 }
0854 }
0855
0856 template<class K, class D, class C>
0857 template<class Type> inline
0858 basic_ptree<K, D, C> & basic_ptree<K, D, C>::put(
0859 const path_type &path, const Type &value)
0860 {
0861 return put(path, value,
0862 typename translator_between<data_type, Type>::type());
0863 }
0864
0865 template<class K, class D, class C>
0866 template<class Type, typename Translator> inline
0867 basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
0868 const path_type &path, const Type &value, Translator tr)
0869 {
0870 self_type &child = add_child(path, self_type());
0871 child.put_value(value, tr);
0872 return child;
0873 }
0874
0875 template<class K, class D, class C>
0876 template<class Type> inline
0877 basic_ptree<K, D, C> & basic_ptree<K, D, C>::add(
0878 const path_type &path, const Type &value)
0879 {
0880 return add(path, value,
0881 typename translator_between<data_type, Type>::type());
0882 }
0883
0884
0885 template<class K, class D, class C>
0886 basic_ptree<K, D, C> *
0887 basic_ptree<K, D, C>::walk_path(path_type &p) const
0888 {
0889 if(p.empty()) {
0890
0891 return const_cast<basic_ptree*>(this);
0892 }
0893
0894 key_type fragment = p.reduce();
0895 const_assoc_iterator el = find(fragment);
0896 if(el == not_found()) {
0897
0898 return 0;
0899 }
0900
0901 return el->second.walk_path(p);
0902 }
0903
0904 template<class K, class D, class C>
0905 basic_ptree<K, D, C> & basic_ptree<K, D, C>::force_path(path_type &p)
0906 {
0907 BOOST_ASSERT(!p.empty() && "Empty path not allowed for put_child.");
0908 if(p.single()) {
0909
0910 return *this;
0911 }
0912 key_type fragment = p.reduce();
0913 assoc_iterator el = find(fragment);
0914
0915
0916 self_type& child = el == not_found() ?
0917 push_back(value_type(fragment, self_type()))->second : el->second;
0918 return child.force_path(p);
0919 }
0920
0921
0922
0923 template<class K, class D, class C>
0924 inline void swap(basic_ptree<K, D, C> &pt1, basic_ptree<K, D, C> &pt2)
0925 {
0926 pt1.swap(pt2);
0927 }
0928
0929 } }
0930
0931 #if defined(BOOST_PROPERTY_TREE_PAIR_BUG)
0932 #undef BOOST_PROPERTY_TREE_PAIR_BUG
0933 #endif
0934
0935 #endif