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